Commit dbfe1240 authored by Daniel Salzman's avatar Daniel Salzman

qp-trie: remove the "qp-" prefix from the API

parent b110033b
......@@ -540,11 +540,11 @@ tests/confio.c
tests/contrib/test_base32hex.c
tests/contrib/test_base64.c
tests/contrib/test_endian.c
tests/contrib/test_hat-trie.c
tests/contrib/test_heap.c
tests/contrib/test_hhash.c
tests/contrib/test_net.c
tests/contrib/test_net_shortwrite.c
tests/contrib/test_qp-trie.c
tests/contrib/test_sockaddr.c
tests/contrib/test_string.c
tests/contrib/test_strtonum.c
......
......@@ -16,86 +16,83 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include "contrib/qp-trie/qp.h"
#include "contrib/macros.h"
typedef struct qp_trie hattrie_t;
typedef struct qp_trie_it hattrie_iter_t;
typedef trie_t hattrie_t;
typedef trie_val_t value_t;
typedef trie_it_t hattrie_iter_t;
inline static hattrie_t* hattrie_create(struct knot_mm *mm)
{
return qp_trie_create(mm);
return trie_create(mm);
}
inline static void hattrie_free(hattrie_t *trie)
{
qp_trie_free(trie);
trie_free(trie);
}
inline static void hattrie_clear(hattrie_t *trie)
{
qp_trie_clear(trie);
trie_clear(trie);
}
inline static size_t hattrie_weight(const hattrie_t *trie)
{
return qp_trie_weight(trie);
return trie_weight(trie);
}
inline static int hattrie_apply_rev(hattrie_t *trie, int (*f)(value_t*,void*), void* d)
{
return qp_trie_apply(trie, f, d);
return trie_apply(trie, f, d);
}
inline static value_t* hattrie_tryget(hattrie_t *trie, const char *key, size_t len)
{
return qp_trie_get_try(trie, key, len);
return trie_get_try(trie, key, len);
}
inline static value_t* hattrie_get(hattrie_t *trie, const char *key, size_t len)
{
return qp_trie_get_ins(trie, key, len);
return trie_get_ins(trie, key, len);
}
inline static int hattrie_find_leq(hattrie_t *trie, const char *key, size_t len, value_t **dst)
{
return qp_trie_get_leq(trie, key, len, dst);
return trie_get_leq(trie, key, len, dst);
}
inline static int hattrie_del(hattrie_t *trie, const char* key, size_t len, value_t *val)
{
return qp_trie_del(trie, key, len, val);
return trie_del(trie, key, len, val);
}
inline static hattrie_iter_t* hattrie_iter_begin(hattrie_t *trie)
{
return qp_trie_it_begin(trie);
return trie_it_begin(trie);
}
inline static void hattrie_iter_next(hattrie_iter_t *it)
{
qp_trie_it_next(it);
trie_it_next(it);
}
inline static bool hattrie_iter_finished(hattrie_iter_t *it)
{
return qp_trie_it_finished(it);
return trie_it_finished(it);
}
inline static void hattrie_iter_free(hattrie_iter_t *it)
{
qp_trie_it_free(it);
trie_it_free(it);
}
inline static const char* hattrie_iter_key(hattrie_iter_t *it, size_t *len)
{
return qp_trie_it_key(it, len);
return trie_it_key(it, len);
}
inline static value_t* hattrie_iter_val(hattrie_iter_t *it)
{
return qp_trie_it_val(it);
return trie_it_val(it);
}
......@@ -22,8 +22,8 @@
#include <string.h>
#include "contrib/qp-trie/qp.h"
#include "contrib/mempattern.h"
#include "contrib/macros.h"
#include "contrib/mempattern.h"
#include "libknot/errcode.h"
#if defined(__i386) || defined(__x86_64) || defined(_M_IX86) \
......@@ -51,14 +51,13 @@ typedef unsigned char byte;
typedef unsigned int uint;
typedef uint bitmap_t; /*! Bit-maps, using the range of 1<<0 to 1<<16 (inclusive). */
/*! \brief A trie node is either leaf_t or branch_t. */
typedef union node node_t;
/*! \brief What we use as trie key internally. */
typedef struct tkey tkey_t;
typedef struct {
uint32_t len; // 32 bits are enough for key lengths; probably even 16 bits would be.
char chars[];
} tkey_t;
/*! \brief Leaf of trie. */
typedef struct leaf {
typedef struct {
#if !FLAGS_HACK
byte flags;
#endif
......@@ -66,10 +65,8 @@ typedef struct leaf {
trie_val_t val;
} leaf_t;
struct tkey {
uint32_t len; // 32 bits are enough for key lengths; probably even 16 bits would be.
char chars[];
};
/*! \brief A trie node is either leaf_t or branch_t. */
typedef union node node_t;
/*!
* \brief Branch node of trie.
......@@ -91,7 +88,7 @@ struct tkey {
* \note The branch nodes are never allocated individually, but they are
* always part of either the root node or the twigs array of the parent.
*/
typedef struct branch {
typedef struct {
#if FLAGS_HACK
uint32_t flags : 2,
bitmap : 17; /*!< The first bitmap bit is for end-of-string child. */
......@@ -104,15 +101,15 @@ typedef struct branch {
} branch_t;
union node {
struct leaf leaf;
struct branch branch;
leaf_t leaf;
branch_t branch;
};
typedef struct qp_trie {
struct trie {
node_t root; // undefined when weight == 0, see empty_root()
size_t weight;
knot_mm_t mm;
} trie_t;
};
/*! \brief Make the root node empty (debug-only). */
static inline void empty_root(node_t *root) {
......@@ -232,7 +229,7 @@ static int key_cmp(const char *k1, uint32_t k1_len, const char *k2, uint32_t k2_
}
}
struct qp_trie* qp_trie_create(knot_mm_t *mm)
trie_t* trie_create(knot_mm_t *mm)
{
assert_portability();
trie_t *trie = mm_alloc(mm, sizeof(trie_t));
......@@ -261,7 +258,7 @@ static void clear_trie(node_t *trie, knot_mm_t *mm)
}
}
void qp_trie_free(struct qp_trie *tbl)
void trie_free(trie_t *tbl)
{
if (tbl == NULL)
return;
......@@ -270,7 +267,7 @@ void qp_trie_free(struct qp_trie *tbl)
mm_free(&tbl->mm, tbl);
}
void qp_trie_clear(struct qp_trie *tbl)
void trie_clear(trie_t *tbl)
{
assert(tbl);
if (!tbl->weight)
......@@ -280,13 +277,13 @@ void qp_trie_clear(struct qp_trie *tbl)
tbl->weight = 0;
}
size_t qp_trie_weight(const struct qp_trie *tbl)
size_t trie_weight(const trie_t *tbl)
{
assert(tbl);
return tbl->weight;
}
trie_val_t* qp_trie_get_try(trie_t *tbl, const char *key, uint32_t len)
trie_val_t* trie_get_try(trie_t *tbl, const char *key, uint32_t len)
{
assert(tbl);
if (!tbl->weight)
......@@ -304,7 +301,7 @@ trie_val_t* qp_trie_get_try(trie_t *tbl, const char *key, uint32_t len)
return &t->leaf.val;
}
int qp_trie_del(struct qp_trie *tbl, const char *key, uint32_t len, trie_val_t *val)
int trie_del(trie_t *tbl, const char *key, uint32_t len, trie_val_t *val)
{
assert(tbl);
if (!tbl->weight)
......@@ -356,11 +353,11 @@ int qp_trie_del(struct qp_trie *tbl, const char *key, uint32_t len, trie_val_t *
/*!
* \brief Stack of nodes, storing a path down a trie.
*
* The structure also serves directly as the public qp_trie_it_t type,
* The structure also serves directly as the public trie_it_t type,
* in which case it always points to the current leaf, unless we've finished
* (i.e. it->len == 0).
*/
typedef struct qp_trie_it {
typedef struct trie_it {
node_t* *stack; /*!< The stack; malloc is used directly instead of mm. */
uint32_t len; /*!< Current length of the stack. */
uint32_t alen; /*!< Allocated/available length of the stack. */
......@@ -369,7 +366,7 @@ typedef struct qp_trie_it {
} nstack_t;
/*! \brief Create a node stack containing just the root (or empty). */
static void ns_init(nstack_t *ns, struct qp_trie *tbl)
static void ns_init(nstack_t *ns, trie_t *tbl)
{
assert(tbl);
ns->stack = ns->stack_init;
......@@ -608,7 +605,7 @@ static int ns_next_leaf(nstack_t *ns)
} while (true);
}
int qp_trie_get_leq(struct qp_trie *tbl, const char *key, uint32_t len, trie_val_t **val)
int trie_get_leq(trie_t *tbl, const char *key, uint32_t len, trie_val_t **val)
{
assert(tbl && val);
*val = NULL; // so on failure we can just return;
......@@ -683,7 +680,7 @@ static int mk_leaf(node_t *leaf, const char *key, uint32_t len, knot_mm_t *mm)
return KNOT_EOK;
}
trie_val_t* qp_trie_get_ins(struct qp_trie *tbl, const char *key, uint32_t len)
trie_val_t* trie_get_ins(trie_t *tbl, const char *key, uint32_t len)
{
assert(tbl);
// First leaf in an empty tbl?
......@@ -764,7 +761,7 @@ static int apply_trie(node_t *t, int (*f)(trie_val_t *, void *), void *d)
return KNOT_EOK;
}
int qp_trie_apply(struct qp_trie *tbl, int (*f)(trie_val_t *, void *), void *d)
int trie_apply(trie_t *tbl, int (*f)(trie_val_t *, void *), void *d)
{
assert(tbl && f);
if (!tbl->weight)
......@@ -773,10 +770,10 @@ int qp_trie_apply(struct qp_trie *tbl, int (*f)(trie_val_t *, void *), void *d)
}
/* These are all thin wrappers around static Tns* functions. */
qp_trie_it_t* qp_trie_it_begin(struct qp_trie *tbl)
trie_it_t* trie_it_begin(trie_t *tbl)
{
assert(tbl);
qp_trie_it_t *it = malloc(sizeof(nstack_t));
trie_it_t *it = malloc(sizeof(nstack_t));
if (!it)
return NULL;
ns_init(it, tbl);
......@@ -790,20 +787,20 @@ qp_trie_it_t* qp_trie_it_begin(struct qp_trie *tbl)
return it;
}
void qp_trie_it_next(qp_trie_it_t *it)
void trie_it_next(trie_it_t *it)
{
assert(it && it->len);
if (ns_next_leaf(it) != KNOT_EOK)
it->len = 0;
}
bool qp_trie_it_finished(qp_trie_it_t *it)
bool trie_it_finished(trie_it_t *it)
{
assert(it);
return it->len == 0;
}
void qp_trie_it_free(qp_trie_it_t *it)
void trie_it_free(trie_it_t *it)
{
if (!it)
return;
......@@ -811,7 +808,7 @@ void qp_trie_it_free(qp_trie_it_t *it)
free(it);
}
const char* qp_trie_it_key(qp_trie_it_t *it, size_t *len)
const char* trie_it_key(trie_it_t *it, size_t *len)
{
assert(it && it->len);
node_t *t = it->stack[it->len - 1];
......@@ -822,7 +819,7 @@ const char* qp_trie_it_key(qp_trie_it_t *it, size_t *len)
return key->chars;
}
trie_val_t* qp_trie_it_val(qp_trie_it_t *it)
trie_val_t* trie_it_val(trie_it_t *it)
{
assert(it && it->len);
node_t *t = it->stack[it->len - 1];
......
......@@ -33,26 +33,29 @@
/*! \brief Element value. */
typedef void* trie_val_t;
/*! Opaque type for holding a QP-trie iterator. */
typedef struct qp_trie_it qp_trie_it_t;
/*! \brief Opaque structure holding a QP-trie. */
typedef struct trie trie_t;
/*! \brief Opaque type for holding a QP-trie iterator. */
typedef struct trie_it trie_it_t;
/*! \brief Create a trie instance. */
struct qp_trie* qp_trie_create(knot_mm_t *mm);
trie_t* trie_create(knot_mm_t *mm);
/*! \brief Free a trie instance. */
void qp_trie_free(struct qp_trie *tbl);
void trie_free(trie_t *tbl);
/*! \brief Clear a trie instance (make it empty). */
void qp_trie_clear(struct qp_trie *tbl);
void trie_clear(trie_t *tbl);
/*! \brief Return the number of keys in the trie. */
size_t qp_trie_weight(const struct qp_trie *tbl);
size_t trie_weight(const trie_t *tbl);
/*! \brief Search the trie, returning NULL on failure. */
trie_val_t* qp_trie_get_try(struct qp_trie *tbl, const char *key, uint32_t len);
trie_val_t* trie_get_try(trie_t *tbl, const char *key, uint32_t len);
/*! \brief Search the trie, inserting NULL trie_val_t on failure. */
trie_val_t* qp_trie_get_ins(struct qp_trie *tbl, const char *key, uint32_t len);
trie_val_t* trie_get_ins(trie_t *tbl, const char *key, uint32_t len);
/*!
* \brief Search for less-or-equal element.
......@@ -61,24 +64,24 @@ trie_val_t* qp_trie_get_ins(struct qp_trie *tbl, const char *key, uint32_t len);
* \return KNOT_EOK for exact match, 1 for previous, KNOT_ENOENT for not-found,
* or KNOT_E*.
*/
int qp_trie_get_leq(struct qp_trie *tbl, const char *key, uint32_t len, trie_val_t **val);
int trie_get_leq(trie_t *tbl, const char *key, uint32_t len, trie_val_t **val);
/*!
* \brief Apply a function to every trie_val_t, in order.
*
* \return KNOT_EOK if success or KNOT_E* if error.
*/
int qp_trie_apply(struct qp_trie *tbl, int (*f)(trie_val_t *, void *), void *d);
int trie_apply(trie_t *tbl, int (*f)(trie_val_t *, void *), void *d);
/*!
* \brief Remove an item, returning KNOT_EOK if succeeded or KNOT_ENOENT if not found.
*
* If val!=NULL and deletion succeeded, the deleted value is set.
*/
int qp_trie_del(struct qp_trie *tbl, const char *key, uint32_t len, trie_val_t *val);
int trie_del(trie_t *tbl, const char *key, uint32_t len, trie_val_t *val);
/*! \brief Create a new iterator pointing to the first element (if any). */
qp_trie_it_t* qp_trie_it_begin(struct qp_trie *tbl);
trie_it_t* trie_it_begin(trie_t *tbl);
/*!
* \brief Advance the iterator to the next element.
......@@ -86,16 +89,16 @@ qp_trie_it_t* qp_trie_it_begin(struct qp_trie *tbl);
* Iteration is in ascending lexicographical order.
* In particular, the empty string would be considered as the very first.
*/
void qp_trie_it_next(qp_trie_it_t *it);
void trie_it_next(trie_it_t *it);
/*! \brief Test if the iterator has gone past the last element. */
bool qp_trie_it_finished(qp_trie_it_t *it);
bool trie_it_finished(trie_it_t *it);
/*! \brief Free any resources of the iterator. It's OK to call it on NULL. */
void qp_trie_it_free(qp_trie_it_t *it);
void trie_it_free(trie_it_t *it);
/*! \brief Return pointer to the key of the current element. */
const char* qp_trie_it_key(qp_trie_it_t *it, size_t *len);
const char* trie_it_key(trie_it_t *it, size_t *len);
/*! \brief Return pointer to the value of the current element (writable). */
trie_val_t* qp_trie_it_val(qp_trie_it_t *it);
trie_val_t* trie_it_val(trie_it_t *it);
......@@ -20,6 +20,7 @@
#include "libknot/errcode.h"
#include "libknot/db/db_trie.h"
#include "contrib/hat-trie/hat-trie.h"
#include "contrib/macros.h"
#include "contrib/mempattern.h"
static int init(knot_db_t **db, knot_mm_t *mm, void *arg)
......
......@@ -5,11 +5,11 @@
/contrib/test_base32hex
/contrib/test_base64
/contrib/test_endian
/contrib/test_hat-trie
/contrib/test_heap
/contrib/test_hhash
/contrib/test_net
/contrib/test_net_shortwrite
/contrib/test_qp-trie
/contrib/test_sockaddr
/contrib/test_string
/contrib/test_strtonum
......
......@@ -14,11 +14,11 @@ check_PROGRAMS = \
contrib/test_base32hex \
contrib/test_base64 \
contrib/test_endian \
contrib/test_hat-trie \
contrib/test_heap \
contrib/test_hhash \
contrib/test_net \
contrib/test_net_shortwrite \
contrib/test_qp-trie \
contrib/test_sockaddr \
contrib/test_string \
contrib/test_strtonum \
......
......@@ -14,11 +14,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <tap/basic.h>
#include "contrib/hat-trie/hat-trie.h"
#include "contrib/qp-trie/qp.h"
#include "contrib/macros.h"
#include "contrib/string.h"
#include "libknot/errcode.h"
......@@ -45,12 +46,12 @@ static char *str_key_rand(size_t len)
}
/* \brief Check lesser or equal result. */
static bool str_key_find_leq(hattrie_t *trie, char **keys, size_t i, size_t size)
static bool str_key_get_leq(trie_t *trie, char **keys, size_t i, size_t size)
{
static char key_buf[KEY_MAXLEN];
int ret = 0;
value_t *val = NULL;
trie_val_t *val = NULL;
const char *key = keys[i];
size_t key_len = strlen(key) + 1;
memcpy(key_buf, key, key_len);
......@@ -68,13 +69,13 @@ static bool str_key_find_leq(hattrie_t *trie, char **keys, size_t i, size_t size
/* Before current key. */
key_buf[key_len - 2] -= 1;
if (i < first_key_count) {
ret = hattrie_find_leq(trie, key_buf, key_len, &val);
ret = trie_get_leq(trie, key_buf, key_len, &val);
if (ret != KNOT_ENOENT) {
diag("%s: leq for key BEFORE %zu/'%s' ret = %d", __func__, i, keys[i], ret);
return false; /* No key before first. */
}
} else {
ret = hattrie_find_leq(trie, key_buf, key_len, &val);
ret = trie_get_leq(trie, key_buf, key_len, &val);
if (ret < KNOT_EOK || strcmp(*val, key_buf) > 0) {
diag("%s: '%s' is not before the key %zu/'%s'", __func__, (char*)*val, i, keys[i]);
return false; /* Found key must be LEQ than searched. */
......@@ -83,7 +84,7 @@ static bool str_key_find_leq(hattrie_t *trie, char **keys, size_t i, size_t size
/* Current key. */
key_buf[key_len - 2] += 1;
ret = hattrie_find_leq(trie, key_buf, key_len, &val);
ret = trie_get_leq(trie, key_buf, key_len, &val);
if (! (ret == KNOT_EOK && val && strcmp(*val, key_buf) == 0)) {
diag("%s: leq for key %zu/'%s' ret = %d", __func__, i, keys[i], ret);
return false; /* Must find equal match. */
......@@ -91,7 +92,7 @@ static bool str_key_find_leq(hattrie_t *trie, char **keys, size_t i, size_t size
/* After the current key. */
key_buf[key_len - 2] += 1;
ret = hattrie_find_leq(trie, key_buf, key_len, &val);
ret = trie_get_leq(trie, key_buf, key_len, &val);
if (! (ret >= KNOT_EOK && strcmp(*val, key_buf) <= 0)) {
diag("%s: leq for key AFTER %zu/'%s' ret = %d %s", __func__, i, keys[i], ret, (char*)*val);
return false; /* Every key must have its LEQ match. */
......@@ -117,15 +118,15 @@ int main(int argc, char *argv[])
str_key_sort(keys, key_count);
/* Create trie */
value_t *val = NULL;
hattrie_t *trie = hattrie_create(NULL);
ok(trie != NULL, "hattrie: create");
trie_val_t *val = NULL;
trie_t *trie = trie_create(NULL);
ok(trie != NULL, "trie: create");
/* Insert keys */
bool passed = true;
size_t inserted = 0;
for (unsigned i = 0; i < key_count; ++i) {
val = hattrie_get(trie, keys[i], strlen(keys[i]) + 1);
val = trie_get_ins(trie, keys[i], strlen(keys[i]) + 1);
if (!val) {
passed = false;
break;
......@@ -135,29 +136,29 @@ int main(int argc, char *argv[])
++inserted;
}
}
ok(passed, "hattrie: insert");
ok(passed, "trie: insert");
/* Check total insertions against trie weight. */
is_int(hattrie_weight(trie), inserted, "hattrie: trie weight matches insertions");
is_int(trie_weight(trie), inserted, "trie: trie weight matches insertions");
/* Lookup all keys */
passed = true;
for (unsigned i = 0; i < key_count; ++i) {
val = hattrie_tryget(trie, keys[i], strlen(keys[i]) + 1);
val = trie_get_try(trie, keys[i], strlen(keys[i]) + 1);
if (val && (*val == keys[i] || strcmp(*val, keys[i]) == 0)) {
continue;
} else {
diag("hattrie: mismatch on element '%u'", i);
diag("trie: mismatch on element '%u'", i);
passed = false;
break;
}
}
ok(passed, "hattrie: lookup all keys");
ok(passed, "trie: lookup all keys");
/* Lesser or equal lookup. */
passed = true;
for (unsigned i = 0; i < key_count; ++i) {
if (!str_key_find_leq(trie, keys, i, key_count)) {
if (!str_key_get_leq(trie, keys, i, key_count)) {
passed = false;
for (int off = -10; off < 10; ++off) {
int k = (int)i + off;
......@@ -169,15 +170,15 @@ int main(int argc, char *argv[])
break;
}
}
ok(passed, "hattrie: find lesser or equal for all keys");
ok(passed, "trie: find lesser or equal for all keys");
/* Sorted iteration. */
char key_buf[KEY_MAXLEN] = {'\0'};
size_t iterated = 0;
hattrie_iter_t *it = hattrie_iter_begin(trie);
while (!hattrie_iter_finished(it)) {
trie_it_t *it = trie_it_begin(trie);
while (!trie_it_finished(it)) {
size_t cur_key_len = 0;
const char *cur_key = hattrie_iter_key(it, &cur_key_len);
const char *cur_key = trie_it_key(it, &cur_key_len);
if (iterated > 0) { /* Only if previous exists. */
if (strcmp(key_buf, cur_key) > 0) {
diag("'%s' <= '%s' FAIL\n", key_buf, cur_key);
......@@ -186,16 +187,16 @@ int main(int argc, char *argv[])
}
++iterated;
memcpy(key_buf, cur_key, cur_key_len);
hattrie_iter_next(it);
trie_it_next(it);
}
is_int(inserted, iterated, "hattrie: sorted iteration");
hattrie_iter_free(it);
is_int(inserted, iterated, "trie: sorted iteration");
trie_it_free(it);
/* Cleanup */
for (unsigned i = 0; i < key_count; ++i) {
free(keys[i]);
}
free(keys);
hattrie_free(trie);
trie_free(trie);
return 0;
}
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