#![allow(clippy::cast_possible_truncation)]
mod node;
#[cfg(test)]
mod tests;
use super::degree_router::EdgeIndex;
use node::CARTNode;
pub(crate) const MAX_LEAF_ENTRIES: usize = 256;
#[derive(Debug, Clone)]
pub struct CompressedART {
root: Option<Box<CARTNode>>,
len: usize,
}
impl Default for CompressedART {
fn default() -> Self {
Self::new()
}
}
impl CompressedART {
#[must_use]
pub fn new() -> Self {
Self { root: None, len: 0 }
}
#[must_use]
pub fn len(&self) -> usize {
self.len
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn insert(&mut self, value: u64) -> bool {
if self.contains(value) {
return false;
}
match &mut self.root {
None => {
self.root = Some(Box::new(CARTNode::new_leaf(value)));
self.len = 1;
true
}
Some(root) => {
let key_bytes = value.to_be_bytes();
if root.insert(&key_bytes, value) {
self.len += 1;
true
} else {
false
}
}
}
}
#[must_use]
pub fn contains(&self, value: u64) -> bool {
match &self.root {
None => false,
Some(root) => {
let key_bytes = value.to_be_bytes();
root.search(&key_bytes, value)
}
}
}
pub fn remove(&mut self, value: u64) -> bool {
match &mut self.root {
None => false,
Some(root) => {
let key_bytes = value.to_be_bytes();
if root.remove(&key_bytes, value) {
self.len -= 1;
if root.is_empty() {
self.root = None;
}
true
} else {
false
}
}
}
}
#[must_use]
pub fn scan(&self) -> Vec<u64> {
let mut result = Vec::with_capacity(self.len);
if let Some(root) = &self.root {
root.collect_all(&mut result);
}
result
}
pub fn iter(&self) -> impl Iterator<Item = u64> + '_ {
self.scan().into_iter()
}
}
#[derive(Debug, Clone, Default)]
pub struct CARTEdgeIndex {
tree: CompressedART,
}
impl CARTEdgeIndex {
#[must_use]
pub fn new() -> Self {
Self {
tree: CompressedART::new(),
}
}
#[must_use]
pub fn from_targets(targets: &[u64]) -> Self {
let mut tree = CompressedART::new();
for &target in targets {
tree.insert(target);
}
Self { tree }
}
}
impl EdgeIndex for CARTEdgeIndex {
fn insert(&mut self, target: u64) {
self.tree.insert(target);
}
fn remove(&mut self, target: u64) -> bool {
self.tree.remove(target)
}
fn contains(&self, target: u64) -> bool {
self.tree.contains(target)
}
fn targets(&self) -> Vec<u64> {
self.tree.scan()
}
fn len(&self) -> usize {
self.tree.len()
}
}