Commit c85fcff7 authored by Vladimír Čunát's avatar Vladimír Čunát

lib/generic/trie: add tries from knot-dns

(Don't use them anywhere yet.)
parent defe4a70
......@@ -11,6 +11,7 @@ as long as it comes with a test case in `tests/test_generics.c`.
* set_ - set abstraction implemented on top of ``map``.
* pack_ - length-prefixed list of objects (i.e. array-list).
* lru_ - LRU-like hash table
* trie_ - a trie-based key-value map, taken from knot-dns
......@@ -42,4 +43,11 @@ lru
.. doxygenfile:: lru.h
:project: libkres
.. doxygenfile:: trie.h
:project: libkres
.. _`Crit-bit tree`:
This diff is collapsed.
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <>.
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <libknot/mm_ctx.h>
* \brief Native API of QP-tries:
* - keys are char strings, not necessarily zero-terminated,
* the structure copies the contents of the passed keys
* - values are void* pointers, typically you get an ephemeral pointer to it
* - key lengths are limited by 2^32-1 ATM
* XXX EDITORS: trie.{h,c} are synced from
* only with #includes adjusted.
/*! \brief Element value. */
typedef void* trie_val_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. */
trie_t* trie_create(knot_mm_t *mm);
/*! \brief Free a trie instance. */
void trie_free(trie_t *tbl);
/*! \brief Clear a trie instance (make it empty). */
void trie_clear(trie_t *tbl);
/*! \brief Return the number of keys in the trie. */
size_t trie_weight(const trie_t *tbl);
/*! \brief Search the trie, returning NULL on failure. */
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* trie_get_ins(trie_t *tbl, const char *key, uint32_t len);
* \brief Search for less-or-equal element.
* \param tbl Trie.
* \param key Searched key.
* \param len Key length.
* \param val Must be valid; it will be set to NULL if not found or errored.
* \return KNOT_EOK for exact match, 1 for previous, KNOT_ENOENT for not-found,
* or KNOT_E*.
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 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 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). */
trie_it_t* trie_it_begin(trie_t *tbl);
* \brief Advance the iterator to the next element.
* Iteration is in ascending lexicographical order.
* In particular, the empty string would be considered as the very first.
void trie_it_next(trie_it_t *it);
/*! \brief Test if the iterator has gone past the last element. */
bool trie_it_finished(trie_it_t *it);
/*! \brief Free any resources of the iterator. It's OK to call it on NULL. */
void trie_it_free(trie_it_t *it);
* \brief Return pointer to the key of the current element.
* \note The len is uint32_t internally but size_t is better for our usage
* as it is without an additional type conversion.
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* trie_it_val(trie_it_t *it);
......@@ -13,6 +13,7 @@ libkres_SOURCES := \
lib/dnssec/ta.c \
lib/generic/lru.c \
lib/generic/map.c \
lib/generic/trie.c \
lib/layer/cache.c \
lib/layer/iterate.c \
lib/layer/validate.c \
......@@ -39,6 +40,7 @@ libkres_HEADERS := \
lib/generic/map.h \
lib/generic/pack.h \
lib/generic/set.h \
lib/generic/trie.h \
lib/layer.h \
lib/layer/iterate.h \
lib/module.h \
......@@ -53,6 +53,13 @@ static isaac_ctx ISAAC;
static bool isaac_seeded = false;
#define SEED_SIZE 256
void *mm_malloc(void *ctx, size_t n)
return malloc(n);
* Macros.
......@@ -121,6 +121,17 @@ static inline void *mm_realloc(knot_mm_t *mm, void *what, size_t size, size_t pr
return realloc(what, size);
/** Trivial malloc() wrapper. */
void *mm_malloc(void *ctx, size_t n);
/** Initialize mm with standard malloc+free. */
static inline void mm_ctx_init(knot_mm_t *mm)
mm->ctx = NULL;
mm->alloc = mm_malloc;
mm->free = free;
/* @endcond */
/** Return time difference in miliseconds.
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment