Unverified Commit a43c842e authored by Luca Boccassi's avatar Luca Boccassi Committed by GitHub

Merge pull request #3556 from ssbl/better-names

Problem: variable and type names are not descriptive
parents 68b744fa d1e6fe19
......@@ -36,143 +36,145 @@
#include <string.h>
#include <vector>
node::node (unsigned char *data) : data_ (data)
node_t::node_t (unsigned char *data) : data_ (data)
{
}
uint32_t node::refcount ()
uint32_t node_t::refcount ()
{
uint32_t u32;
memcpy (&u32, data_, sizeof (u32));
return u32;
}
void node::set_refcount (uint32_t value)
void node_t::set_refcount (uint32_t value)
{
memcpy (data_, &value, sizeof (value));
}
uint32_t node::prefix_length ()
uint32_t node_t::prefix_length ()
{
uint32_t u32;
memcpy (&u32, data_ + sizeof (uint32_t), sizeof (u32));
return u32;
}
void node::set_prefix_length (uint32_t value)
void node_t::set_prefix_length (uint32_t value)
{
memcpy (data_ + sizeof (value), &value, sizeof (value));
}
uint32_t node::edgecount ()
uint32_t node_t::edgecount ()
{
uint32_t u32;
memcpy (&u32, data_ + 2 * sizeof (uint32_t), sizeof (u32));
return u32;
}
void node::set_edgecount (uint32_t value)
void node_t::set_edgecount (uint32_t value)
{
memcpy (data_ + 2 * sizeof (value), &value, sizeof (value));
}
unsigned char *node::prefix ()
unsigned char *node_t::prefix ()
{
return data_ + 3 * sizeof (uint32_t);
}
void node::set_prefix (const unsigned char *bytes)
void node_t::set_prefix (const unsigned char *bytes)
{
memcpy (prefix (), bytes, prefix_length ());
}
unsigned char *node::first_bytes ()
unsigned char *node_t::first_bytes ()
{
return prefix () + prefix_length ();
}
void node::set_first_bytes (const unsigned char *bytes)
void node_t::set_first_bytes (const unsigned char *bytes)
{
memcpy (first_bytes (), bytes, edgecount ());
}
unsigned char node::first_byte_at (size_t i)
unsigned char node_t::first_byte_at (size_t index)
{
zmq_assert (i < edgecount ());
return first_bytes ()[i];
zmq_assert (index < edgecount ());
return first_bytes ()[index];
}
void node::set_first_byte_at (size_t i, unsigned char byte)
void node_t::set_first_byte_at (size_t index, unsigned char byte)
{
zmq_assert (i < edgecount ());
first_bytes ()[i] = byte;
zmq_assert (index < edgecount ());
first_bytes ()[index] = byte;
}
unsigned char *node::node_ptrs ()
unsigned char *node_t::node_pointers ()
{
return prefix () + prefix_length () + edgecount ();
}
void node::set_node_ptrs (const unsigned char *ptrs)
void node_t::set_node_pointers (const unsigned char *pointers)
{
memcpy (node_ptrs (), ptrs, edgecount () * sizeof (void *));
memcpy (node_pointers (), pointers, edgecount () * sizeof (void *));
}
node node::node_at (size_t i)
node_t node_t::node_at (size_t index)
{
zmq_assert (i < edgecount ());
zmq_assert (index < edgecount ());
unsigned char *data;
memcpy (&data, node_ptrs () + i * sizeof (void *), sizeof (data));
return node (data);
memcpy (&data, node_pointers () + index * sizeof (void *), sizeof (data));
return node_t (data);
}
void node::set_node_at (size_t i, node n)
void node_t::set_node_at (size_t index, node_t node)
{
zmq_assert (i < edgecount ());
memcpy (node_ptrs () + i * sizeof (void *), &n.data_, sizeof (n.data_));
zmq_assert (index < edgecount ());
memcpy (node_pointers () + index * sizeof (void *), &node.data_,
sizeof (node.data_));
}
void node::set_edge_at (size_t i, unsigned char byte, node n)
void node_t::set_edge_at (size_t index, unsigned char first_byte, node_t node)
{
set_first_byte_at (i, byte);
set_node_at (i, n);
set_first_byte_at (index, first_byte);
set_node_at (index, node);
}
bool node::operator== (node other) const
bool node_t::operator== (node_t other) const
{
return data_ == other.data_;
}
bool node::operator!= (node other) const
bool node_t::operator!= (node_t other) const
{
return !(*this == other);
}
void node::resize (size_t prefix_length, size_t edgecount)
void node_t::resize (size_t prefix_length, size_t edgecount)
{
size_t sz =
size_t node_size =
3 * sizeof (uint32_t) + prefix_length + edgecount * (1 + sizeof (void *));
unsigned char *new_data =
static_cast<unsigned char *> (realloc (data_, sz));
static_cast<unsigned char *> (realloc (data_, node_size));
zmq_assert (new_data);
data_ = new_data;
set_prefix_length (static_cast<uint32_t> (prefix_length));
set_edgecount (static_cast<uint32_t> (edgecount));
}
node make_node (size_t refs, size_t bytes, size_t edges)
node_t make_node (size_t refcount, size_t prefix_length, size_t edgecount)
{
size_t size = 3 * sizeof (uint32_t) + bytes + edges * (1 + sizeof (void *));
size_t node_size =
3 * sizeof (uint32_t) + prefix_length + edgecount * (1 + sizeof (void *));
unsigned char *data = static_cast<unsigned char *> (malloc (size));
unsigned char *data = static_cast<unsigned char *> (malloc (node_size));
zmq_assert (data);
node n (data);
n.set_refcount (static_cast<uint32_t> (refs));
n.set_prefix_length (static_cast<uint32_t> (bytes));
n.set_edgecount (static_cast<uint32_t> (edges));
return n;
node_t node (data);
node.set_refcount (static_cast<uint32_t> (refcount));
node.set_prefix_length (static_cast<uint32_t> (prefix_length));
node.set_edgecount (static_cast<uint32_t> (edgecount));
return node;
}
// ----------------------------------------------------------------------
......@@ -181,11 +183,11 @@ zmq::radix_tree::radix_tree () : root_ (make_node (0, 0, 0)), size_ (0)
{
}
static void free_nodes (node n)
static void free_nodes (node_t node)
{
for (size_t i = 0; i < n.edgecount (); ++i)
free_nodes (n.node_at (i));
free (n.data_);
for (size_t i = 0; i < node.edgecount (); ++i)
free_nodes (node.node_at (i));
free (node.data_);
}
zmq::radix_tree::~radix_tree ()
......@@ -193,64 +195,74 @@ zmq::radix_tree::~radix_tree ()
free_nodes (root_);
}
match_result::match_result (size_t i,
size_t j,
match_result_t::match_result_t (size_t key_bytes_matched,
size_t prefix_bytes_matched,
size_t edge_index,
size_t gp_edge_index,
node current,
node parent,
node grandparent) :
nkey (i),
nprefix (j),
size_t parent_edge_index,
node_t current,
node_t parent,
node_t grandparent) :
key_bytes_matched (key_bytes_matched),
prefix_bytes_matched (prefix_bytes_matched),
edge_index (edge_index),
gp_edge_index (gp_edge_index),
parent_edge_index (parent_edge_index),
current_node (current),
parent_node (parent),
grandparent_node (grandparent)
{
}
match_result zmq::radix_tree::match (const unsigned char *key,
size_t size,
bool check = false) const
match_result_t zmq::radix_tree::match (const unsigned char *key,
size_t key_size,
bool is_lookup = false) const
{
zmq_assert (key);
size_t i = 0; // Number of characters matched in key.
size_t j = 0; // Number of characters matched in current node.
size_t edge_idx = 0; // Index of outgoing edge from the parent node.
size_t gp_edge_idx = 0; // Index of outgoing edge from grandparent.
node current_node = root_;
node parent_node = current_node;
node grandparent_node = current_node;
// Node we're currently at in the traversal and its predecessors.
node_t current_node = root_;
node_t parent_node = current_node;
node_t grandparent_node = current_node;
// Index of the next byte to match in the key.
size_t key_byte_index = 0;
// Index of the next byte to match in the current node's prefix.
size_t prefix_byte_index = 0;
// Index of the edge from parent to current node.
size_t edge_index = 0;
// Index of the edge from grandparent to parent.
size_t parent_edge_index = 0;
while (current_node.prefix_length () > 0 || current_node.edgecount () > 0) {
for (j = 0; j < current_node.prefix_length () && i < size; ++j, ++i) {
if (current_node.prefix ()[j] != key[i])
for (prefix_byte_index = 0;
prefix_byte_index < current_node.prefix_length ()
&& key_byte_index < key_size;
++prefix_byte_index, ++key_byte_index) {
if (current_node.prefix ()[prefix_byte_index]
!= key[key_byte_index])
break;
}
// Even if a prefix of the key matches and we're doing a
// lookup, this means we've found a matching subscription.
if (check && j == current_node.prefix_length ()
if (is_lookup && prefix_byte_index == current_node.prefix_length ()
&& current_node.refcount () > 0) {
i = size;
key_byte_index = key_size;
break;
}
// There was a mismatch or we've matched the whole key, so
// there's nothing more to do.
if (j != current_node.prefix_length () || i == size)
if (prefix_byte_index != current_node.prefix_length ()
|| key_byte_index == key_size)
break;
// We need to match the rest of the key. Check if there's an
// outgoing edge from this node.
node next_node = current_node;
for (size_t k = 0; k < current_node.edgecount (); ++k) {
if (current_node.first_byte_at (k) == key[i]) {
gp_edge_idx = edge_idx;
edge_idx = k;
next_node = current_node.node_at (k);
node_t next_node = current_node;
for (size_t i = 0; i < current_node.edgecount (); ++i) {
if (current_node.first_byte_at (i) == key[key_byte_index]) {
parent_edge_index = edge_index;
edge_index = i;
next_node = current_node.node_at (i);
break;
}
}
......@@ -262,27 +274,29 @@ match_result zmq::radix_tree::match (const unsigned char *key,
current_node = next_node;
}
return match_result (i, j, edge_idx, gp_edge_idx, current_node, parent_node,
return match_result_t (key_byte_index, prefix_byte_index, edge_index,
parent_edge_index, current_node, parent_node,
grandparent_node);
}
bool zmq::radix_tree::add (const unsigned char *key, size_t size)
bool zmq::radix_tree::add (const unsigned char *key, size_t key_size)
{
match_result result = match (key, size);
size_t i = result.nkey;
size_t j = result.nprefix;
size_t edge_idx = result.edge_index;
node current_node = result.current_node;
node parent_node = result.parent_node;
match_result_t match_result = match (key, key_size);
size_t key_bytes_matched = match_result.key_bytes_matched;
size_t prefix_bytes_matched = match_result.prefix_bytes_matched;
size_t edge_index = match_result.edge_index;
node_t current_node = match_result.current_node;
node_t parent_node = match_result.parent_node;
if (i != size) {
if (key_bytes_matched != key_size) {
// Not all characters match, we might have to split the node.
if (i == 0 || j == current_node.prefix_length ()) {
if (key_bytes_matched == 0
|| prefix_bytes_matched == current_node.prefix_length ()) {
// The mismatch is at one of the outgoing edges, so we
// create an edge from the current node to a new leaf node
// that has the rest of the key as the prefix.
node key_node = make_node (1, size - i, 0);
key_node.set_prefix (key + i);
node_t key_node = make_node (1, key_size - key_bytes_matched, 0);
key_node.set_prefix (key + key_bytes_matched);
// Reallocate for one more edge.
current_node.resize (current_node.prefix_length (),
......@@ -290,24 +304,25 @@ bool zmq::radix_tree::add (const unsigned char *key, size_t size)
// Make room for the new edge. We need to shift the chunk
// of node pointers one byte to the right. Since resize()
// increments the edgecount by 1, node_ptrs() tells us the
// increments the edgecount by 1, node_pointers() tells us the
// destination address. The chunk of node pointers starts
// at one byte to the left of this destination.
//
// Since the regions can overlap, we use memmove.
memmove (current_node.node_ptrs (), current_node.node_ptrs () - 1,
memmove (current_node.node_pointers (),
current_node.node_pointers () - 1,
(current_node.edgecount () - 1) * sizeof (void *));
// Add an edge to the new node.
current_node.set_edge_at (current_node.edgecount () - 1, key[i],
key_node);
current_node.set_edge_at (current_node.edgecount () - 1,
key[key_bytes_matched], key_node);
// We need to update all pointers to the current node
// after the call to resize().
if (current_node.prefix_length () == 0)
root_.data_ = current_node.data_;
else
parent_node.set_node_at (edge_idx, current_node);
parent_node.set_node_at (edge_index, current_node);
++size_;
return true;
}
......@@ -318,24 +333,25 @@ bool zmq::radix_tree::add (const unsigned char *key, size_t size)
// One node will have the rest of the characters from the key,
// and the other node will have the rest of the characters
// from the current node's prefix.
node key_node = make_node (1, size - i, 0);
node split_node = make_node (current_node.refcount (),
current_node.prefix_length () - j,
node_t key_node = make_node (1, key_size - key_bytes_matched, 0);
node_t split_node =
make_node (current_node.refcount (),
current_node.prefix_length () - prefix_bytes_matched,
current_node.edgecount ());
// Copy the prefix chunks to the new nodes.
key_node.set_prefix (key + i);
split_node.set_prefix (current_node.prefix () + j);
key_node.set_prefix (key + key_bytes_matched);
split_node.set_prefix (current_node.prefix () + prefix_bytes_matched);
// Copy the current node's edges to the new node.
split_node.set_first_bytes (current_node.first_bytes ());
split_node.set_node_ptrs (current_node.node_ptrs ());
split_node.set_node_pointers (current_node.node_pointers ());
// Resize the current node to accommodate a prefix comprising
// the matched characters and 2 outgoing edges to the above
// nodes. Set the refcount to 0 since this node doesn't hold a
// key.
current_node.resize (j, 2);
current_node.resize (prefix_bytes_matched, 2);
current_node.set_refcount (0);
// Add links to the new nodes. We don't need to copy the
......@@ -344,61 +360,63 @@ bool zmq::radix_tree::add (const unsigned char *key, size_t size)
current_node.set_edge_at (1, split_node.prefix ()[0], split_node);
++size_;
parent_node.set_node_at (edge_idx, current_node);
parent_node.set_node_at (edge_index, current_node);
return true;
}
// All characters in the key match, but we still might need to split.
if (j != current_node.prefix_length ()) {
if (prefix_bytes_matched != current_node.prefix_length ()) {
// All characters in the key match, but not all characters
// from the current node's prefix match.
// Create a node that contains the rest of the characters from
// the current node's prefix and the outgoing edges from the
// current node.
node split_node = make_node (current_node.refcount (),
current_node.prefix_length () - j,
node_t split_node =
make_node (current_node.refcount (),
current_node.prefix_length () - prefix_bytes_matched,
current_node.edgecount ());
split_node.set_prefix (current_node.prefix () + j);
split_node.set_prefix (current_node.prefix () + prefix_bytes_matched);
split_node.set_first_bytes (current_node.first_bytes ());
split_node.set_node_ptrs (current_node.node_ptrs ());
split_node.set_node_pointers (current_node.node_pointers ());
// Resize the current node to hold only the matched characters
// from its prefix and one edge to the new node.
current_node.resize (j, 1);
current_node.resize (prefix_bytes_matched, 1);
// Add an edge to the split node and set the refcount to 1
// since this key wasn't inserted earlier. We don't need to
// set the prefix because the first j bytes in the prefix are
// preserved by resize().
// set the prefix because the first `prefix_bytes_matched` bytes
// in the prefix are preserved by resize().
current_node.set_edge_at (0, split_node.prefix ()[0], split_node);
current_node.set_refcount (1);
++size_;
parent_node.set_node_at (edge_idx, current_node);
parent_node.set_node_at (edge_index, current_node);
return true;
}
zmq_assert (i == size);
zmq_assert (j == current_node.prefix_length ());
zmq_assert (key_bytes_matched == key_size);
zmq_assert (prefix_bytes_matched == current_node.prefix_length ());
++size_;
current_node.set_refcount (current_node.refcount () + 1);
return current_node.refcount () == 1;
}
bool zmq::radix_tree::rm (const unsigned char *key, size_t size)
bool zmq::radix_tree::rm (const unsigned char *key, size_t key_size)
{
match_result result = match (key, size);
size_t i = result.nkey;
size_t j = result.nprefix;
size_t edge_idx = result.edge_index;
size_t gp_edge_idx = result.gp_edge_index;
node current_node = result.current_node;
node parent_node = result.parent_node;
node grandparent_node = result.grandparent_node;
match_result_t match_result = match (key, key_size);
size_t key_bytes_matched = match_result.key_bytes_matched;
size_t prefix_bytes_matched = match_result.prefix_bytes_matched;
size_t edge_index = match_result.edge_index;
size_t parent_edge_index = match_result.parent_edge_index;
node_t current_node = match_result.current_node;
node_t parent_node = match_result.parent_node;
node_t grandparent_node = match_result.grandparent_node;
if (i != size || j != current_node.prefix_length ()
if (key_bytes_matched != key_size
|| prefix_bytes_matched != current_node.prefix_length ()
|| current_node.refcount () == 0)
return false;
......@@ -419,7 +437,7 @@ bool zmq::radix_tree::rm (const unsigned char *key, size_t size)
if (outgoing_edges == 1) {
// Merge this node with the single child node.
node child = current_node.node_at (0);
node_t child = current_node.node_at (0);
// Make room for the child node's prefix and edges. We need to
// keep the old prefix length since resize() will overwrite
......@@ -434,11 +452,11 @@ bool zmq::radix_tree::rm (const unsigned char *key, size_t size)
// Copy the rest of child node's data to the current node.
current_node.set_first_bytes (child.first_bytes ());
current_node.set_node_ptrs (child.node_ptrs ());
current_node.set_node_pointers (child.node_pointers ());
current_node.set_refcount (child.refcount ());
free (child.data_);
parent_node.set_node_at (edge_idx, current_node);
parent_node.set_node_at (edge_index, current_node);
return true;
}
......@@ -447,8 +465,8 @@ bool zmq::radix_tree::rm (const unsigned char *key, size_t size)
// Removing this node leaves the parent with one child.
// If the parent doesn't hold a key or if it isn't the root,
// we can merge it with its single child node.
zmq_assert (edge_idx < 2);
node other_child = parent_node.node_at (!edge_idx);
zmq_assert (edge_index < 2);
node_t other_child = parent_node.node_at (!edge_index);
// Make room for the child node's prefix and edges. We need to
// keep the old prefix length since resize() will overwrite
......@@ -463,12 +481,12 @@ bool zmq::radix_tree::rm (const unsigned char *key, size_t size)
// Copy the rest of child node's data to the current node.
parent_node.set_first_bytes (other_child.first_bytes ());
parent_node.set_node_ptrs (other_child.node_ptrs ());
parent_node.set_node_pointers (other_child.node_pointers ());
parent_node.set_refcount (other_child.refcount ());
free (current_node.data_);
free (other_child.data_);
grandparent_node.set_node_at (gp_edge_idx, parent_node);
grandparent_node.set_node_at (parent_edge_index, parent_node);
return true;
}
......@@ -477,17 +495,18 @@ bool zmq::radix_tree::rm (const unsigned char *key, size_t size)
// parent.
zmq_assert (outgoing_edges == 0);
// Move the first byte and node pointer to the back of the byte
// and pointer chunks respectively.
size_t last_idx = parent_node.edgecount () - 1;
unsigned char last_byte = parent_node.first_byte_at (last_idx);
node last_ptr = parent_node.node_at (last_idx);
parent_node.set_edge_at (edge_idx, last_byte, last_ptr);
// Replace the edge to the current node with the last edge. An
// edge consists of a byte and a pointer to the next node. First
// replace the byte.
size_t last_index = parent_node.edgecount () - 1;
unsigned char last_byte = parent_node.first_byte_at (last_index);
node_t last_node = parent_node.node_at (last_index);
parent_node.set_edge_at (edge_index, last_byte, last_node);
// Move the chunk of pointers one byte to the left, effectively
// deleting the last byte in the region of first bytes by
// overwriting it.
memmove (parent_node.node_ptrs () - 1, parent_node.node_ptrs (),
memmove (parent_node.node_pointers () - 1, parent_node.node_pointers (),
parent_node.edgecount () * sizeof (void *));
// Shrink the parent node to the new size, which "deletes" the
......@@ -501,38 +520,39 @@ bool zmq::radix_tree::rm (const unsigned char *key, size_t size)
if (parent_node.prefix_length () == 0)
root_.data_ = parent_node.data_;
else
grandparent_node.set_node_at (gp_edge_idx, parent_node);
grandparent_node.set_node_at (parent_edge_index, parent_node);
return true;
}
bool zmq::radix_tree::check (const unsigned char *key, size_t size)
bool zmq::radix_tree::check (const unsigned char *key, size_t key_size)
{
if (root_.refcount () > 0)
return true;
match_result result = match (key, size, true);
return result.nkey == size
&& result.nprefix == result.current_node.prefix_length ()
&& result.current_node.refcount () > 0;
match_result_t match_result = match (key, key_size, true);
return match_result.key_bytes_matched == key_size
&& match_result.prefix_bytes_matched
== match_result.current_node.prefix_length ()
&& match_result.current_node.refcount () > 0;
}
static void
visit_keys (node n,
visit_keys (node_t node,
std::vector<unsigned char> &buffer,
void (*func) (unsigned char *data, size_t size, void *arg),
void *arg)
{
for (size_t i = 0; i < n.prefix_length (); ++i)
buffer.push_back (n.prefix ()[i]);
for (size_t i = 0; i < node.prefix_length (); ++i)
buffer.push_back (node.prefix ()[i]);
if (n.refcount () > 0) {
if (node.refcount () > 0) {
zmq_assert (!buffer.empty ());
func (&buffer[0], buffer.size (), arg);
}
for (size_t i = 0; i < n.edgecount (); ++i)
visit_keys (n.node_at (i), buffer, func, arg);
for (size_t i = 0; i < n.prefix_length (); ++i)
for (size_t i = 0; i < node.edgecount (); ++i)
visit_keys (node.node_at (i), buffer, func, arg);
for (size_t i = 0; i < node.prefix_length (); ++i)
buffer.pop_back ();
}
......
......@@ -60,54 +60,55 @@
// The link to each child is looked up using its index, e.g. the child
// with index 0 will have its first byte and node pointer at the start
// of the chunk of first bytes and node pointers respectively.
struct node
struct node_t
{
unsigned char *data_;
explicit node (unsigned char *data);
explicit node_t (unsigned char *data);
bool operator== (node other) const;
bool operator!= (node other) const;
bool operator== (node_t other) const;
bool operator!= (node_t other) const;
inline uint32_t refcount ();
inline uint32_t prefix_length ();
inline uint32_t edgecount ();
inline unsigned char *prefix ();
inline unsigned char *first_bytes ();
inline unsigned char first_byte_at (size_t i);
inline unsigned char *node_ptrs ();
inline node node_at (size_t i);
inline unsigned char first_byte_at (size_t index);
inline unsigned char *node_pointers ();
inline node_t node_at (size_t index);
inline void set_refcount (uint32_t value);
inline void set_prefix_length (uint32_t value);
inline void set_edgecount (uint32_t value);
inline void set_prefix (const unsigned char *prefix);
inline void set_first_bytes (const unsigned char *bytes);
inline void set_first_byte_at (size_t i, unsigned char byte);
inline void set_node_ptrs (const unsigned char *ptrs);
inline void set_node_at (size_t i, node n);
inline void set_edge_at (size_t i, unsigned char byte, node n);
inline void set_first_byte_at (size_t index, unsigned char byte);
inline void set_node_pointers (const unsigned char *pointers);
inline void set_node_at (size_t index, node_t node);
inline void
set_edge_at (size_t index, unsigned char first_byte, node_t node);
void resize (size_t prefix_length, size_t edgecount);
};
node make_node (size_t refcount, size_t prefix_length, size_t nedges);
node_t make_node (size_t refcount, size_t prefix_length, size_t edgecount);
struct match_result
struct match_result_t
{
size_t nkey;
size_t nprefix;
size_t key_bytes_matched;
size_t prefix_bytes_matched;
size_t edge_index;
size_t gp_edge_index;
node current_node;
node parent_node;
node grandparent_node;
size_t parent_edge_index;
node_t current_node;
node_t parent_node;
node_t grandparent_node;
match_result (size_t i,
size_t j,
match_result_t (size_t key_bytes_matched,
size_t prefix_bytes_matched,
size_t edge_index,
size_t gp_edge_index,
node current,
node parent,
node grandparent);
size_t parent_edge_index,
node_t current,
node_t parent,
node_t grandparent);
};
namespace zmq
......@@ -120,26 +121,26 @@ class radix_tree
// Add key to the tree. Returns true if this was a new key rather
// than a duplicate.
bool add (const unsigned char *prefix_, size_t size_);
bool add (const unsigned char *key_, size_t key_size_);
// Remove key from the tree. Returns true if he item is acually
// Remove key from the tree. Returns true if the item is actually
// removed from the tree.
bool rm (const unsigned char *prefix_, size_t size_);
bool rm (const unsigned char *key_, size_t key_size_);
// Check whether particular key is in the tree.
bool check (const unsigned char *prefix, size_t size_);
bool check (const unsigned char *key_, size_t key_size_);
// Apply the function supplied to each key in the tree.
void apply (void (*func) (unsigned char *data_, size_t size_, void *arg_),
void *arg);
void apply (void (*func_) (unsigned char *data, size_t size, void *arg),
void *arg_);
size_t size () const;
private:
inline match_result
match (const unsigned char *key, size_t size, bool check) const;
inline match_result_t
match (const unsigned char *key, size_t key_size, bool is_lookup) const;
node root_;
node_t root_;
size_t size_;
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment