diff --git a/src/trie.cpp b/src/trie.cpp index d53a135b..81c3f851 100644 --- a/src/trie.cpp +++ b/src/trie.cpp @@ -1,6 +1,7 @@ /* Copyright (c) 2009-2011 250bpm s.r.o. Copyright (c) 2007-2009 iMatix Corporation + Copyright (c) 2011-2012 Spotify AB Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file This file is part of 0MQ. @@ -35,7 +36,8 @@ zmq::trie_t::trie_t () : refcnt (0), min (0), - count (0) + count (0), + live_nodes (0) { } @@ -113,6 +115,7 @@ bool zmq::trie_t::add (unsigned char *prefix_, size_t size_) if (!next.node) { next.node = new (std::nothrow) trie_t; zmq_assert (next.node); + ++live_nodes; } return next.node->add (prefix_ + 1, size_ - 1); } @@ -120,6 +123,7 @@ bool zmq::trie_t::add (unsigned char *prefix_, size_t size_) if (!next.table [c - min]) { next.table [c - min] = new (std::nothrow) trie_t; zmq_assert (next.table [c - min]); + ++live_nodes; } return next.table [c - min]->add (prefix_ + 1, size_ - 1); } @@ -146,7 +150,18 @@ bool zmq::trie_t::rm (unsigned char *prefix_, size_t size_) if (!next_node) return false; - return next_node->rm (prefix_ + 1, size_ - 1); + bool ret = next_node->rm (prefix_ + 1, size_ - 1); + + if (next_node->is_redundant ()) { + delete next_node; + if (count == 1) + next.node = 0; + else + next.table [c - min] = 0; + --live_nodes; + } + + return ret; } bool zmq::trie_t::check (unsigned char *data_, size_t size_) @@ -224,6 +239,10 @@ void zmq::trie_t::apply_helper ( if (next.table [c]) next.table [c]->apply_helper (buff_, buffsize_ + 1, maxbuffsize_, func_, arg_); - } + } } +bool zmq::trie_t::is_redundant() const +{ + return refcnt == 0 && live_nodes == 0; +} diff --git a/src/trie.hpp b/src/trie.hpp index 76e4fd92..cde4b45e 100644 --- a/src/trie.hpp +++ b/src/trie.hpp @@ -1,6 +1,7 @@ /* Copyright (c) 2009-2011 250bpm s.r.o. Copyright (c) 2007-2009 iMatix Corporation + Copyright (c) 2011-2012 Spotify AB Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file This file is part of 0MQ. @@ -57,10 +58,12 @@ namespace zmq unsigned char **buff_, size_t buffsize_, size_t maxbuffsize_, void (*func_) (unsigned char *data_, size_t size_, void *arg_), void *arg_); + bool is_redundant () const; uint32_t refcnt; unsigned char min; unsigned short count; + unsigned short live_nodes; union { class trie_t *node; class trie_t **table;