use std::fmt::Debug;
use std::marker::PhantomData;
use std::slice::Iter;
use serde::{Serialize, Deserialize};
use crate::key::{TrieKey, KeyPrefix, ValueMerge};
use crate::iterator::{TrieIterator};
use crate::matcher::PushdownStateMachine;
#[derive(Clone, Serialize, Deserialize)]
pub struct RFRNode<K: KeyPrefix + Clone, V: Clone> {
pub node_key: TrieKey<K>,
pub value: Option<V>,
pub children: Vec<Box<RFRNode<K, V>>>,
#[serde(skip)]
_phantom_k: PhantomData<K>,
#[serde(skip)]
_phantom_v: PhantomData<V>,
}
impl<K, V> RFRNode<K, V> where K: KeyPrefix + Clone, V: Clone {
#[inline]
pub fn new() -> Self {
Self {
node_key: TrieKey::new(K::empty()),
value: None,
children: Vec::new(),
_phantom_k: Default::default(),
_phantom_v: Default::default(),
}
}
#[inline]
pub fn new_aux(node_key: TrieKey<K>) -> Self {
Self {
node_key,
value: None,
children: Vec::new(),
_phantom_k: Default::default(),
_phantom_v: Default::default(),
}
}
#[inline]
pub fn new_leaf_with_prefix(node_key: TrieKey<K>, value: V) -> Self {
Self {
node_key,
value: Some(value),
children: Vec::new(),
_phantom_k: Default::default(),
_phantom_v: Default::default(),
}
}
#[inline]
pub fn strip_prefix(&mut self, prefix_len: usize) {
self.node_key = TrieKey::new(self.node_key.key.new_from_key_prefix(prefix_len));
}
#[inline]
pub fn insert(&mut self, key: TrieKey<K>, value: Option<V>) -> Option<V> {
let mut prev_insert_index = 0 as usize;
let mut insert_index = 0 as usize;
let mut lcp = 0 as usize;
let mut index = 0 as usize;
let mut full_match = false;
for child in self.children.iter() {
let (item_lcp, item_is_preceeding, item_is_full_match) = key.lcp(&child.node_key);
prev_insert_index = index;
lcp = item_lcp;
full_match = item_is_full_match;
if !item_is_preceeding {
index += 1;
insert_index = index;
if lcp > 0 {
break;
}
}
else {
break;
}
}
if full_match {
self.children.get_mut(prev_insert_index).unwrap().value = value.clone();
}
else {
if lcp > 0 { let prev_node = self.children.get_mut(prev_insert_index).unwrap();
let common_prefix = prev_node.node_key.key.new_from_key_prefix(lcp);
let prev_node_postfix = prev_node.node_key.key.new_from_postfix(lcp);
let new_node_postfix = key.key.new_from_postfix(lcp);
let new_node_postfix_kl = new_node_postfix.key_len();
let prev_node_postfix_kl = prev_node_postfix.key_len();
if prev_node_postfix_kl != 0 {
let mut prev_node = self.children.remove(prev_insert_index);
prev_node.strip_prefix(lcp);
let mut aux: Box<RFRNode<K, V>> = if new_node_postfix_kl != 0 || value.is_none() {
Box::new(RFRNode::new_aux(
TrieKey::new(common_prefix)
))
}
else {
Box::new(RFRNode::new_leaf_with_prefix(
TrieKey::new(common_prefix),
value.as_ref().unwrap().clone()
))
};
aux.insert(TrieKey::new(prev_node_postfix), prev_node.value);
for _idx in 0..prev_node.children.len() {
let prev_node_child = prev_node.children.remove(0);
aux.children.get_mut(0).unwrap().children.push(prev_node_child);
}
if new_node_postfix_kl != 0 {
aux.insert(TrieKey::new(new_node_postfix), value.clone());
}
self.children.insert(prev_insert_index, aux);
}
else {
prev_node.insert(TrieKey::new(new_node_postfix), value.clone());
}
}
else {
if value.is_some() {
self.children.insert(insert_index, Box::new(RFRNode::new_leaf_with_prefix(
key,
value.as_ref().unwrap().clone()
)));
return None;
}
else {
self.children.insert(insert_index, Box::new(RFRNode::new_aux(
key,
)));
}
}
}
return value;
}
#[inline]
pub fn lookup<M: PushdownStateMachine + Clone>(&self, match_key: &K) -> TrieIterator<'_, K, V, M> {
TrieIterator::new(self, match_key)
}
#[inline]
pub fn get<M: PushdownStateMachine + Clone>(&self, key: &K) -> Option<V> {
for value in self.lookup::<M>(key) {
return Some(value);
}
None
}
pub fn get_merge<M: PushdownStateMachine + Clone>(&self, key: &K) -> Option<V>
where V: ValueMerge + Debug
{
let mut acc_value = None;
for value in self.lookup::<M>(key) {
if acc_value.is_none() {
acc_value.replace(value);
}
else {
acc_value.as_mut().unwrap().merge_mut(&value);
}
}
acc_value
}
#[inline]
pub fn iter(&self) -> Iter<'_, Box<RFRNode<K, V>>> {
self.children.iter()
}
pub fn foreach<F>(&self, level: usize, f: &F) -> ()
where F: Fn((usize, &K, &Option<V>))
{
for item in self.iter() {
f( (level, &item.node_key.key, &item.value) );
item.foreach( level + 1, f);
}
}
}