31 #ifndef __BASE_TRIE_HH__ 32 #define __BASE_TRIE_HH__ 42 template <
class Key,
class Value>
54 return (test & mask) ==
key;
62 Node(Key _key, Key _mask, Value *_val) :
63 key(_key & _mask), mask(_mask), value(_val),
95 ccprintf(os,
"(%p, %p, %#X, %#X, %p)\n",
96 parent,
this, key, mask, value);
98 kids[0]->
dump(os, level + 1);
100 kids[1]->
dump(os, level + 1);
113 static const unsigned MaxBits =
sizeof(Key) * 8;
129 if (kid && kid->matches(key) && (kid->mask & new_mask) == kid->mask) {
149 const Key msb =
ULL(1) << (MaxBits - 1);
150 return orig | (orig >> 1) | msb;
168 if (node->kids[0] && node->kids[0]->matches(key))
169 node = node->
kids[0];
170 else if (node->kids[1] && node->kids[1]->matches(key))
171 node = node->
kids[1];
195 Key new_mask = ~(Key)0;
197 new_mask <<= (MaxBits -
width);
204 while (
goesAfter(&node, node->kids[0], key, new_mask) ||
205 goesAfter(&node, node->kids[1], key, new_mask))
209 Key cur_mask = node->mask;
211 if (cur_mask == new_mask) {
212 assert(!node->value);
217 for (
unsigned int i = 0;
i < 2;
i++) {
218 Node *&kid = node->kids[
i];
222 new_node =
new Node(key, new_mask, val);
223 new_node->parent = node;
233 last_mask = cur_mask;
235 done = ((key & cur_mask) != (kid->key & cur_mask)) ||
236 last_mask == new_mask;
238 cur_mask = last_mask;
241 if (cur_mask == node->mask)
245 new_node =
new Node(key, cur_mask, NULL);
246 new_node->parent = node;
247 kid->parent = new_node;
248 new_node->kids[0] = kid;
252 if (cur_mask == new_mask) {
253 new_node->value =
val;
258 new_node =
new Node(key, new_mask, val);
259 new_node->parent = kid;
260 kid->kids[1] = new_node;
264 panic(
"Reached the end of the Trie insert function!\n");
289 remove(Handle handle)
292 Value *
val = node->value;
299 panic(
"Trie: Can't remove root node.\n");
307 if (parent->kids[0] == node)
309 else if (parent->kids[1] == node)
312 panic(
"Trie: Inconsistent parent/kid relationship.\n");
314 if (parent->kids[1] && !parent->kids[0]) {
315 parent->kids[0] = parent->kids[1];
316 parent->kids[1] = NULL;
321 if (!parent->kids[1] && !parent->value && parent->parent)
338 return remove(handle);
356 dump(
const char *title, std::ostream &
os=std::cout)
358 ccprintf(
os,
"**************************************************\n");
359 ccprintf(
os,
"*** Start of Trie: %s\n", title);
360 ccprintf(
os,
"*** (parent, me, key, mask, value pointer)\n");
361 ccprintf(
os,
"**************************************************\n");
#define panic(...)
This implements a cprintf based panic() function.
void ccprintf(cp::Print &print)
Handle insert(Key key, unsigned width, Value *val)
Method which inserts a key/value pair into the trie.
bool goesAfter(Node **parent, Node *kid, Key key, Key new_mask)
A utility method which checks whether the key being looked up lies beyond the Node being examined...
static const unsigned MaxBits
Node(Key _key, Key _mask, Value *_val)
void clear()
A method which removes all key/value pairs from the trie.
Handle lookupHandle(Key key)
Method which looks up the Handle corresponding to a particular key.
void dump(std::ostream &os, int level)
Key extendMask(Key orig)
A utility method which extends a mask value one more bit towards the lsb.
Value * lookup(Key key)
Method which looks up the Value corresponding to a particular key.
void dump(const char *title, std::ostream &os=std::cout)
A debugging method which prints the contents of this trie.
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
#define ULL(N)
uint64_t constant