Prune redundant nodes in the trie.

Signed-off-by: Staffan Gimåker <staffan@spotify.com>
This commit is contained in:
Staffan Gimåker 2012-01-03 16:24:44 +01:00
parent 6fa9ffebe5
commit 19129edc60
2 changed files with 25 additions and 3 deletions

View File

@ -1,6 +1,7 @@
/* /*
Copyright (c) 2009-2011 250bpm s.r.o. Copyright (c) 2009-2011 250bpm s.r.o.
Copyright (c) 2007-2009 iMatix Corporation Copyright (c) 2007-2009 iMatix Corporation
Copyright (c) 2011-2012 Spotify AB
Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
This file is part of 0MQ. This file is part of 0MQ.
@ -35,7 +36,8 @@
zmq::trie_t::trie_t () : zmq::trie_t::trie_t () :
refcnt (0), refcnt (0),
min (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) { if (!next.node) {
next.node = new (std::nothrow) trie_t; next.node = new (std::nothrow) trie_t;
zmq_assert (next.node); zmq_assert (next.node);
++live_nodes;
} }
return next.node->add (prefix_ + 1, size_ - 1); 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]) { if (!next.table [c - min]) {
next.table [c - min] = new (std::nothrow) trie_t; next.table [c - min] = new (std::nothrow) trie_t;
zmq_assert (next.table [c - min]); zmq_assert (next.table [c - min]);
++live_nodes;
} }
return next.table [c - min]->add (prefix_ + 1, size_ - 1); 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) if (!next_node)
return false; 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_) 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]) if (next.table [c])
next.table [c]->apply_helper (buff_, buffsize_ + 1, maxbuffsize_, next.table [c]->apply_helper (buff_, buffsize_ + 1, maxbuffsize_,
func_, arg_); func_, arg_);
} }
} }
bool zmq::trie_t::is_redundant() const
{
return refcnt == 0 && live_nodes == 0;
}

View File

@ -1,6 +1,7 @@
/* /*
Copyright (c) 2009-2011 250bpm s.r.o. Copyright (c) 2009-2011 250bpm s.r.o.
Copyright (c) 2007-2009 iMatix Corporation Copyright (c) 2007-2009 iMatix Corporation
Copyright (c) 2011-2012 Spotify AB
Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
This file is part of 0MQ. This file is part of 0MQ.
@ -57,10 +58,12 @@ namespace zmq
unsigned char **buff_, size_t buffsize_, size_t maxbuffsize_, unsigned char **buff_, size_t buffsize_, size_t maxbuffsize_,
void (*func_) (unsigned char *data_, size_t size_, void *arg_), void (*func_) (unsigned char *data_, size_t size_, void *arg_),
void *arg_); void *arg_);
bool is_redundant () const;
uint32_t refcnt; uint32_t refcnt;
unsigned char min; unsigned char min;
unsigned short count; unsigned short count;
unsigned short live_nodes;
union { union {
class trie_t *node; class trie_t *node;
class trie_t **table; class trie_t **table;