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:
parent
5936379b29
commit
e170136a2e
@ -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_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user