use crate::keys::*;
use crate::{SubTrie, SubTrieMut, BRANCH_FACTOR};
use std::borrow::Borrow;
use std::default::Default;
use nibble_vec::Nibblet;
#[derive(Debug, Clone)]
pub struct TrieNode<K, V> {
pub key: Nibblet,
pub key_value: Option<Box<KeyValue<K, V>>>,
pub child_count: usize,
pub children: [Option<Box<TrieNode<K, V>>>; BRANCH_FACTOR],
}
#[derive(Debug, Clone)]
pub struct KeyValue<K, V> {
pub key: K,
pub value: V,
}
impl<K, V> TrieNode<K, V>
where
K: TrieKey,
{
#[inline]
pub fn new() -> TrieNode<K, V> {
TrieNode {
key: Nibblet::new(),
key_value: None,
children: Default::default(),
child_count: 0,
}
}
#[inline]
pub fn with_key_value(key_fragments: Nibblet, key: K, value: V) -> TrieNode<K, V> {
TrieNode {
key: key_fragments,
key_value: Some(Box::new(KeyValue {
key: key,
value: value,
})),
children: Default::default(),
child_count: 0,
}
}
#[inline]
pub fn key(&self) -> Option<&K> {
self.key_value.as_ref().map(|kv| &kv.key)
}
#[inline]
pub fn value(&self) -> Option<&V> {
self.key_value.as_ref().map(|kv| &kv.value)
}
#[inline]
pub fn value_mut(&mut self) -> Option<&mut V> {
self.key_value.as_mut().map(|kv| &mut kv.value)
}
#[inline]
pub fn value_checked<Q: ?Sized>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: TrieKey,
{
self.key_value.as_ref().map(|kv| {
check_keys(kv.key.borrow(), key);
&kv.value
})
}
#[inline]
pub fn value_checked_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: TrieKey,
{
self.key_value.as_mut().map(|kv| {
check_keys(kv.key.borrow(), key);
&mut kv.value
})
}
#[inline]
pub fn compute_size(&self) -> usize {
let mut size = self.key_value.is_some() as usize;
for child in &self.children {
if let Some(ref child) = *child {
size += child.compute_size();
}
}
size
}
#[inline]
pub fn add_child(&mut self, idx: usize, node: Box<TrieNode<K, V>>) {
debug_assert!(self.children[idx].is_none());
self.child_count += 1;
self.children[idx] = Some(node);
}
#[inline]
pub fn take_child(&mut self, idx: usize) -> Option<Box<TrieNode<K, V>>> {
self.children[idx].take().map(|node| {
self.child_count -= 1;
node
})
}
#[inline]
pub fn take_only_child(&mut self) -> Box<TrieNode<K, V>> {
debug_assert_eq!(self.child_count, 1);
for i in 0..BRANCH_FACTOR {
if let Some(child) = self.take_child(i) {
return child;
}
}
unreachable!("node with child_count 1 has no actual children");
}
#[inline]
pub fn add_key_value(&mut self, key: K, value: V) {
debug_assert!(self.key_value.is_none());
self.key_value = Some(Box::new(KeyValue { key, value }));
}
#[inline]
pub fn take_value<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: TrieKey,
{
self.key_value.take().map(|kv| {
check_keys(kv.key.borrow(), key);
kv.value
})
}
#[inline]
pub fn replace_value(&mut self, key: K, value: V) -> Option<V> {
let previous = self.take_value(&key);
self.add_key_value(key, value);
previous
}
#[inline]
pub fn as_value_node(&self) -> Option<&TrieNode<K, V>> {
self.key_value.as_ref().map(|_| self)
}
#[inline]
pub fn split(&mut self, idx: usize) {
let key = self.key.split(idx);
let key_value = self.key_value.take();
let mut children: [Option<Box<TrieNode<K, V>>>; BRANCH_FACTOR] = Default::default();
for (i, child) in self.children.iter_mut().enumerate() {
if child.is_some() {
children[i] = child.take();
}
}
let child_count = self.child_count;
self.child_count = 1;
let bucket = key.get(0) as usize;
self.children[bucket] = Some(Box::new(TrieNode {
key: key,
key_value,
children,
child_count,
}));
}
#[inline]
pub fn as_subtrie(&self, prefix: Nibblet) -> SubTrie<K, V> {
SubTrie {
prefix: prefix,
node: self,
}
}
#[inline]
pub fn as_subtrie_mut<'a>(
&'a mut self,
prefix: Nibblet,
length: &'a mut usize,
) -> SubTrieMut<'a, K, V> {
SubTrieMut {
prefix: prefix,
length: length,
node: self,
}
}
pub fn check_integrity_recursive(&self, prefix: &Nibblet) -> (bool, usize) {
let mut sub_tree_size = 0;
let is_root = prefix.len() == 0;
if !is_root && self.child_count == 1 && self.key_value.is_none() {
println!("Value-less node with a single child.");
return (false, sub_tree_size);
}
if !is_root && self.key.len() == 0 {
println!("Key length is 0 at non-root node.");
return (false, sub_tree_size);
}
let child_count = self
.children
.iter()
.fold(0, |acc, e| acc + (e.is_some() as usize));
if child_count != self.child_count {
println!(
"Child count error, recorded: {}, actual: {}",
self.child_count, child_count
);
return (false, sub_tree_size);
}
let trie_key = prefix.clone().join(&self.key);
if let Some(ref kv) = self.key_value {
sub_tree_size += 1;
let actual_key = kv.key.encode();
if trie_key != actual_key {
return (false, sub_tree_size);
}
}
for i in 0..BRANCH_FACTOR {
if let Some(ref child) = self.children[i] {
match child.check_integrity_recursive(&trie_key) {
(false, _) => return (false, sub_tree_size),
(true, child_size) => sub_tree_size += child_size,
}
}
}
(true, sub_tree_size)
}
}
impl<K: TrieKey, V> Default for TrieNode<K, V> {
fn default() -> Self {
Self::new()
}
}