btrfs_explorer/btrfs_explorer/src/nodereader.rs

56 lines
1.5 KiB
Rust

use std::{
collections::HashMap,
sync::Arc,
cell::RefCell,
time::Instant,
};
use crate::btrfs_structs::{Node, ParseError, ParseBin};
use crate::addrmap::{LogToPhys, AddressMap};
pub struct NodeReader<'a> {
image: &'a [u8],
addr_map: AddressMap,
cache: RefCell<HashMap<u64, Arc<Node>>>,
}
impl<'a> NodeReader<'a> {
pub fn new(image: &'a [u8]) -> Result<NodeReader<'a>, ParseError> {
let addr_map = AddressMap::new(image)?;
Ok(NodeReader {image, addr_map, cache: RefCell::new(HashMap::new())})
}
pub fn with_addrmap(image: &'a [u8], addr_map: AddressMap) -> Result<NodeReader<'a>, ParseError> {
Ok(NodeReader {image, addr_map, cache: RefCell::new(HashMap::new())})
}
/// Read a node given its logical address
pub fn get_node(&self, addr: u64) -> Result<Arc<Node>, ParseError> {
if let Some(node) = self.cache.borrow().get(&addr) {
return Ok(Arc::clone(node))
}
let start_time = Instant::now();
let node_data = self.addr_map.node_at_log(self.image, addr)?;
let node = Arc::new(Node::parse(node_data)?);
self.cache.borrow_mut().insert(addr, Arc::clone(&node));
let t = Instant::now().duration_since(start_time);
println!("Read node {:X} in {:?}", addr, t);
Ok(node)
}
pub fn get_raw_data(&self, addr: u64, start: u32, end: u32) -> Result<&'a [u8], ParseError> {
let node_data = self.addr_map.node_at_log(self.image, addr)?;
Ok(&node_data[start as usize .. end as usize])
}
pub fn addr_map(&self) -> &AddressMap {
&self.addr_map
}
}