Prune redundant nodes in the mtrie.

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

View File

@ -1,5 +1,6 @@
/* /*
Copyright (c) 2011 250bpm s.r.o. Copyright (c) 2011 250bpm s.r.o.
Copyright (c) 2011-2012 Spotify AB
Copyright (c) 2011 Other contributors as noted in the AUTHORS file Copyright (c) 2011 Other contributors as noted in the AUTHORS file
This file is part of 0MQ. This file is part of 0MQ.
@ -34,7 +35,8 @@
zmq::mtrie_t::mtrie_t () : zmq::mtrie_t::mtrie_t () :
min (0), min (0),
count (0) count (0),
live_nodes (0)
{ {
} }
@ -118,6 +120,7 @@ bool zmq::mtrie_t::add_helper (unsigned char *prefix_, size_t size_,
if (count == 1) { if (count == 1) {
if (!next.node) { if (!next.node) {
next.node = new (std::nothrow) mtrie_t; next.node = new (std::nothrow) mtrie_t;
++live_nodes;
zmq_assert (next.node); zmq_assert (next.node);
} }
return next.node->add_helper (prefix_ + 1, size_ - 1, pipe_); return next.node->add_helper (prefix_ + 1, size_ - 1, pipe_);
@ -125,6 +128,7 @@ bool zmq::mtrie_t::add_helper (unsigned char *prefix_, size_t size_,
else { else {
if (!next.table [c - min]) { if (!next.table [c - min]) {
next.table [c - min] = new (std::nothrow) mtrie_t; next.table [c - min] = new (std::nothrow) mtrie_t;
++live_nodes;
zmq_assert (next.table [c - min]); zmq_assert (next.table [c - min]);
} }
return next.table [c - min]->add_helper (prefix_ + 1, size_ - 1, pipe_); return next.table [c - min]->add_helper (prefix_ + 1, size_ - 1, pipe_);
@ -167,6 +171,11 @@ void zmq::mtrie_t::rm_helper (pipe_t *pipe_, unsigned char **buff_,
buffsize_++; buffsize_++;
next.node->rm_helper (pipe_, buff_, buffsize_, maxbuffsize_, next.node->rm_helper (pipe_, buff_, buffsize_, maxbuffsize_,
func_, arg_); func_, arg_);
if (next.node->is_redundant ()) {
delete next.node;
next.node = 0;
--live_nodes;
}
return; return;
} }
@ -176,6 +185,11 @@ void zmq::mtrie_t::rm_helper (pipe_t *pipe_, unsigned char **buff_,
if (next.table [c]) if (next.table [c])
next.table [c]->rm_helper (pipe_, buff_, buffsize_ + 1, next.table [c]->rm_helper (pipe_, buff_, buffsize_ + 1,
maxbuffsize_, func_, arg_); maxbuffsize_, func_, arg_);
if (next.table [c]->is_redundant ()) {
delete next.table [c];
next.table [c] = 0;
--live_nodes;
}
} }
} }
@ -203,7 +217,18 @@ bool zmq::mtrie_t::rm_helper (unsigned char *prefix_, size_t size_,
if (!next_node) if (!next_node)
return false; return false;
return next_node->rm_helper (prefix_ + 1, size_ - 1, pipe_); bool ret = next_node->rm_helper (prefix_ + 1, size_ - 1, pipe_);
if (next_node->is_redundant ()) {
delete next_node;
if (count == 1)
next.node = 0;
else
next.table [c - min] = 0;
--live_nodes;
}
return ret;
} }
void zmq::mtrie_t::match (unsigned char *data_, size_t size_, void zmq::mtrie_t::match (unsigned char *data_, size_t size_,
@ -247,3 +272,7 @@ void zmq::mtrie_t::match (unsigned char *data_, size_t size_,
} }
} }
bool zmq::mtrie_t::is_redundant() const
{
return pipes.empty () && live_nodes == 0;
}

View File

@ -1,5 +1,6 @@
/* /*
Copyright (c) 2011 250bpm s.r.o. Copyright (c) 2011 250bpm s.r.o.
Copyright (c) 2011-2012 Spotify AB
Copyright (c) 2011 Other contributors as noted in the AUTHORS file Copyright (c) 2011 Other contributors as noted in the AUTHORS file
This file is part of 0MQ. This file is part of 0MQ.
@ -69,12 +70,14 @@ namespace zmq
void *arg_); void *arg_);
bool rm_helper (unsigned char *prefix_, size_t size_, bool rm_helper (unsigned char *prefix_, size_t size_,
zmq::pipe_t *pipe_); zmq::pipe_t *pipe_);
bool is_redundant () const;
typedef std::set <zmq::pipe_t*> pipes_t; typedef std::set <zmq::pipe_t*> pipes_t;
pipes_t pipes; pipes_t pipes;
unsigned char min; unsigned char min;
unsigned short count; unsigned short count;
unsigned short live_nodes;
union { union {
class mtrie_t *node; class mtrie_t *node;
class mtrie_t **table; class mtrie_t **table;