summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/patricia.h265
1 files changed, 0 insertions, 265 deletions
diff --git a/include/patricia.h b/include/patricia.h
deleted file mode 100644
index 5893a209e..000000000
--- a/include/patricia.h
+++ /dev/null
@@ -1,265 +0,0 @@
-
-/* Gets the bit-th bit from key */
-#define GET_BIT(key, bit) (key[bit / 8] & (1 << (bit & 7)))
-/* Checks if the bit-th bit from key1 and key2 differ, returns 1 if they do */
-#define GET_BIT_XOR(key1, key2, bit) ((key1[bit / 8] ^ key2[bit / 8]) & (1 << (bit & 7)))
-
-template<typename Data> struct patricia_elem
-{
- unsigned int bit;
- patricia_elem<Data> *up, *one, *zero;
- Anope::string key;
- Data data;
-};
-
-template<typename Data, typename char_traits = std::std_char_traits>
-class patricia_tree
-{
- typedef std::basic_string<char, char_traits, std::allocator<char> > String;
-
- patricia_elem<Data> *root;
- size_t count;
-
- public:
- patricia_tree()
- {
- this->root = NULL;
- this->count = 0;
- }
-
- virtual ~patricia_tree()
- {
- while (this->root)
- this->erase(this->root->key);
- }
-
- inline size_t size() const { return this->count; }
- inline bool empty() const { return this->count == 0; }
-
- Data find(const Anope::string &ukey)
- {
- Anope::string key;
- for (size_t i = 0, j = ukey.length(); i < j; ++i)
- key.push_back(char_traits::chartolower(ukey[i]));
-
- size_t keylen = key.length();
- patricia_elem<Data> *prev = NULL, *cur = this->root;
- bool bitval;
- while (cur && (!prev || prev->bit < cur->bit))
- {
- prev = cur;
-
- if (cur->bit / 8 < keylen)
- bitval = GET_BIT(key, cur->bit);
- else
- bitval = false;
-
- cur = bitval ? cur->one : cur->zero;
- }
-
- if (cur && String(cur->key.c_str()).compare(key.c_str()) == 0)
- return cur->data;
-
- return NULL;
- }
-
- void insert(const Anope::string &ukey, Data data)
- {
- Anope::string key;
- for (size_t i = 0, j = ukey.length(); i < j; ++i)
- key.push_back(char_traits::chartolower(ukey[i]));
-
- size_t keylen = key.length();
- patricia_elem<Data> *prev = NULL, *cur = this->root;
- bool bitval;
- while (cur && (!prev || prev->bit < cur->bit))
- {
- prev = cur;
-
- if (cur->bit / 8 < keylen)
- bitval = GET_BIT(key, cur->bit);
- else
- bitval = false;
-
- cur = bitval ? cur->one : cur->zero;
- }
-
- if (cur && String(cur->key.c_str()).compare(key.c_str()) == 0)
- return;
-
- patricia_elem<Data> *newelem = new patricia_elem<Data>();
- newelem->key = key;
- newelem->data = data;
-
- if (!cur)
- newelem->bit = prev ? prev->bit + 1 : 0;
- else
- for (newelem->bit = 0; GET_BIT_XOR(key, cur->key, newelem->bit) == 0; ++newelem->bit);
-
- patricia_elem<Data> *place = prev;
-
- while (place && newelem->bit < place->bit)
- {
- prev = place;
- place = place->up;
- }
-
- newelem->up = place;
-
- if (GET_BIT(key, newelem->bit))
- {
- newelem->one = newelem;
- newelem->zero = place == prev ? cur : prev;
- }
- else
- {
- newelem->zero = newelem;
- newelem->one = place == prev ? cur : prev;
- }
-
- if (place != prev)
- prev->up = newelem;
-
- if (place)
- {
- bitval = GET_BIT(key, place->bit);
- if (bitval)
- place->one = newelem;
- else
- place->zero = newelem;
- }
- else
- this->root = newelem;
-
- ++this->count;
- }
-
- Data erase(const Anope::string &ukey)
- {
- Anope::string key;
- for (size_t i = 0, j = ukey.length(); i < j; ++i)
- key.push_back(char_traits::chartolower(ukey[i]));
-
- size_t keylen = key.length();
- patricia_elem<Data> *prev = NULL, *cur = this->root;
- bool bitval;
- while (cur && (!prev || prev->bit < cur->bit))
- {
- prev = cur;
-
- if (cur->bit / 8 < keylen)
- bitval = GET_BIT(key, cur->bit);
- else
- bitval = false;
-
- cur = bitval ? cur->one : cur->zero;
- }
-
- if (!cur || String(cur->key.c_str()).compare(key.c_str()))
- return NULL;
-
- patricia_elem<Data> *other = (bitval ? prev->zero : prev->one);
-
- if (!prev->up)
- this->root = other;
- else if (prev->up->zero == prev)
- prev->up->zero = other;
- else
- prev->up->one = other;
-
- if (prev->zero && prev->zero->up == prev)
- prev->zero->up = prev->up;
- if (prev->one && prev->one->up == prev)
- prev->one->up = prev->up;
-
- if (cur != prev)
- {
- if (!cur->up)
- this->root = prev;
- else if (cur->up->zero == cur)
- cur->up->zero = prev;
- else
- cur->up->one = prev;
-
- if (cur->zero && cur->zero->up == cur)
- cur->zero->up = prev;
- if (cur->one && cur->one->up == cur)
- cur->one->up = prev;
-
- prev->one = cur->one;
- prev->zero = cur->zero;
- prev->up = cur->up;
- prev->bit = cur->bit;
- }
-
- Data data = cur->data;
- delete cur;
-
- --this->count;
-
- return data;
- }
-
- class iterator
- {
- enum IterationState
- {
- ITERATION_AT_CENTER,
- ITERATION_FROM_CENTER
- };
-
- patricia_elem<Data> *elem;
- IterationState from;
-
- public:
- iterator(patricia_tree<Data, char_traits> &tree)
- {
- this->elem = tree.root;
- this->from = ITERATION_AT_CENTER;
- }
-
- bool next()
- {
- if (this->elem == NULL)
- ;
- else if (this->from == ITERATION_AT_CENTER)
- {
- if (this->elem->zero != NULL && this->elem->zero->bit > this->elem->bit)
- {
- this->elem = this->elem->zero;
- return this->next();
- }
-
- this->from = ITERATION_FROM_CENTER;
- return true;
- }
- else if (this->from == ITERATION_FROM_CENTER)
- {
- if (this->elem->one != NULL && this->elem->one->bit > this->elem->bit)
- {
- this->elem = this->elem->one;
- this->from = ITERATION_AT_CENTER;
- return this->next();
- }
-
- while (this->elem->up != NULL && this->elem->up->one == this->elem)
- this->elem = this->elem->up;
-
- if (this->elem->up != NULL)
- {
- this->elem = this->elem->up;
- return true;
- }
- }
-
- return false;
- }
-
- inline Data operator*()
- {
- return this->elem->data;
- }
- };
-};
-
-