fixed PartialKey
- removed unnecessary/old code - PartialKey id is no longer Optional, since that made no sense. - lazily compare partialkey to key (probably not needed but looks neater)
This commit is contained in:
parent
6dd58e3b65
commit
43a92bedcf
|
@ -23,8 +23,8 @@ pub enum KnownObjectId {
|
||||||
QuotaTree,
|
QuotaTree,
|
||||||
UuidTree,
|
UuidTree,
|
||||||
FreeSpaceTree,
|
FreeSpaceTree,
|
||||||
RootINode = 0x100,
|
// RootINode = 0x100, // first free id, always the root inode of a fs
|
||||||
__LastFreeId = u64::MAX - 256,
|
// __LastFreeId = u64::MAX - 256, // last free id
|
||||||
DataRelocTree = u64::MAX - 9,
|
DataRelocTree = u64::MAX - 9,
|
||||||
TreeReloc = u64::MAX - 8,
|
TreeReloc = u64::MAX - 8,
|
||||||
TreeLog = u64::MAX - 7,
|
TreeLog = u64::MAX - 7,
|
||||||
|
|
|
@ -16,8 +16,12 @@ pub struct PartialKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialKey {
|
impl PartialKey {
|
||||||
pub fn new(id: Option<KnownObjectId>, ty: Option<ObjectType>, offset: Option<u64>) -> Self {
|
pub fn new(id: KnownObjectId, ty: Option<ObjectType>, offset: Option<u64>) -> Self {
|
||||||
Self { id, ty, offset }
|
Self {
|
||||||
|
id: Some(id),
|
||||||
|
ty,
|
||||||
|
offset,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,25 +69,18 @@ mod partial_key_tests {
|
||||||
0x8dbfc2d2, // crc of "default"
|
0x8dbfc2d2, // crc of "default"
|
||||||
);
|
);
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(KnownObjectId::ChunkTree, Some(ObjectType::DirItem), None);
|
||||||
Some(KnownObjectId::ChunkTree),
|
|
||||||
Some(ObjectType::DirItem),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
assert_eq!(pkey.partial_cmp(&key), None);
|
assert_eq!(pkey.partial_cmp(&key), None);
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(
|
||||||
Some(KnownObjectId::ChunkTree),
|
KnownObjectId::ChunkTree,
|
||||||
Some(ObjectType::DirItem),
|
Some(ObjectType::DirItem),
|
||||||
Some(0xdeadbeef),
|
Some(0xdeadbeef),
|
||||||
);
|
);
|
||||||
assert_ne!(pkey.partial_cmp(&key), Some(core::cmp::Ordering::Equal));
|
assert_ne!(pkey.partial_cmp(&key), Some(core::cmp::Ordering::Equal));
|
||||||
|
|
||||||
let pkey = PartialKey::new(None, Some(ObjectType::DirItem), Some(0xdeadbeef));
|
|
||||||
assert_ne!(pkey.partial_cmp(&key), None);
|
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(
|
||||||
Some(KnownObjectId::ChunkTree),
|
KnownObjectId::ChunkTree,
|
||||||
Some(ObjectType::DirItem),
|
Some(ObjectType::DirItem),
|
||||||
Some(0x8dbfc2d2),
|
Some(0x8dbfc2d2),
|
||||||
);
|
);
|
||||||
|
@ -98,25 +95,18 @@ mod partial_key_tests {
|
||||||
0x8dbfc2d2, // crc of "default"
|
0x8dbfc2d2, // crc of "default"
|
||||||
);
|
);
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(KnownObjectId::ChunkTree, Some(ObjectType::DirItem), None);
|
||||||
Some(KnownObjectId::ChunkTree),
|
|
||||||
Some(ObjectType::DirItem),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
assert!(pkey.eq(&key));
|
assert!(pkey.eq(&key));
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(
|
||||||
Some(KnownObjectId::ChunkTree),
|
KnownObjectId::ChunkTree,
|
||||||
Some(ObjectType::DirItem),
|
Some(ObjectType::DirItem),
|
||||||
Some(0xdeadbeef),
|
Some(0xdeadbeef),
|
||||||
);
|
);
|
||||||
assert!(!pkey.eq(&key));
|
assert!(!pkey.eq(&key));
|
||||||
|
|
||||||
let pkey = PartialKey::new(None, Some(ObjectType::DirItem), Some(0xdeadbeef));
|
|
||||||
assert!(!pkey.eq(&key));
|
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(
|
||||||
Some(KnownObjectId::ChunkTree),
|
KnownObjectId::ChunkTree,
|
||||||
Some(ObjectType::DirItem),
|
Some(ObjectType::DirItem),
|
||||||
Some(0x8dbfc2d2),
|
Some(0x8dbfc2d2),
|
||||||
);
|
);
|
||||||
|
|
|
@ -869,21 +869,6 @@ impl NodeHandle {
|
||||||
.expect("idx out of bounds")
|
.expect("idx out of bounds")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn advance_sideways(self) -> NodeHandleAdvanceResult {
|
|
||||||
let header = self.node.inner.header();
|
|
||||||
if header.nritems.get() >= self.idx + 1 {
|
|
||||||
NodeHandleAdvanceResult::Ascend
|
|
||||||
} else {
|
|
||||||
match &self.node.inner {
|
|
||||||
BTreeNode::Internal(_) => NodeHandleAdvanceResult::Next(Self {
|
|
||||||
idx: self.idx + 1,
|
|
||||||
..self
|
|
||||||
}),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn find_key_rev<K: PartialEq<Key> + PartialOrd<Key>>(self, key: &K) -> SearchResult {
|
pub fn find_key_rev<K: PartialEq<Key> + PartialOrd<Key>>(self, key: &K) -> SearchResult {
|
||||||
match &self.node.inner {
|
match &self.node.inner {
|
||||||
BTreeNode::Internal(node) => {
|
BTreeNode::Internal(node) => {
|
||||||
|
@ -934,12 +919,6 @@ impl NodeHandle {
|
||||||
}
|
}
|
||||||
BTreeNode::Leaf(node) => {
|
BTreeNode::Leaf(node) => {
|
||||||
for (i, child) in node.items.iter().enumerate() {
|
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) {
|
if key.eq(&child.key) {
|
||||||
return SearchResult::Leaf(NodeHandle {
|
return SearchResult::Leaf(NodeHandle {
|
||||||
idx: i as u32,
|
idx: i as u32,
|
||||||
|
@ -1075,20 +1054,20 @@ impl NodeHandle {
|
||||||
|
|
||||||
/// key lookup that will find the first key that matches the present items in this partial key
|
/// key lookup that will find the first key that matches the present items in this partial key
|
||||||
pub struct PartialKey {
|
pub struct PartialKey {
|
||||||
pub id: Option<KnownObjectId>,
|
pub id: KnownObjectId,
|
||||||
pub ty: Option<ObjectType>,
|
pub ty: Option<ObjectType>,
|
||||||
pub offset: Option<u64>,
|
pub offset: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialKey {
|
impl PartialKey {
|
||||||
pub fn new(id: Option<KnownObjectId>, ty: Option<ObjectType>, offset: Option<u64>) -> Self {
|
pub fn new(id: KnownObjectId, ty: Option<ObjectType>, offset: Option<u64>) -> Self {
|
||||||
Self { id, ty, offset }
|
Self { id, ty, offset }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<Key> for PartialKey {
|
impl PartialEq<Key> for PartialKey {
|
||||||
fn eq(&self, other: &Key) -> bool {
|
fn eq(&self, other: &Key) -> bool {
|
||||||
self.id.map(|id| id == other.id()).unwrap_or(true)
|
self.id == other.id()
|
||||||
&& self.ty.map(|ty| ty == other.ty()).unwrap_or(true)
|
&& self.ty.map(|ty| ty == other.ty()).unwrap_or(true)
|
||||||
&& self
|
&& self
|
||||||
.offset
|
.offset
|
||||||
|
@ -1100,17 +1079,15 @@ impl PartialEq<Key> for PartialKey {
|
||||||
/// compares Self to a key, by comparing each item with the element in key if present, and skipping to the next item if missing.
|
/// compares Self to a key, by comparing each item with the element in key if present, and skipping to the next item if missing.
|
||||||
impl PartialOrd<Key> for PartialKey {
|
impl PartialOrd<Key> for PartialKey {
|
||||||
fn partial_cmp(&self, other: &Key) -> Option<core::cmp::Ordering> {
|
fn partial_cmp(&self, other: &Key) -> Option<core::cmp::Ordering> {
|
||||||
let id = self.id.and_then(|id| id.partial_cmp(&other.id()));
|
match self.id.partial_cmp(&other.id()) {
|
||||||
let ty = self.ty.and_then(|ty| ty.partial_cmp(&other.ty()));
|
Some(core::cmp::Ordering::Equal) | None => {
|
||||||
let offset = self
|
match self.ty.and_then(|ty| ty.partial_cmp(&other.ty())) {
|
||||||
.offset
|
Some(core::cmp::Ordering::Equal) | None => self
|
||||||
.and_then(|offset| offset.partial_cmp(&other.offset.get()));
|
.offset
|
||||||
|
.and_then(|offset| offset.partial_cmp(&other.offset.get())),
|
||||||
match id {
|
ord => ord,
|
||||||
Some(core::cmp::Ordering::Equal) | None => match ty {
|
}
|
||||||
Some(core::cmp::Ordering::Equal) | None => offset,
|
}
|
||||||
ord => ord,
|
|
||||||
},
|
|
||||||
ord => ord,
|
ord => ord,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1130,25 +1107,18 @@ mod partial_key_tests {
|
||||||
0x8dbfc2d2, // crc of "default"
|
0x8dbfc2d2, // crc of "default"
|
||||||
);
|
);
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(KnownObjectId::ChunkTree, Some(ObjectType::DirItem), None);
|
||||||
Some(KnownObjectId::ChunkTree),
|
|
||||||
Some(ObjectType::DirItem),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
assert_eq!(pkey.partial_cmp(&key), None);
|
assert_eq!(pkey.partial_cmp(&key), None);
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(
|
||||||
Some(KnownObjectId::ChunkTree),
|
KnownObjectId::ChunkTree,
|
||||||
Some(ObjectType::DirItem),
|
Some(ObjectType::DirItem),
|
||||||
Some(0xdeadbeef),
|
Some(0xdeadbeef),
|
||||||
);
|
);
|
||||||
assert_ne!(pkey.partial_cmp(&key), Some(core::cmp::Ordering::Equal));
|
assert_ne!(pkey.partial_cmp(&key), Some(core::cmp::Ordering::Equal));
|
||||||
|
|
||||||
let pkey = PartialKey::new(None, Some(ObjectType::DirItem), Some(0xdeadbeef));
|
|
||||||
assert_ne!(pkey.partial_cmp(&key), None);
|
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(
|
||||||
Some(KnownObjectId::ChunkTree),
|
KnownObjectId::ChunkTree,
|
||||||
Some(ObjectType::DirItem),
|
Some(ObjectType::DirItem),
|
||||||
Some(0x8dbfc2d2),
|
Some(0x8dbfc2d2),
|
||||||
);
|
);
|
||||||
|
@ -1163,25 +1133,18 @@ mod partial_key_tests {
|
||||||
0x8dbfc2d2, // crc of "default"
|
0x8dbfc2d2, // crc of "default"
|
||||||
);
|
);
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(KnownObjectId::ChunkTree, Some(ObjectType::DirItem), None);
|
||||||
Some(KnownObjectId::ChunkTree),
|
|
||||||
Some(ObjectType::DirItem),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
assert!(pkey.eq(&key));
|
assert!(pkey.eq(&key));
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(
|
||||||
Some(KnownObjectId::ChunkTree),
|
KnownObjectId::ChunkTree,
|
||||||
Some(ObjectType::DirItem),
|
Some(ObjectType::DirItem),
|
||||||
Some(0xdeadbeef),
|
Some(0xdeadbeef),
|
||||||
);
|
);
|
||||||
assert!(!pkey.eq(&key));
|
assert!(!pkey.eq(&key));
|
||||||
|
|
||||||
let pkey = PartialKey::new(None, Some(ObjectType::DirItem), Some(0xdeadbeef));
|
|
||||||
assert!(!pkey.eq(&key));
|
|
||||||
|
|
||||||
let pkey = PartialKey::new(
|
let pkey = PartialKey::new(
|
||||||
Some(KnownObjectId::ChunkTree),
|
KnownObjectId::ChunkTree,
|
||||||
Some(ObjectType::DirItem),
|
Some(ObjectType::DirItem),
|
||||||
Some(0x8dbfc2d2),
|
Some(0x8dbfc2d2),
|
||||||
);
|
);
|
||||||
|
|
|
@ -400,7 +400,7 @@ impl<R: super::Read> Fs<R> {
|
||||||
&self,
|
&self,
|
||||||
inode: &INode,
|
inode: &INode,
|
||||||
) -> Result<impl Iterator<Item = DirItemEntry> + '_> {
|
) -> Result<impl Iterator<Item = DirItemEntry> + '_> {
|
||||||
let key = PartialKey::new(Some(inode.id()), Some(ObjectType::DirIndex), None);
|
let key = PartialKey::new(inode.id(), Some(ObjectType::DirIndex), None);
|
||||||
|
|
||||||
let children = self.fs_root.find_range(&key)?;
|
let children = self.fs_root.find_range(&key)?;
|
||||||
|
|
||||||
|
@ -496,7 +496,7 @@ impl<R: super::Read> Fs<R> {
|
||||||
fn find_inode_child(&self, parent_inode: u64, child: &[u8]) -> Result<Option<DirItemEntry>> {
|
fn find_inode_child(&self, parent_inode: u64, child: &[u8]) -> Result<Option<DirItemEntry>> {
|
||||||
let crc = calculate_crc32c(0xfffffffe, child);
|
let crc = calculate_crc32c(0xfffffffe, child);
|
||||||
let key = PartialKey::new(
|
let key = PartialKey::new(
|
||||||
Some(parent_inode.into()),
|
parent_inode.into(),
|
||||||
Some(ObjectType::DirItem),
|
Some(ObjectType::DirItem),
|
||||||
Some(crc as u64),
|
Some(crc as u64),
|
||||||
);
|
);
|
||||||
|
@ -527,8 +527,7 @@ impl<R: super::Read> Fs<R> {
|
||||||
pub fn get_inode_extents(&self, inode_id: u64) -> Result<Vec<(u64, ExtentData)>> {
|
pub fn get_inode_extents(&self, inode_id: u64) -> Result<Vec<(u64, ExtentData)>> {
|
||||||
if let Some(dir_entry) = self.get_inode_dir_index(inode_id)? {
|
if let Some(dir_entry) = self.get_inode_dir_index(inode_id)? {
|
||||||
if dir_entry.item().ty() == DirItemType::RegFile {
|
if dir_entry.item().ty() == DirItemType::RegFile {
|
||||||
let key =
|
let key = PartialKey::new(inode_id.into(), Some(ObjectType::ExtentData), None);
|
||||||
PartialKey::new(Some(inode_id.into()), Some(ObjectType::ExtentData), None);
|
|
||||||
|
|
||||||
let extents = self.fs_root.find_range(&key)?;
|
let extents = self.fs_root.find_range(&key)?;
|
||||||
|
|
||||||
|
@ -705,7 +704,7 @@ impl<R: super::Read> Fs<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_inode_ref(&self, inode_id: u64) -> Result<Option<(Item, INodeRefEntry)>> {
|
fn find_inode_ref(&self, inode_id: u64) -> Result<Option<(Item, INodeRefEntry)>> {
|
||||||
let key = PartialKey::new(Some(inode_id.into()), Some(ObjectType::INodeRef), None);
|
let key = PartialKey::new(inode_id.into(), Some(ObjectType::INodeRef), None);
|
||||||
|
|
||||||
match self.fs_root.entry(&key)? {
|
match self.fs_root.entry(&key)? {
|
||||||
super::tree::entry::Entry::Occupied(entry) => {
|
super::tree::entry::Entry::Occupied(entry) => {
|
||||||
|
@ -724,7 +723,7 @@ impl<R: super::Read> Fs<R> {
|
||||||
) -> Result<Option<DirItemEntry>> {
|
) -> Result<Option<DirItemEntry>> {
|
||||||
//let crc = calculate_crc32c(0xfffffffe, &inoderef.name());
|
//let crc = calculate_crc32c(0xfffffffe, &inoderef.name());
|
||||||
let key = PartialKey::new(
|
let key = PartialKey::new(
|
||||||
Some(parent_inode.into()),
|
parent_inode.into(),
|
||||||
Some(ObjectType::DirIndex),
|
Some(ObjectType::DirIndex),
|
||||||
Some(inoderef.item().index.get()),
|
Some(inoderef.item().index.get()),
|
||||||
);
|
);
|
||||||
|
@ -843,7 +842,7 @@ mod tests {
|
||||||
let fs = v2.default_subvolume().expect("default subvol");
|
let fs = v2.default_subvolume().expect("default subvol");
|
||||||
|
|
||||||
let search_key = PartialKey::new(
|
let search_key = PartialKey::new(
|
||||||
Some(fs.root_item.root_dirid.get().into()),
|
fs.root_item.root_dirid.get().into(),
|
||||||
Some(ObjectType::DirIndex),
|
Some(ObjectType::DirIndex),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
|
@ -104,7 +104,7 @@ fn get_inode_items() -> Result<()> {
|
||||||
let v2 = open_filesystem()?;
|
let v2 = open_filesystem()?;
|
||||||
let fs = v2.default_subvolume().expect("default subvol");
|
let fs = v2.default_subvolume().expect("default subvol");
|
||||||
|
|
||||||
let search_key = PartialKey::new(Some(fs.root_dir_id()), Some(ObjectType::DirIndex), None);
|
let search_key = PartialKey::new(fs.root_dir_id(), Some(ObjectType::DirIndex), None);
|
||||||
|
|
||||||
// with range
|
// with range
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue