thin-provisioning-tools/src/pdata/array_walker.rs

97 lines
2.7 KiB
Rust
Raw Normal View History

2020-12-09 16:10:06 +05:30
use std::sync::Arc;
use crate::io_engine::*;
use crate::pdata::array_block::*;
use crate::pdata::btree::*;
use crate::pdata::btree_walker::*;
use crate::pdata::unpack::*;
//------------------------------------------
pub struct ArrayWalker {
engine: Arc<dyn IoEngine + Send + Sync>,
2021-03-03 15:57:57 +05:30
ignore_non_fatal: bool,
2020-12-09 16:10:06 +05:30
}
// FIXME: define another Result type for array visiting?
pub trait ArrayVisitor<V: Unpack> {
2021-03-03 15:57:57 +05:30
fn visit(&self, index: u64, v: V) -> anyhow::Result<()>;
2020-12-09 16:10:06 +05:30
}
struct BlockValueVisitor<'a, V> {
2020-12-09 16:10:06 +05:30
engine: Arc<dyn IoEngine + Send + Sync>,
array_block_visitor: &'a mut dyn ArrayVisitor<V>,
2020-12-09 16:10:06 +05:30
}
impl<'a, V: Unpack + Copy> BlockValueVisitor<'a, V> {
2021-03-03 15:57:57 +05:30
pub fn new(
2020-12-09 16:10:06 +05:30
e: Arc<dyn IoEngine + Send + Sync>,
v: &'a mut dyn ArrayVisitor<V>,
) -> BlockValueVisitor<'a, V> {
2020-12-09 16:10:06 +05:30
BlockValueVisitor {
engine: e,
array_block_visitor: v,
}
}
2021-03-03 15:57:57 +05:30
pub fn visit_array_block(&self, index: u64, array_block: ArrayBlock<V>) {
let begin = index * array_block.header.max_entries as u64;
2020-12-09 16:10:06 +05:30
for i in 0..array_block.header.nr_entries {
2021-03-03 15:57:57 +05:30
self.array_block_visitor
.visit(begin + i as u64, array_block.values[i as usize])
.unwrap();
2020-12-09 16:10:06 +05:30
}
}
}
impl<'a, V: Unpack + Copy> NodeVisitor<u64> for BlockValueVisitor<'a, V> {
2020-12-09 16:10:06 +05:30
// FIXME: return errors
fn visit(
&self,
2021-02-24 17:51:10 +05:30
path: &[u64],
2020-12-09 16:10:06 +05:30
_kr: &KeyRange,
_h: &NodeHeader,
keys: &[u64],
2021-03-03 15:57:57 +05:30
values: &[u64],
2020-12-09 16:10:06 +05:30
) -> Result<()> {
2021-03-03 15:57:57 +05:30
for (n, index) in keys.iter().enumerate() {
let b = self.engine.read(values[n]).map_err(|_| io_err(path))?;
2020-12-09 16:10:06 +05:30
let array_block = unpack_array_block::<V>(b.get_data()).map_err(|_| io_err(path))?;
2021-03-03 15:57:57 +05:30
self.visit_array_block(*index, array_block);
2020-12-09 16:10:06 +05:30
}
Ok(())
}
2021-02-24 17:51:10 +05:30
fn visit_again(&self, _path: &[u64], _b: u64) -> Result<()> {
2020-12-09 16:10:06 +05:30
Ok(())
}
fn end_walk(&self) -> Result<()> {
Ok(())
}
}
impl ArrayWalker {
pub fn new(engine: Arc<dyn IoEngine + Send + Sync>, ignore_non_fatal: bool) -> ArrayWalker {
let r: ArrayWalker = ArrayWalker {
engine,
ignore_non_fatal,
};
r
}
// FIXME: redefine the Result type for array visiting?
pub fn walk<V>(&self, visitor: &mut dyn ArrayVisitor<V>, root: u64) -> Result<()>
2020-12-09 16:10:06 +05:30
where
2021-03-03 15:57:57 +05:30
V: Unpack + Copy,
2020-12-09 16:10:06 +05:30
{
let w = BTreeWalker::new(self.engine.clone(), self.ignore_non_fatal);
2021-03-03 15:57:57 +05:30
let mut path = Vec::new();
2020-12-09 16:10:06 +05:30
path.push(0);
let v = BlockValueVisitor::<V>::new(self.engine.clone(), visitor);
w.walk(&mut path, &v, root)
}
}
//------------------------------------------