Use Arc instead of Rc to prepare for shared tree cache

This commit is contained in:
Florian Stecker 2024-02-13 17:06:18 -05:00
parent 80942c8ed3
commit ae91f77d02
2 changed files with 10 additions and 8 deletions

View File

@ -1,4 +1,5 @@
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc;
use crate::btrfs_structs::{ParseBin, Key, ChunkItem, Value, Superblock, ParseError, NODE_SIZE}; use crate::btrfs_structs::{ParseBin, Key, ChunkItem, Value, Superblock, ParseError, NODE_SIZE};
use crate::btrfs_lookup::Tree; use crate::btrfs_lookup::Tree;
@ -14,7 +15,7 @@ impl AddressMap {
let chunk_tree = Tree { let chunk_tree = Tree {
image: image, image: image,
addr_map: Rc::new(bootstrap_addr), addr_map: Arc::new(bootstrap_addr),
root_addr_log: superblock.chunk_root, root_addr_log: superblock.chunk_root,
}; };

View File

@ -1,5 +1,6 @@
use std::convert::identity; use std::convert::identity;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc;
use std::ops::{Deref, RangeBounds, Bound}; use std::ops::{Deref, RangeBounds, Bound};
use crate::btrfs_structs::{Leaf, Key, Item, InteriorNode, Node, ParseError, ParseBin, Value, Superblock, ItemType, ZERO_KEY}; use crate::btrfs_structs::{Leaf, Key, Item, InteriorNode, Node, ParseError, ParseBin, Value, Superblock, ItemType, ZERO_KEY};
@ -9,18 +10,18 @@ use crate::addrmap::{node_at_log, AddressMap};
/// and handles the tree traversal and the virtual address translation. /// and handles the tree traversal and the virtual address translation.
pub struct Tree<'a> { pub struct Tree<'a> {
pub image: &'a [u8], pub image: &'a [u8],
pub addr_map: Rc<AddressMap>, pub addr_map: Arc<AddressMap>,
pub root_addr_log: u64, pub root_addr_log: u64,
} }
impl<'a> Tree<'a> { impl<'a> Tree<'a> {
pub fn new<T: Into<u64>>(image: &'a [u8], tree_id: T) -> Result<Tree<'a>, ParseError> { pub fn new<T: Into<u64>>(image: &'a [u8], tree_id: T) -> Result<Tree<'a>, ParseError> {
let addr_map = Rc::new(AddressMap::new(image)?); let addr_map = Arc::new(AddressMap::new(image)?);
let superblock = Superblock::parse(&image[0x10000..])?; let superblock = Superblock::parse(&image[0x10000..])?;
let root_tree = Tree { let root_tree = Tree {
image, image,
addr_map: Rc::clone(&addr_map), addr_map: Arc::clone(&addr_map),
root_addr_log: superblock.root root_addr_log: superblock.root
}; };
let tree_root_item = root_tree.find_key(Key::new(tree_id.into(), ItemType::Root, 0))?; let tree_root_item = root_tree.find_key(Key::new(tree_id.into(), ItemType::Root, 0))?;
@ -34,26 +35,26 @@ impl<'a> Tree<'a> {
} }
pub fn root(image: &'a [u8]) -> Result<Tree<'a>, ParseError> { pub fn root(image: &'a [u8]) -> Result<Tree<'a>, ParseError> {
let addr_map = Rc::new(AddressMap::new(image)?); let addr_map = Arc::new(AddressMap::new(image)?);
let superblock = Superblock::parse(&image[0x10000..])?; let superblock = Superblock::parse(&image[0x10000..])?;
Ok(Tree { image, addr_map, root_addr_log: superblock.root }) Ok(Tree { image, addr_map, root_addr_log: superblock.root })
} }
pub fn chunk(image: &'a [u8]) -> Result<Tree<'a>, ParseError> { pub fn chunk(image: &'a [u8]) -> Result<Tree<'a>, ParseError> {
let addr_map = Rc::new(AddressMap::new(image)?); let addr_map = Arc::new(AddressMap::new(image)?);
let superblock = Superblock::parse(&image[0x10000..])?; let superblock = Superblock::parse(&image[0x10000..])?;
Ok(Tree { image, addr_map, root_addr_log: superblock.chunk_root }) Ok(Tree { image, addr_map, root_addr_log: superblock.chunk_root })
} }
/// Read a node given its logical address /// Read a node given its logical address
pub fn get_node(&self, addr: u64) -> Result<Rc<Node>, ParseError> { pub fn get_node(&self, addr: u64) -> Result<Arc<Node>, ParseError> {
// eprintln!("Reading node at {:x}", addr); // eprintln!("Reading node at {:x}", addr);
let node_data = node_at_log(self.image, self.addr_map.as_ref(), addr)?; let node_data = node_at_log(self.image, self.addr_map.as_ref(), addr)?;
let node = Node::parse(node_data)?; let node = Node::parse(node_data)?;
Ok(Rc::new(node)) Ok(Arc::new(node))
} }
} }