0
0
mirror of https://github.com/zeromq/libzmq.git synced 2024-12-29 00:32:34 +08:00

More bugs in mtrie fixed

Aside of fixing couple of corner cases this patch turns the 'match'
function in mtrie from recursive to iterative.

Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
This commit is contained in:
Martin Sustrik 2011-09-16 16:34:28 +02:00
parent 5936379b29
commit e170136a2e
2 changed files with 26 additions and 25 deletions

View File

@ -209,33 +209,36 @@ bool zmq::mtrie_t::rm_helper (unsigned char *prefix_, size_t size_,
void zmq::mtrie_t::match (unsigned char *data_, size_t size_, void zmq::mtrie_t::match (unsigned char *data_, size_t size_,
void (*func_) (pipe_t *pipe_, void *arg_), void *arg_) void (*func_) (pipe_t *pipe_, void *arg_), void *arg_)
{ {
match_helper (data_, size_, func_, arg_); mtrie_t *current = this;
} while (size_) {
void zmq::mtrie_t::match_helper (unsigned char *data_, size_t size_, // Signal the pipes attached to this node.
void (*func_) (pipe_t *pipe_, void *arg_), void *arg_) for (pipes_t::iterator it = current->pipes.begin ();
{ it != current->pipes.end (); ++it)
// TODO: This function is on critical path. Rewrite it as iteration func_ (*it, arg_);
// rather than recursion.
// Signal the pipes attached to this node. // If there are no subnodes in the trie, return.
for (pipes_t::iterator it = pipes.begin (); it != pipes.end (); ++it) if (current->count == 0)
func_ (*it, arg_); break;
// If there are no subnodes in the trie, return. // If there's one subnode (optimisation).
if (count == 0) if (current->count == 1) {
return; if (data_ [0] != current->min)
break;
current = current->next.node;
data_++;
size_--;
continue;
}
// If there's one subnode (optimisation). // If there are multiple subnodes.
if (count == 1) { if (data_ [0] < min || data_ [0] >= min + count)
if (min == data_ [0]) break;
next.node->match_helper (data_ + 1, size_ - 1, func_, arg_); if (!current->next.table [data_ [0] - min])
return; break;
current = current->next.table [data_ [0] - min];
data_++;
size_--;
} }
// If there are multiple subnodes.
if (next.table [data_ [0] - min])
next.table [data_ [0] - min]->match_helper (data_ + 1, size_ - 1,
func_, arg_);
} }

View File

@ -67,8 +67,6 @@ namespace zmq
void *arg_); void *arg_);
bool rm_helper (unsigned char *prefix_, size_t size_, bool rm_helper (unsigned char *prefix_, size_t size_,
class pipe_t *pipe_); class pipe_t *pipe_);
void match_helper (unsigned char *data_, size_t size_,
void (*func_) (class pipe_t *pipe_, void *arg_), void *arg_);
typedef std::set <class pipe_t*> pipes_t; typedef std::set <class pipe_t*> pipes_t;
pipes_t pipes; pipes_t pipes;