From 33852e99b09e88205605431e14a625255921e1d5 Mon Sep 17 00:00:00 2001 From: Janis Date: Thu, 30 Mar 2023 22:57:46 +0200 Subject: [PATCH] cleanup --- btrfs/src/lib.rs | 20 +--- btrfs/src/structs.rs | 1 + btrfs/src/v2/tree.rs | 233 ++++++++++++----------------------------- btrfs/src/v2/volume.rs | 5 +- 4 files changed, 69 insertions(+), 190 deletions(-) diff --git a/btrfs/src/lib.rs b/btrfs/src/lib.rs index 04d67ac..8daff04 100644 --- a/btrfs/src/lib.rs +++ b/btrfs/src/lib.rs @@ -1,4 +1,4 @@ -#![allow(dead_code)] +//#![allow(dead_code)] #![feature(error_in_core)] #![cfg_attr(not(any(feature = "std", test)), no_std)] @@ -17,7 +17,7 @@ use scroll::Pread; use thiserror::Error; use structs::{Chunk, Key, KeyPtr, KnownObjectId, ObjectType, RootItem, Stripe, Superblock}; -use tree::{PartialKey, Tree}; +use tree::Tree; extern crate alloc; @@ -350,22 +350,6 @@ impl Btrfs { if let Some(subvol_root) = root_tree.find_key(&key)? { // if we found the dir entry of the "default subvol" (mharmstone nomenclature) // we then look for the root fs tree in the root tree with the ID found in the `.location` of the dir_item only (from mharmstone) - let search_key = PartialKey::new( - Some( - subvol_root - .1 - .as_dir_item() - .expect("dir item") - .first() - .expect("dir item entry") - .dir_item - .location - .id(), - ), - Some(ObjectType::RootItem), - None, - ); - log::info!("subvol item: {subvol_root:#?}"); let subvol_id = subvol_root .1 diff --git a/btrfs/src/structs.rs b/btrfs/src/structs.rs index cc3ff76..f9531bc 100644 --- a/btrfs/src/structs.rs +++ b/btrfs/src/structs.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use core::{mem::size_of, ops::Deref}; use bytemuck::{Pod, Zeroable}; diff --git a/btrfs/src/v2/tree.rs b/btrfs/src/v2/tree.rs index ff25d1c..129e2c4 100644 --- a/btrfs/src/v2/tree.rs +++ b/btrfs/src/v2/tree.rs @@ -104,7 +104,7 @@ impl Tree { &self, key: &K, ) -> Result> { - let mut node = self.root.clone(); + let mut node = NodeHandle::start(self.root.clone()); loop { let search = node.find_key(key); @@ -112,12 +112,18 @@ impl Tree { SearchResult::Leaf(a) => { return a.parse_item(); } - SearchResult::Edge(edge) => match &edge.node.inner { + SearchResult::Edge(mut edge) => match &edge.node.inner { BTreeNode::Internal(internal) => { let child_ptr = internal.children.get(edge.idx as usize).expect("adsf"); let bytes = self.volume.read_keyptr(child_ptr)?; - node = Rc::new(Node::from_bytes(bytes)?); + let child = Rc::new(Node::from_bytes(bytes)?); + edge.parents.push((edge.node, edge.idx)); + node = NodeHandle { + parents: edge.parents, + node: child, + idx: 0, + }; // recurse } BTreeNode::Leaf(_) => { @@ -368,7 +374,7 @@ impl Node { match &self.inner { BTreeNode::Internal(_) => Ok(None), BTreeNode::Leaf(leaf) => { - // TODO: better error to indicate that i was out of bounds + // TODO: better error to indicate that it was out of bounds let item = leaf.items.get(i).ok_or(Error::ReadFailed)?; let start = size_of::
() + item.offset.get() as usize; let size = item.size.get() as usize; @@ -380,63 +386,6 @@ impl Node { } } } - - // TODO: move this to nodehandle - pub fn find_key + PartialOrd>(self: &Rc, key: &K) -> SearchResult { - match &self.inner { - BTreeNode::Internal(node) => { - for (i, child) in node.children.iter().enumerate() { - match key.partial_cmp(&child.key) { - Some(core::cmp::Ordering::Less) => { - return SearchResult::Edge(NodeHandle { - parents: Default::default(), - node: self.clone(), - idx: if i == 0 { 0 } else { i as u32 - 1 }, - }); - } - Some(core::cmp::Ordering::Equal) | None => { - return SearchResult::Edge(NodeHandle { - parents: Default::default(), - node: self.clone(), - idx: i as u32, - }); - } - _ => {} - } - } - - SearchResult::Edge(NodeHandle { - parents: Default::default(), - node: self.clone(), - idx: node.children.len() as u32 - 1, - }) - } - BTreeNode::Leaf(node) => { - for (i, child) in node.items.iter().enumerate() { - // if key < &child.key { - // return SearchResult::Leaf(NodeHandle { - // node: self.clone(), - // idx: if i == 0 { 0 } else { i as u32 - 1 }, - // }); - // } else - if key.eq(&child.key) { - return SearchResult::Leaf(NodeHandle { - parents: Default::default(), - node: self.clone(), - idx: i as u32, - }); - } - } - - log::debug!("key definitely not found!"); - SearchResult::Edge(NodeHandle { - parents: Default::default(), - node: self.clone(), - idx: node.items.len() as u32 - 1, - }) - } - } - } } impl Range @@ -455,93 +404,6 @@ where pub fn is_empty(&self) -> bool { return self.start == self.end; } - - pub fn init_start(&mut self) -> Result<()> { - let start = match &self.start { - RootOrEdge::Root(root) => { - match root.node.inner { - BTreeNode::Internal(_) => { - // descend until leaf - let mut advance = root.clone().advance_down(); - loop { - match advance { - NodeHandleAdvanceResult::Decend { parent, child_ptr } => { - let bytes = self.volume.read_keyptr(&child_ptr)?; - let child = - NodeHandle::start(Rc::new(Node::from_bytes(bytes)?)); - self.parents.push(parent); - - match &child.node.inner { - BTreeNode::Internal(_) => { - // continue loop - advance = child.advance_down(); - } - BTreeNode::Leaf(_) => { - break child; - } - } - } - NodeHandleAdvanceResult::Next(handle) => { - break handle; - } - NodeHandleAdvanceResult::Ascend => unreachable!(), - } - } - } - BTreeNode::Leaf(_) => root.clone(), - } - } - RootOrEdge::Edge(edge) => edge.clone(), - }; - - self.start = RootOrEdge::Edge(start); - - Ok(()) - } - - pub fn advance(&mut self) -> Result> { - if !self.is_empty() { - let start = self.start.into_handle(); - let mut advance = start.advance_down(); - loop { - match advance { - NodeHandleAdvanceResult::Decend { parent, child_ptr } => { - let bytes = self.volume.read_keyptr(&child_ptr)?; - let child = NodeHandle::start(Rc::new(Node::from_bytes(bytes)?)); - self.parents.push(parent); - self.start = RootOrEdge::Edge(child); - - match &self.start.node.inner { - BTreeNode::Internal(_) => { - return self.advance(); - } - BTreeNode::Leaf(_) => { - break; - } - } - } - NodeHandleAdvanceResult::Next(next) => { - self.start = RootOrEdge::Edge(next); - break; - } - NodeHandleAdvanceResult::Ascend => { - if let Some(last) = self.parents.pop() { - advance = NodeHandle { - idx: last.idx + 1, - ..last - } - .advance_down(); - } else { - return Ok(None); - } - } - } - } - Ok(Some(())) - } else { - Ok(None) - } - } } impl Iterator for Range @@ -619,6 +481,57 @@ impl NodeHandle { } } + pub fn find_key + PartialOrd>(self, key: &K) -> SearchResult { + match &self.node.inner { + BTreeNode::Internal(node) => { + for (i, child) in node.children.iter().enumerate() { + match key.partial_cmp(&child.key) { + Some(core::cmp::Ordering::Less) => { + return SearchResult::Edge(Self { + idx: if i == 0 { 0 } else { i as u32 - 1 }, + ..self + }); + } + Some(core::cmp::Ordering::Equal) | None => { + return SearchResult::Edge(NodeHandle { + idx: i as u32, + ..self + }); + } + _ => {} + } + } + + SearchResult::Edge(NodeHandle { + idx: node.children.len() as u32 - 1, + ..self + }) + } + BTreeNode::Leaf(node) => { + for (i, child) in node.items.iter().enumerate() { + // if key < &child.key { + // return SearchResult::Leaf(NodeHandle { + // node: self.clone(), + // idx: if i == 0 { 0 } else { i as u32 - 1 }, + // }); + // } else + if key.eq(&child.key) { + return SearchResult::Leaf(NodeHandle { + idx: i as u32, + ..self + }); + } + } + + log::debug!("key definitely not found!"); + SearchResult::Edge(NodeHandle { + idx: node.items.len() as u32 - 1, + ..self + }) + } + } + } + // needs reference to volume to be able to read children key_ptrs // this is a live reference so if in the future I want to have a &mut to something in Volume // greppable: volume ref @@ -721,7 +634,10 @@ impl NodeHandle { node: child, }) } - Err(_) => Err(Self { parents, node, idx }), + Err(_) => { + log::error!("failed to read child node!"); + Err(Self { parents, node, idx }) + } }; // TODO: better error or panic here? this would return self, indicating the end of the tree, even though we simply failed to retrieve the next node @@ -736,25 +652,6 @@ impl NodeHandle { } } - // returns the next node in ascending sequential order - pub fn advance_down(self) -> NodeHandleAdvanceResult { - let header = self.node.inner.header(); - if self.idx + 1 >= header.nritems.get() { - NodeHandleAdvanceResult::Ascend - } else { - match &self.node.inner { - BTreeNode::Internal(node) => NodeHandleAdvanceResult::Decend { - parent: self.clone(), - child_ptr: *node.children.first().expect("no children in node"), - }, - BTreeNode::Leaf(_) => NodeHandleAdvanceResult::Next(Self { - idx: self.idx + 1, - ..self - }), - } - } - } - pub fn end(node: BoxedNode) -> Self { let parents = Vec::with_capacity(node.inner.header().level as usize); Self { diff --git a/btrfs/src/v2/volume.rs b/btrfs/src/v2/volume.rs index 33183b6..7d8facb 100644 --- a/btrfs/src/v2/volume.rs +++ b/btrfs/src/v2/volume.rs @@ -4,10 +4,7 @@ use alloc::collections::btree_map::Entry; use alloc::{collections::BTreeMap, rc::Rc, vec, vec::Vec}; use scroll::Pread; -use crate::structs::{ - Chunk, Key, KeyPtr, KnownObjectId, ObjectType, RootItem, Stripe, Superblock, TreeItem, -}; -use crate::v2::tree::PartialKey; +use crate::structs::{Chunk, Key, KeyPtr, KnownObjectId, ObjectType, Stripe, Superblock, TreeItem}; use crate::{Error, Result}; use super::tree::Tree;