9 #ifndef __libutilxx__sella__container__CedarTrie_H__
10 #define __libutilxx__sella__container__CedarTrie_H__
12 #include "../../common.h"
13 #include "ContainerException.h"
15 #define SUPPRESS_CEDAR_ASSERT
17 #ifdef USE_PREFIX_TRIE
19 #elif defined USE_REDUCED_TRIE
33 #ifdef USE_ORDERED_TRIE
38 typedef std::shared_ptr<CedarTrie<value_t>> shared;
42 static_assert(
sizeof(value_t) <= 4,
"CedarTrie requires that V must be 4 bytes (int32_t) or less");
45 void insert(
const std::string &key,
const value_t &value)
throw () {
46 trie.update(key.data(), key.size(), value);
49 void insert(
const char *key,
size_t len,
const value_t &value)
throw () {
50 trie.update(key, len, value);
53 void insert(
const char *key,
const value_t &value)
throw () {
54 trie.update(key, ::strlen(key), value);
57 void insert(
const uint8_t *key,
size_t len,
const value_t &value)
throw () {
58 trie.update((
const char*) key, len, value);
61 int remove(
const std::string &key)
throw () {
62 return trie.erase(key.data(), key.size(), 0);
65 int remove(
const char *key)
throw () {
66 return trie.erase(key, ::strlen(key), 0);
69 int remove(
const char *key,
size_t len)
throw () {
70 return trie.erase(key, len, 0);
73 int remove(
const uint8_t *key,
size_t len)
throw () {
74 return trie.erase((
const char*) key, len, 0);
77 bool lookup(
const char *key,
size_t len, value_t &value)
throw () {
78 typename trie_t::result_triple_type result_triple[1] = { 0, 0, 0 };
80 if (trie.commonPrefixPredict(key, result_triple, 1, len, 0) > 0) {
81 if (result_triple[0].length == 0) {
82 value = result_triple[0].value;
91 bool lookup(
const std::string &key, value_t &value)
throw () {
92 return lookup(key.data(), key.size(), value);
95 bool lookup(
const uint8_t *key,
size_t len, value_t &value)
throw () {
96 return lookup((
const char*) key, len, value);
99 bool lookup(
const std::string &prefix, std::vector<std::pair<std::string, value_t>> &values)
throw () {
100 typename trie_t::result_triple_type* result_triple =
new typename trie_t::result_triple_type[64];
103 if ((count = trie.commonPrefixPredict(prefix.data(), result_triple, 64, prefix.size(), 0)) > 0) {
105 delete result_triple;
107 result_triple =
new typename trie_t::result_triple_type[count];
109 if ((count = trie.commonPrefixPredict(prefix.data(), result_triple, count, prefix.size(), 0)) < 1) {
110 delete result_triple;
116 values.reserve(count);
118 for (
size_t i = 0; i < count; i++) {
121 trie.suffix(suffix, result_triple[0].length, result_triple[0].
id);
122 values.push_back(std::make_pair(prefix + suffix, result_triple[0].value));
125 delete result_triple;
133 value_t at(
const std::string &key)
throw (ContainerException) {
134 return at(key.data(), key.size());
137 value_t at(
const char *key)
throw (ContainerException) {
138 return at(key, ::strlen(key));
141 value_t at(
const char *key,
size_t len)
throw (ContainerException) {
144 if (!lookup(key, len, v)) {
145 THROW(ContainerException,
"key %s not found", std::string(key, len).c_str());
151 value_t at(
const uint8_t *key,
size_t len)
throw (ContainerException) {
152 return ((
const char*) key, len);
155 const value_t& operator[](
const std::string &key)
const throw (ContainerException) {
156 return trie.update(key.data(), key.size());
159 const value_t& operator[](
const char *key)
const throw (ContainerException) {
160 return trie.update(key, ::strlen(key));
163 value_t& operator[](
const std::string &key)
throw (ContainerException) {
164 return trie.update(key.data(), key.size());
167 value_t& operator[](
const char *key)
throw (ContainerException) {
168 return trie.update(key, ::strlen(key));
171 bool contains(
const std::string &key)
throw () {
174 return lookup(key, v);
177 bool contains(
const char *key)
throw () {
180 return lookup(key, ::strlen(key), v);
183 bool contains(
const char *key,
size_t len)
throw () {
186 return lookup(key, len, v);
189 size_t capacity(
void)
const {
190 return trie.capacity();
193 size_t size(
void)
const {
197 size_t total_size(
void)
const {
198 return trie.total_size();
201 size_t unit_size(
void)
const {
202 return trie.unit_size();
205 size_t nonzero_size(
void)
const {
206 return trie.nonzero_size();
209 size_t num_keys(
void)
const {
210 return trie.num_keys();
213 bool empty(
void)
const throw () {
214 return (trie.num_keys() == 0);
217 void clear(
void)
throw () {