Skip to content

Commit

Permalink
chore: remove BitArray<T,SIZE> in favor of [Option<T>;SIZE] (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
DelSkayn authored Feb 7, 2024
1 parent 716f4ff commit 25f9c14
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 344 deletions.
12 changes: 6 additions & 6 deletions src/art.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ impl<P: KeyTrait + Clone, V: Clone> Node<P, V> {
#[inline]
fn is_full(&self) -> bool {
match &self.node_type {
NodeType::Node1(n) => self.num_children() >= n.size(),
NodeType::Node4(n) => self.num_children() >= n.size(),
NodeType::Node16(n) => self.num_children() >= n.size(),
NodeType::Node48(n) => self.num_children() >= n.size(),
NodeType::Node256(n) => self.num_children() > n.size(),
NodeType::Node1(n) => n.num_children() >= n.size(),
NodeType::Node4(n) => n.num_children() >= n.size(),
NodeType::Node16(n) => n.num_children() >= n.size(),
NodeType::Node48(n) => n.num_children() >= n.size(),
NodeType::Node256(n) => n.num_children() > n.size(),
NodeType::Twig(_) => panic!("Unexpected Twig node encountered in is_full()"),
}
}
Expand Down Expand Up @@ -1629,7 +1629,7 @@ mod tests {
// Insertion
for i in 0..49u32 {
let key = VariableSizeKey::from_slice(&i.to_be_bytes());
tree.insert(&key, 1, 0, 0);
tree.insert(&key, 1, 0, 0).unwrap();
}

// Removal
Expand Down
257 changes: 0 additions & 257 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,166 +373,6 @@ impl<const SIZE: usize> BitSet<SIZE> {
}
}

/// A struct `BitArray` is a generic wrapper over an array that can store elements of type `X`.
pub struct BitArray<X, const WIDTH: usize> {
items: Box<[MaybeUninit<X>; WIDTH]>,
bits: BitSet<WIDTH>,
}
/// This is an implementation of the Default trait for BitArray. It simply calls the `new` function.
impl<X, const WIDTH: usize> Default for BitArray<X, WIDTH> {
fn default() -> Self {
Self::new()
}
}

impl<X, const WIDTH: usize> BitArray<X, WIDTH> {
/// This function constructs a new BitArray with a `WIDTH` number of `Option<X>` elements.
pub fn new() -> Self {
Self {
items: Box::new(unsafe { MaybeUninit::uninit().assume_init() }),
bits: BitSet::new(),
}
}

pub fn push(&mut self, x: X) -> Option<usize> {
if let Some(pos) = self.bits.first_empty() {
self.bits.set(pos);
unsafe {
self.items[pos].as_mut_ptr().write(x);
}
Some(pos)
} else {
None
}
}

pub fn pop(&mut self) -> Option<X> {
if let Some(pos) = self.bits.last() {
self.bits.unset(pos);
let old = std::mem::replace(&mut self.items[pos], MaybeUninit::uninit());
Some(unsafe { old.assume_init() })
} else {
None
}
}

pub fn last(&self) -> Option<&X> {
if let Some(pos) = self.bits.last() {
unsafe { Some(self.items[pos].assume_init_ref()) }
} else {
None
}
}

pub fn get(&self, pos: usize) -> Option<&X> {
if self.bits.check(pos) {
unsafe { Some(self.items[pos].assume_init_ref()) }
} else {
None
}
}

pub fn get_mut(&mut self, pos: usize) -> Option<&mut X> {
if self.bits.check(pos) {
unsafe { Some(self.items[pos].assume_init_mut()) }
} else {
None
}
}

pub fn set(&mut self, pos: usize, x: X) {
if pos < self.items.len() {
unsafe {
self.items[pos].as_mut_ptr().write(x);
};
self.bits.set(pos);
}
}

#[inline]
pub fn erase(&mut self, pos: usize) -> Option<X> {
assert!(pos < WIDTH);
if self.bits.check(pos) {
let old = std::mem::replace(&mut self.items[pos], MaybeUninit::uninit());
self.bits.unset(pos);
Some(unsafe { old.assume_init() })
} else {
None
}
}

pub fn clear(&mut self) {
for i in 0..WIDTH {
if self.bits.check(i) {
unsafe { self.items[i].assume_init_drop() }
}
}
self.bits.clear();
}

pub fn is_empty(&self) -> bool {
self.bits.is_empty()
}

pub fn iter_keys(&self) -> impl DoubleEndedIterator<Item = usize> + '_ {
self.items.iter().enumerate().filter_map(|x| {
if self.bits.check(x.0) {
Some(x.0)
} else {
None
}
})
}

pub fn iter(&self) -> impl DoubleEndedIterator<Item = (usize, &X)> {
self.items.iter().enumerate().filter_map(move |x| {
if self.bits.check(x.0) {
unsafe { Some((x.0, x.1.assume_init_ref())) }
} else {
None
}
})
}

#[inline]
pub fn first_free_pos(&self) -> Option<usize> {
self.bits.first_empty()
}

#[inline]
pub fn last_used_pos(&self) -> Option<usize> {
self.bits.last()
}
}

impl<X: Clone, const WIDTH: usize> Clone for BitArray<X, WIDTH> {
fn clone(&self) -> Self {
let mut new_items: Box<[MaybeUninit<X>; WIDTH]> =
Box::new(unsafe { MaybeUninit::uninit().assume_init() });

for i in 0..WIDTH {
if self.bits.check(i) {
new_items[i] = MaybeUninit::new(unsafe { self.items[i].assume_init_ref() }.clone());
}
}
Self {
items: new_items,
bits: self.bits.clone(),
}
}
}

impl<X, const WIDTH: usize> Drop for BitArray<X, WIDTH> {
fn drop(&mut self) {
for i in 0..WIDTH {
if self.bits.check(i) {
unsafe { self.items[i].assume_init_drop() }
}
}
self.bits.clear();
}
}

// Define a custom error enum representing different error cases for the Trie
#[derive(Clone, Debug)]
pub enum TrieError {
Expand Down Expand Up @@ -571,100 +411,3 @@ impl fmt::Display for TrieError {
}
}
}

