31 typedef typename Leaf::Key Key;
34 typedef enum {EMPTY, MISSED_LEFT, ON_TARGET, MISSED_RIGHT} Missed;
53 explicit XFastTrie(BitExtractor bx = BitExtractor(), Compare cmp = Compare()): _bx(bx), _cmp(cmp), _root(nullptr, false, false), _leftmost(nullptr), _rightmost(nullptr) {}
55 XFastTrie(
XFastTrie&& other)
noexcept: _bx(other._bx), _cmp(other._cmp), _root(other._root), _leftmost(other._leftmost), _rightmost(other._rightmost), _hash(std::move(other._hash)) {
56 other._root = Node(
nullptr,
false,
false);
57 other._leftmost =
nullptr;
58 other._rightmost =
nullptr;
61 Leaf* leftmost()
const {
return _leftmost; }
62 Leaf* rightmost()
const {
return _rightmost; }
64 Leaf* find(
const Key& key)
const {
65 auto key_ = _bx.shift(key, 0);
66 if (_hash[0].contains(key_)) {
67 return reinterpret_cast<Leaf*
>(_hash[0].at(key_));
72 Leaf* pred(
const Key& key,
bool strict =
false)
const {
73 auto [guess, missed, level] = approx(key);
80 return strict ? guess->prv : guess;
86 Leaf* succ(
const Key& key,
bool strict =
false)
const {
87 auto [guess, missed, level] = approx(key);
94 return strict ? guess->nxt : guess;
100 void insert(Leaf* leaf) {
103 auto [guess, missed, level] = approx(leaf->key);
106 _root = Node(leaf,
false,
false);
124 if (prv !=
nullptr) {
127 if (nxt !=
nullptr) {
134 next_bit = _bx.extract_bit(leaf->key, H - 1);
136 _root.set_right_present();
139 _root.set_left_present();
143 next_bit = _bx.extract_bit(leaf->key, level - 1);
145 if ((!_root.left_present() && !next_bit) || (!_root.right_present() && next_bit)) {
146 _root.set_descendant(leaf);
149 for (
unsigned int h = H - 1; h >= level; --h) {
150 auto key_prefix = _bx.shift(leaf->key, h);
151 std::uintptr_t value = _hash[h].at(key_prefix);
153 if (!node.left_present()) {
154 if (_cmp(leaf->key, node.descendant()->key)) {
155 node.set_descendant(leaf);
156 _hash[h][key_prefix] = node.value;
159 if (!node.right_present()) {
160 if (_cmp(node.descendant()->key, leaf->key)) {
161 node.set_descendant(leaf);
162 _hash[h][key_prefix] = node.value;
167 for (
unsigned int h = std::min(level, H - 1); h > 0; --h) {
168 next_bit = _bx.extract_bit(leaf->key, h - 1);
169 auto key_prefix = _bx.shift(leaf->key, h);
170 if (_hash[h].contains(key_prefix)) {
171 std::uintptr_t value = _hash[h].at(key_prefix);
174 node.set_right_present();
175 if (!node.left_present()) {
176 if (_cmp(leaf->key, node.descendant()->key)) {
177 node.set_descendant(leaf);
182 node.set_left_present();
183 if (!node.right_present()) {
184 if (_cmp(node.descendant()->key, leaf->key)) {
185 node.set_descendant(leaf);
189 _hash[h][key_prefix] = node.value;
192 Node node(leaf, !next_bit, next_bit);
193 _hash[h][key_prefix] = node.value;
197 _hash[0][_bx.shift(leaf->key, 0)] =
reinterpret_cast<std::uintptr_t
>(leaf);
199 if (_leftmost ==
nullptr || _cmp(leaf->key, _leftmost->key)) {
202 if (_rightmost ==
nullptr || _cmp(_rightmost->key, leaf->key)) {
207 void remove(Leaf* leaf) {
208 auto prv = leaf->prv;
209 auto nxt = leaf->nxt;
210 if (prv !=
nullptr) {
213 if (nxt !=
nullptr) {
217 _hash[0].erase(_bx.shift(leaf->key, 0));
219 bool subtree_removed =
true;
220 for (
unsigned int h = 1; h < H; ++h) {
221 auto key_prefix = _bx.shift(leaf->key, h);
222 std::uintptr_t value = _hash[h].at(key_prefix);
224 if (subtree_removed) {
225 if (_bx.extract_bit(leaf->key, h - 1)) {
226 node.clear_right_present();
227 if (node.left_present()) {
228 node.set_descendant(prv);
229 _hash[h][key_prefix] = node.value;
230 subtree_removed =
false;
233 _hash[h].erase(key_prefix);
237 node.clear_left_present();
238 if (node.right_present()) {
239 node.set_descendant(nxt);
240 _hash[h][key_prefix] = node.value;
241 subtree_removed =
false;
244 _hash[h].erase(key_prefix);
249 if (node.descendant() == leaf) {
250 if (!node.left_present()) {
251 node.set_descendant(nxt);
253 if (!node.right_present()) {
254 node.set_descendant(prv);
256 _hash[h][key_prefix] = node.value;
261 if (subtree_removed) {
262 if (_bx.extract_bit(leaf->key, H - 1)) {
263 _root.clear_right_present();
264 if (_root.left_present()) {
265 _root.set_descendant(prv);
268 _root.set_descendant(
nullptr);
272 _root.clear_left_present();
273 if (_root.right_present()) {
274 _root.set_descendant(nxt);
277 _root.set_descendant(
nullptr);
282 if (_root.descendant() == leaf) {
283 if (!_root.left_present()) {
284 _root.set_descendant(nxt);
286 if (!_root.right_present()) {
287 _root.set_descendant(prv);
292 if (_leftmost == leaf) {
295 if (_rightmost == leaf) {
301 for (
unsigned int h = 0; h < H; ++h) {
304 _root = Node(
nullptr,
false,
false);
306 _rightmost =
nullptr;
311 if (!_root.left_present() && !_root.right_present()) {
312 return {
nullptr, EMPTY, H };
320 if (_hash[m].contains(_bx.shift(key, m))) {
327 if (_hash[l].contains(_bx.shift(key, l))) {
335 std::uintptr_t value = _hash[0].at(_bx.shift(key, 0));
336 return {
reinterpret_cast<Leaf*
>(value), ON_TARGET, 0 };
341 std::uintptr_t value = _hash[m].at(_bx.shift(key, m));
347 if (node.left_present()) {
348 return { node.descendant(), MISSED_LEFT, m };
351 return { node.descendant(), MISSED_RIGHT, m };