cleanup
This commit is contained in:
parent
cc0b4b817f
commit
33852e99b0
|
@ -1,4 +1,4 @@
|
||||||
#![allow(dead_code)]
|
//#![allow(dead_code)]
|
||||||
#![feature(error_in_core)]
|
#![feature(error_in_core)]
|
||||||
#![cfg_attr(not(any(feature = "std", test)), no_std)]
|
#![cfg_attr(not(any(feature = "std", test)), no_std)]
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ use scroll::Pread;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use structs::{Chunk, Key, KeyPtr, KnownObjectId, ObjectType, RootItem, Stripe, Superblock};
|
use structs::{Chunk, Key, KeyPtr, KnownObjectId, ObjectType, RootItem, Stripe, Superblock};
|
||||||
use tree::{PartialKey, Tree};
|
use tree::Tree;
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
@ -350,22 +350,6 @@ impl<R: VolumeIo> Btrfs<R> {
|
||||||
if let Some(subvol_root) = root_tree.find_key(&key)? {
|
if let Some(subvol_root) = root_tree.find_key(&key)? {
|
||||||
// if we found the dir entry of the "default subvol" (mharmstone nomenclature)
|
// 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)
|
// 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
|
let subvol_id = subvol_root
|
||||||
.1
|
.1
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
use core::{mem::size_of, ops::Deref};
|
use core::{mem::size_of, ops::Deref};
|
||||||
|
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
|
|
@ -104,7 +104,7 @@ impl<R: super::Read> Tree<R> {
|
||||||
&self,
|
&self,
|
||||||
key: &K,
|
key: &K,
|
||||||
) -> Result<Option<(Item, TreeItem)>> {
|
) -> Result<Option<(Item, TreeItem)>> {
|
||||||
let mut node = self.root.clone();
|
let mut node = NodeHandle::start(self.root.clone());
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let search = node.find_key(key);
|
let search = node.find_key(key);
|
||||||
|
@ -112,12 +112,18 @@ impl<R: super::Read> Tree<R> {
|
||||||
SearchResult::Leaf(a) => {
|
SearchResult::Leaf(a) => {
|
||||||
return a.parse_item();
|
return a.parse_item();
|
||||||
}
|
}
|
||||||
SearchResult::Edge(edge) => match &edge.node.inner {
|
SearchResult::Edge(mut edge) => match &edge.node.inner {
|
||||||
BTreeNode::Internal(internal) => {
|
BTreeNode::Internal(internal) => {
|
||||||
let child_ptr = internal.children.get(edge.idx as usize).expect("adsf");
|
let child_ptr = internal.children.get(edge.idx as usize).expect("adsf");
|
||||||
|
|
||||||
let bytes = self.volume.read_keyptr(child_ptr)?;
|
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
|
// recurse
|
||||||
}
|
}
|
||||||
BTreeNode::Leaf(_) => {
|
BTreeNode::Leaf(_) => {
|
||||||
|
@ -368,7 +374,7 @@ impl Node {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
BTreeNode::Internal(_) => Ok(None),
|
BTreeNode::Internal(_) => Ok(None),
|
||||||
BTreeNode::Leaf(leaf) => {
|
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 item = leaf.items.get(i).ok_or(Error::ReadFailed)?;
|
||||||
let start = size_of::<Header>() + item.offset.get() as usize;
|
let start = size_of::<Header>() + item.offset.get() as usize;
|
||||||
let size = item.size.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<K: PartialEq<Key> + PartialOrd<Key>>(self: &Rc<Self>, 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<R> Range<R>
|
impl<R> Range<R>
|
||||||
|
@ -455,93 +404,6 @@ where
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
return self.start == self.end;
|
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<Option<()>> {
|
|
||||||
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<R> Iterator for Range<R>
|
impl<R> Iterator for Range<R>
|
||||||
|
@ -619,6 +481,57 @@ impl NodeHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_key<K: PartialEq<Key> + PartialOrd<Key>>(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
|
// 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
|
// this is a live reference so if in the future I want to have a &mut to something in Volume
|
||||||
// greppable: volume ref
|
// greppable: volume ref
|
||||||
|
@ -721,7 +634,10 @@ impl NodeHandle {
|
||||||
node: child,
|
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
|
// 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 {
|
pub fn end(node: BoxedNode) -> Self {
|
||||||
let parents = Vec::with_capacity(node.inner.header().level as usize);
|
let parents = Vec::with_capacity(node.inner.header().level as usize);
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -4,10 +4,7 @@ use alloc::collections::btree_map::Entry;
|
||||||
use alloc::{collections::BTreeMap, rc::Rc, vec, vec::Vec};
|
use alloc::{collections::BTreeMap, rc::Rc, vec, vec::Vec};
|
||||||
use scroll::Pread;
|
use scroll::Pread;
|
||||||
|
|
||||||
use crate::structs::{
|
use crate::structs::{Chunk, Key, KeyPtr, KnownObjectId, ObjectType, Stripe, Superblock, TreeItem};
|
||||||
Chunk, Key, KeyPtr, KnownObjectId, ObjectType, RootItem, Stripe, Superblock, TreeItem,
|
|
||||||
};
|
|
||||||
use crate::v2::tree::PartialKey;
|
|
||||||
use crate::{Error, Result};
|
use crate::{Error, Result};
|
||||||
|
|
||||||
use super::tree::Tree;
|
use super::tree::Tree;
|
||||||
|
|
Loading…
Reference in a new issue