#[cfg(test)]
mod tests {
use super::BitArray;

#[test]
fn push_and_pop() {
let mut v: BitArray<i32, 10> = BitArray::new();
let index = v.push(5).unwrap();
assert_eq!(v.get(index), Some(&5));
assert_eq!(v.pop(), Some(5));
}

#[test]
fn last() {
let mut v: BitArray<i32, 10> = BitArray::new();
v.push(5);
v.push(6);
assert_eq!(v.last(), Some(&6));
}

#[test]
fn last_used_pos() {
let mut v: BitArray<i32, 10> = BitArray::new();
v.push(5);
v.push(6);
assert_eq!(v.last_used_pos(), Some(1));
}

#[test]
fn first_free_pos() {
let mut v: BitArray<i32, 10> = BitArray::new();
v.push(5);
assert_eq!(v.first_free_pos().unwrap(), 1);
}

#[test]
fn get_and_set() {
let mut v: BitArray<i32, 10> = BitArray::new();
v.set(5, 6);
assert_eq!(v.get(5), Some(&6));
}

#[test]
fn get_mut() {
let mut v: BitArray<i32, 10> = BitArray::new();
v.set(5, 6);
if let Some(value) = v.get_mut(5) {
*value = 7;
}
assert_eq!(v.get(5), Some(&7));
}

#[test]
fn erase() {
let mut v: BitArray<i32, 10> = BitArray::new();
v.push(5);

assert_eq!(*v.get(0).unwrap(), 5);
assert_eq!(v.erase(0), Some(5));
assert_eq!(v.get(0), None);
}

#[test]
fn clear() {
let mut v: BitArray<i32, 10> = BitArray::new();
v.push(5);
v.clear();
assert!(v.is_empty());
}

#[test]
fn is_empty() {
let mut v: BitArray<i32, 10> = BitArray::new();
assert!(v.is_empty());
v.push(5);
assert!(!v.is_empty());
}

#[test]
fn iter_keys() {
let mut v: BitArray<i32, 10> = BitArray::new();
v.push(5);
v.push(6);
let keys: Vec<usize> = v.iter_keys().collect();
assert_eq!(keys, vec![0, 1]);
}

#[test]
fn iter() {
let mut v: BitArray<i32, 10> = BitArray::new();
v.push(5);
v.push(6);
let values: Vec<(usize, &i32)> = v.iter().collect();
assert_eq!(values, vec![(0, &5), (1, &6)]);
}
}
Loading

0 comments on commit 25f9c14

Please sign in to comment.