Skip to content

Commit

Permalink
add is_empty
Browse files Browse the repository at this point in the history
  • Loading branch information
XiangpengHao committed Nov 21, 2024
1 parent 33d7ae4 commit daab670
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 21 deletions.
48 changes: 40 additions & 8 deletions src/base_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,19 @@ macro_rules! gen_method {
pub(crate) fn $method_name(&self, $($arg_n : $args),*) -> $return {
match self.get_type() {
NodeType::N4 => {
let node = unsafe{&* (self as *const BaseNode as *const Node4)};
let node = self.as_n4();
node.$method_name($($arg_n),*)
},
NodeType::N16 => {
let node = unsafe{&* (self as *const BaseNode as *const Node16)};
let node = self.as_n16();
node.$method_name($($arg_n),*)
},
NodeType::N48 => {
let node = unsafe{&* (self as *const BaseNode as *const Node48)};
let node = self.as_n48();
node.$method_name($($arg_n),*)
},
NodeType::N256 => {
let node = unsafe{&* (self as *const BaseNode as *const Node256)};
let node = self.as_n256();
node.$method_name($($arg_n),*)
},
}
Expand All @@ -147,19 +147,19 @@ macro_rules! gen_method_mut {
pub(crate) fn $method_name(&mut self, $($arg_n : $args),*) -> $return {
match self.get_type() {
NodeType::N4 => {
let node = unsafe{&mut * (self as *mut BaseNode as *mut Node4)};
let node = self.as_n4_mut();
node.$method_name($($arg_n),*)
},
NodeType::N16 => {
let node = unsafe{&mut * (self as *mut BaseNode as *mut Node16)};
let node = self.as_n16_mut();
node.$method_name($($arg_n),*)
},
NodeType::N48 => {
let node = unsafe{&mut * (self as *mut BaseNode as *mut Node48)};
let node = self.as_n48_mut();
node.$method_name($($arg_n),*)
},
NodeType::N256 => {
let node = unsafe{&mut * (self as *mut BaseNode as *mut Node256)};
let node = self.as_n256_mut();
node.$method_name($($arg_n),*)
},
}
Expand Down Expand Up @@ -231,6 +231,38 @@ impl BaseNode {
self.meta.node_type
}

pub(crate) fn as_n4(&self) -> &Node4 {
unsafe { &*(self as *const BaseNode as *const Node4) }
}

pub(crate) fn as_n16(&self) -> &Node16 {
unsafe { &*(self as *const BaseNode as *const Node16) }
}

pub(crate) fn as_n48(&self) -> &Node48 {
unsafe { &*(self as *const BaseNode as *const Node48) }
}

pub(crate) fn as_n256(&self) -> &Node256 {
unsafe { &*(self as *const BaseNode as *const Node256) }
}

pub(crate) fn as_n4_mut(&mut self) -> &mut Node4 {
unsafe { &mut *(self as *mut BaseNode as *mut Node4) }
}

pub(crate) fn as_n16_mut(&mut self) -> &mut Node16 {
unsafe { &mut *(self as *mut BaseNode as *mut Node16) }
}

pub(crate) fn as_n48_mut(&mut self) -> &mut Node48 {
unsafe { &mut *(self as *mut BaseNode as *mut Node48) }
}

pub(crate) fn as_n256_mut(&mut self) -> &mut Node256 {
unsafe { &mut *(self as *mut BaseNode as *mut Node256) }
}

fn read_lock_inner<'a>(node: NonNull<BaseNode>) -> Result<ReadGuard<'a>, ArtError> {
let version = unsafe { &*node.as_ptr() }
.type_version_lock_obsolete
Expand Down
16 changes: 16 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,22 @@ where
}
}

/// Returns if the tree is empty.
///
/// # Examples
///
/// ```
/// use congee::Congee;
/// let tree = Congee::default();
/// let guard = tree.pin();
/// assert!(tree.is_empty(&guard));
/// tree.insert(1, 42, &guard);
/// assert!(!tree.is_empty(&guard));
/// ```
pub fn is_empty(&self, guard: &epoch::Guard) -> bool {
self.inner.is_empty(guard)
}

/// Removes key-value pair from the tree, returns the value if the key was found.
///
/// # Examples
Expand Down
1 change: 0 additions & 1 deletion src/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ impl<'a, T: Node> TypedReadGuard<'a, T> {
Ordering::Relaxed,
) {
Ok(_) => Ok(TypedWriteGuard {
// SAFETY: this is seems to be unsound, but we (1) acquired write lock, (2) has the right memory ordering.
node: unsafe { &mut *(self.node as *mut T) },
}),
Err(_v) => Err((self, ArtError::VersionNotMatch)),
Expand Down
17 changes: 5 additions & 12 deletions src/node_4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,11 @@ impl Node for Node4 {
}
}

unsafe {
std::ptr::copy(
self.keys.as_ptr().add(pos),
self.keys.as_mut_ptr().add(pos + 1),
self.base.meta.count as usize - pos,
);

std::ptr::copy(
self.children.as_ptr().add(pos),
self.children.as_mut_ptr().add(pos + 1),
self.base.meta.count as usize - pos,
);
if pos < self.base.meta.count as usize {
self.keys
.copy_within(pos..self.base.meta.count as usize, pos + 1);
self.children
.copy_within(pos..self.base.meta.count as usize, pos + 1);
}

self.keys[pos] = key;
Expand Down
11 changes: 11 additions & 0 deletions src/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ impl<const K_LEN: usize, A: Allocator + Clone> RawCongee<K_LEN, A> {
}

impl<const K_LEN: usize, A: Allocator + Clone + Send> RawCongee<K_LEN, A> {
pub(crate) fn is_empty(&self, _guard: &Guard) -> bool {
loop {
if let Ok(node) = BaseNode::read_lock_root(self.root) {
let is_empty = node.as_ref().meta.count == 0;
if node.check_version().is_ok() {
return is_empty;
}
}
}
}

#[inline]
pub(crate) fn get(&self, key: &[u8; K_LEN], _guard: &Guard) -> Option<usize> {
'outer: loop {
Expand Down

0 comments on commit daab670

Please sign in to comment.