diff --git a/btrfs/src/tree.rs b/btrfs/src/tree.rs index c6880b2..d4538ae 100644 --- a/btrfs/src/tree.rs +++ b/btrfs/src/tree.rs @@ -13,6 +13,81 @@ use alloc::{ use scroll::Pread; use zerocopy::FromBytes; +pub struct PartialKey { + id: Option, + ty: Option, + offset: Option, +} + +impl PartialKey { + pub fn new(id: Option, ty: Option, offset: Option) -> Self { + Self { id, ty, offset } + } +} + +impl PartialEq for PartialKey { + fn eq(&self, other: &Key) -> bool { + self.id.map(|id| id == other.id()).unwrap_or(true) + && self.ty.map(|ty| ty == other.ty()).unwrap_or(true) + && self + .offset + .map(|offset| offset == other.offset.get()) + .unwrap_or(true) + } +} + +/// 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 for PartialKey { + fn partial_cmp(&self, other: &Key) -> Option { + let id = self.id.and_then(|id| id.partial_cmp(&other.id())); + let ty = self.ty.and_then(|ty| ty.partial_cmp(&other.ty())); + let offset = self + .offset + .and_then(|offset| offset.partial_cmp(&other.offset.get())); + + match id { + Some(core::cmp::Ordering::Equal) | None => match ty { + Some(core::cmp::Ordering::Equal) | None => offset, + ord => ord, + }, + ord => ord, + } + } +} + +#[cfg(test)] +mod partial_key_tests { + use test_log::test; + + use super::*; + + #[test] + fn test_partial_key_ord() { + let key = Key::new( + KnownObjectId::ChunkTree, + ObjectType::DirItem, + 0x8dbfc2d2, // crc of "default" + ); + + let pkey = PartialKey::new( + Some(KnownObjectId::ChunkTree), + Some(ObjectType::DirItem), + None, + ); + assert_eq!(pkey.partial_cmp(&key), None); + + let pkey = PartialKey::new( + Some(KnownObjectId::ChunkTree), + Some(ObjectType::DirItem), + Some(0xdeadbeef), + ); + 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); + } +} + #[derive(Debug, Clone)] pub struct BTreeLeafNode { pub header: Header,