fr_trie/
node.rs

1//! The Trie internal node implementation
2use std::fmt::Debug;
3use std::marker::PhantomData;
4use std::slice::Iter;
5use serde::{Serialize, Deserialize};
6use crate::key::{TrieKey, KeyPrefix, ValueMerge};
7use crate::iterator::{TrieIterator};
8use crate::matcher::PushdownStateMachine;
9
10#[derive(Clone, Serialize, Deserialize)]
11pub struct RFRNode<K: KeyPrefix + Clone, V: Clone> {
12    pub node_key: TrieKey<K>,
13
14    /// The key and value stored at this node.
15    pub value: Option<V>,
16
17    pub children: Vec<Box<RFRNode<K, V>>>,
18
19    #[serde(skip)]
20    _phantom_k: PhantomData<K>,
21
22    #[serde(skip)]
23    _phantom_v: PhantomData<V>,
24}
25
26impl<K, V> RFRNode<K, V> where K: KeyPrefix + Clone, V: Clone {
27
28    #[inline]
29    pub fn new() -> Self {
30        Self {
31            node_key: TrieKey::new(K::empty()),
32            value: None,
33            children: Vec::new(),
34            _phantom_k: Default::default(),
35            _phantom_v: Default::default(),
36        }
37    }
38
39    #[inline]
40    pub fn new_aux(node_key: TrieKey<K>) -> Self {
41        Self {
42            node_key,
43            value: None,
44            children: Vec::new(),
45            _phantom_k: Default::default(),
46            _phantom_v: Default::default(),
47        }
48    }
49
50    #[inline]
51    pub fn new_leaf_with_prefix(node_key: TrieKey<K>, value: V) -> Self {
52        Self {
53            node_key,
54            value: Some(value),
55            children: Vec::new(),
56            _phantom_k: Default::default(),
57            _phantom_v: Default::default(),
58        }
59    }
60
61    #[inline]
62    pub fn strip_prefix(&mut self, prefix_len: usize) {
63        self.node_key = TrieKey::new(self.node_key.key.new_from_key_prefix(prefix_len));
64    }
65
66    #[inline]
67    pub fn insert(&mut self, key: TrieKey<K>, value: Option<V>) -> Option<V>  {
68        
69        let mut prev_insert_index = 0 as usize;
70        let mut insert_index = 0 as usize;
71        let mut lcp = 0 as usize;
72        let mut index = 0 as usize;
73        let mut full_match = false;
74
75        for child in self.children.iter() {
76            let (item_lcp, item_is_preceeding, item_is_full_match) = key.lcp(&child.node_key);
77            prev_insert_index = index;
78            lcp = item_lcp;
79            full_match = item_is_full_match;
80            if !item_is_preceeding {
81                index += 1;
82                insert_index = index;
83                if lcp > 0 {
84                    break;
85                }
86            }
87            else {
88                break;
89            }
90        }
91
92        if full_match {
93            // Node already exists and is a full match
94            // Alternatives:
95            // 1. Colliding node is leaf -> Just replace
96            // 2. Colliding node is aux -> TBD
97            self.children.get_mut(prev_insert_index).unwrap().value = value.clone();
98        }
99        else {
100            if lcp > 0 { // Partial collision
101                // Child is leaf: Split
102                let prev_node = self.children.get_mut(prev_insert_index).unwrap();
103
104                let common_prefix = prev_node.node_key.key.new_from_key_prefix(lcp);
105                let prev_node_postfix = prev_node.node_key.key.new_from_postfix(lcp);
106
107                let new_node_postfix = key.key.new_from_postfix(lcp);
108                let new_node_postfix_kl = new_node_postfix.key_len();
109                let prev_node_postfix_kl = prev_node_postfix.key_len();
110                if prev_node_postfix_kl != 0 {
111                    let mut prev_node = self.children.remove(prev_insert_index);
112                    prev_node.strip_prefix(lcp);
113                    let mut aux: Box<RFRNode<K, V>> = if new_node_postfix_kl != 0 || value.is_none() {
114                        Box::new(RFRNode::new_aux(
115                            TrieKey::new(common_prefix)
116                        ))
117                    }
118                    else {
119                        Box::new(RFRNode::new_leaf_with_prefix(
120                            TrieKey::new(common_prefix),
121                            value.as_ref().unwrap().clone()
122                            ))
123                    };
124                    aux.insert(TrieKey::new(prev_node_postfix), prev_node.value);
125                    for _idx in 0..prev_node.children.len() {
126                        let prev_node_child = prev_node.children.remove(0);
127                        aux.children.get_mut(0).unwrap().children.push(prev_node_child);
128                    }
129                    if new_node_postfix_kl != 0 {
130                        aux.insert(TrieKey::new(new_node_postfix), value.clone());
131                    }
132                    self.children.insert(prev_insert_index, aux);
133                }
134                else {
135                    prev_node.insert(TrieKey::new(new_node_postfix), value.clone());
136                }
137            }
138            else {
139                // No collition -> Just insert as a leaf
140                if value.is_some() {
141                    self.children.insert(insert_index, Box::new(RFRNode::new_leaf_with_prefix(
142                        key,
143                        value.as_ref().unwrap().clone()
144                    )));
145                    return None;
146                }
147                else {
148                    self.children.insert(insert_index, Box::new(RFRNode::new_aux(
149                        key,
150                    )));
151                }
152            }
153        }
154        return value;
155    }
156
157    #[inline]
158    pub fn lookup<M: PushdownStateMachine + Clone>(&self, match_key: &K) -> TrieIterator<'_, K, V, M> {
159        TrieIterator::new(self, match_key)
160    }
161
162    #[inline]
163    pub fn get<M: PushdownStateMachine + Clone>(&self, key: &K) -> Option<V> {
164        for value in self.lookup::<M>(key) {
165            return Some(value);
166        }
167        None
168    }
169
170    pub fn get_merge<M: PushdownStateMachine + Clone>(&self, key: &K) -> Option<V>
171        where V: ValueMerge + Debug
172    {
173        let mut acc_value = None;
174        for value in self.lookup::<M>(key) {
175            if acc_value.is_none() {
176                acc_value.replace(value);
177            }
178            else {
179                acc_value.as_mut().unwrap().merge_mut(&value);
180            }
181        }
182        acc_value
183    }
184
185    #[inline]
186    pub fn iter(&self) -> Iter<'_, Box<RFRNode<K, V>>> {
187        self.children.iter()
188    }
189
190    pub fn foreach<F>(&self, level: usize, f: &F) -> ()
191        where F: Fn((usize, &K, &Option<V>))
192    {
193        for item in self.iter() {
194            f( (level, &item.node_key.key, &item.value) );
195            item.foreach( level + 1, f);
196        }
197    }
198}
199
200
201