#[cfg(feature = "full")]
use grovedb_costs::{CostResult, CostsExt, OperationCost};
use grovedb_version::version::GroveVersion;
#[cfg(feature = "full")]
use super::{
super::{Link, TreeNode},
Fetch,
};
use crate::tree::kv::ValueDefinedCostType;
#[cfg(feature = "full")]
use crate::Error;
#[cfg(feature = "full")]
pub struct RefWalker<'a, S>
where
S: Fetch + Sized + Clone,
{
tree: &'a mut TreeNode,
source: S,
}
#[cfg(feature = "full")]
impl<'a, S> RefWalker<'a, S>
where
S: Fetch + Sized + Clone,
{
pub fn new(tree: &'a mut TreeNode, source: S) -> Self {
RefWalker { tree, source }
}
pub fn tree(&self) -> &TreeNode {
self.tree
}
pub fn walk<V>(
&mut self,
left: bool,
value_defined_cost_fn: Option<&V>,
grove_version: &GroveVersion,
) -> CostResult<Option<RefWalker<S>>, Error>
where
V: Fn(&[u8], &GroveVersion) -> Option<ValueDefinedCostType>,
{
let link = match self.tree.link(left) {
None => return Ok(None).wrap_with_cost(Default::default()),
Some(link) => link,
};
let mut cost = OperationCost::default();
match link {
Link::Reference { .. } => {
let load_res = self
.tree
.load(left, &self.source, value_defined_cost_fn, grove_version)
.unwrap_add_cost(&mut cost);
if let Err(e) = load_res {
return Err(e).wrap_with_cost(cost);
}
}
Link::Modified { .. } => panic!("Cannot traverse Link::Modified"),
Link::Uncommitted { .. } | Link::Loaded { .. } => {}
}
let child = self.tree.child_mut(left).unwrap();
Ok(Some(RefWalker::new(child, self.source.clone()))).wrap_with_cost(cost)
}
}