github.com/moontrade/nogc@v0.1.7/collections/tree/art.cc (about) 1 #include <stdlib.h> 2 #include <string.h> 3 #include <atomic> 4 #include <thread> 5 #include "art.h" 6 #include "lock.h" 7 #include "RWSpinLock.h" 8 9 void art_sleep(uint64_t nanos) { 10 std::this_thread::sleep_for((std::chrono::nanoseconds) nanos); 11 } 12 13 #ifdef __i386__ 14 #include <emmintrin.h> 15 #else 16 #ifdef __amd64__ 17 18 #include <emmintrin.h> 19 20 #endif 21 #endif 22 23 /** 24 * Macros to manipulate pointer tags 25 */ 26 #define IS_LEAF(x) (((uintptr_t)x & 1)) 27 #define SET_LEAF(x) ((void*)((uintptr_t)x | 1)) 28 #define LEAF_RAW(x) ((art_leaf*)((void*)((uintptr_t)x & ~1))) 29 30 static inline void rwlock_lock(void* lock) { 31 ((RWSpinLock*)lock)->lock(); 32 } 33 static inline void rwlock_unlock(void* lock) { 34 ((RWSpinLock*)lock)->unlock(); 35 } 36 static inline void rwlock_lock_shared(void* lock) { 37 ((RWSpinLock*)lock)->lock_shared(); 38 } 39 static inline void rwlock_unlock_shared(void* lock) { 40 ((RWSpinLock*)lock)->unlock_shared(); 41 } 42 43 static inline void rwticketlock_lock(void* lock) { 44 ((RWTicketSpinLock32*)lock)->lock(); 45 } 46 47 static inline void rwticketlock_unlock(void* lock) { 48 ((RWTicketSpinLock32*)lock)->unlock(); 49 } 50 51 static inline void rwticketlock_lock_shared(void* lock) { 52 ((RWTicketSpinLock32*)lock)->lock_shared(); 53 } 54 55 static inline void rwticketlock_unlock_shared(void* lock) { 56 ((RWTicketSpinLock32*)lock)->unlock_shared(); 57 } 58 59 //struct art_lock_api { 60 // int fair; 61 // void (* lock)(void*); 62 // void (* unlock)(void*); 63 // void (* lock_shared)(void*); 64 // void (* unlock_shared)(void*); 65 //}; 66 // 67 //const struct art_lock_api art_lock_api_unfair = { 68 // .fair = 0, 69 // .lock = rwlock_lock, 70 // .unlock = rwlock_unlock, 71 // .lock_shared = rwlock_lock_shared, 72 // .unlock_shared = rwlock_unlock_shared, 73 //}; 74 // 75 //const struct art_lock_api art_lock_api_fair = { 76 // .fair = 1, 77 // .lock = rwticketlock_lock, 78 // .unlock = rwticketlock_unlock, 79 // .lock_shared = rwticketlock_lock_shared, 80 // .unlock_shared = rwticketlock_unlock_shared, 81 //}; 82 83 /** 84 * Allocates a node of the given type, 85 * initializes to zero and sets the type. 86 */ 87 static art_node *alloc_node(uint8_t type) { 88 art_node *n; 89 switch (type) { 90 case NODE4: 91 n = (art_node *) calloc(1, sizeof(art_node4)); 92 break; 93 case NODE16: 94 n = (art_node *) calloc(1, sizeof(art_node16)); 95 break; 96 case NODE48: 97 n = (art_node *) calloc(1, sizeof(art_node48)); 98 break; 99 case NODE256: 100 n = (art_node *) calloc(1, sizeof(art_node256)); 101 break; 102 default: 103 abort(); 104 } 105 n->type = type; 106 return n; 107 } 108 109 /** 110 * Initializes an ART tree 111 * @return 0 on success. 112 */ 113 int art_tree_init(art_tree *t) { 114 memset((void *) t, 0, sizeof(art_tree)); 115 t->root = NULL; 116 t->size = 0; 117 t->memory = sizeof(art_tree); 118 return 0; 119 } 120 121 void art_tree_init_lock(art_tree *t) { 122 t->lock = (void*)(&t->lock_); 123 } 124 125 // Recursively destroys the tree 126 static void destroy_node(art_node *n) { 127 // Break if null 128 if (!n) return; 129 130 // Special case leafs 131 if (IS_LEAF(n)) { 132 free(LEAF_RAW(n)); 133 return; 134 } 135 136 // Handle each node type 137 int i, idx; 138 union { 139 art_node4 *p1; 140 art_node16 *p2; 141 art_node48 *p3; 142 art_node256 *p4; 143 } p; 144 switch (n->type) { 145 case NODE4: 146 p.p1 = (art_node4 *) n; 147 for (i = 0; i < n->num_children; i++) { 148 destroy_node(p.p1->children[i]); 149 } 150 break; 151 152 case NODE16: 153 p.p2 = (art_node16 *) n; 154 for (i = 0; i < n->num_children; i++) { 155 destroy_node(p.p2->children[i]); 156 } 157 break; 158 159 case NODE48: 160 p.p3 = (art_node48 *) n; 161 for (i = 0; i < 256; i++) { 162 idx = ((art_node48 *) n)->keys[i]; 163 if (!idx) continue; 164 destroy_node(p.p3->children[idx - 1]); 165 } 166 break; 167 168 case NODE256: 169 p.p4 = (art_node256 *) n; 170 for (i = 0; i < 256; i++) { 171 if (p.p4->children[i]) 172 destroy_node(p.p4->children[i]); 173 } 174 break; 175 176 default: 177 abort(); 178 } 179 180 // Free ourself on the way up 181 free(n); 182 } 183 184 // Recursively destroys the tree 185 static void destroy_node_and_free_value(art_node *n) { 186 // Break if null 187 if (!n) return; 188 189 // Special case leafs 190 if (IS_LEAF(n)) { 191 art_leaf* leaf = LEAF_RAW(n); 192 if (leaf->value.value) { 193 free(leaf->value.value); 194 } 195 free((void*)leaf); 196 return; 197 } 198 199 // Handle each node type 200 int i, idx; 201 union { 202 art_node4 *p1; 203 art_node16 *p2; 204 art_node48 *p3; 205 art_node256 *p4; 206 } p; 207 switch (n->type) { 208 case NODE4: 209 p.p1 = (art_node4 *) n; 210 for (i = 0; i < n->num_children; i++) { 211 destroy_node(p.p1->children[i]); 212 } 213 break; 214 215 case NODE16: 216 p.p2 = (art_node16 *) n; 217 for (i = 0; i < n->num_children; i++) { 218 destroy_node(p.p2->children[i]); 219 } 220 break; 221 222 case NODE48: 223 p.p3 = (art_node48 *) n; 224 for (i = 0; i < 256; i++) { 225 idx = ((art_node48 *) n)->keys[i]; 226 if (!idx) continue; 227 destroy_node(p.p3->children[idx - 1]); 228 } 229 break; 230 231 case NODE256: 232 p.p4 = (art_node256 *) n; 233 for (i = 0; i < 256; i++) { 234 if (p.p4->children[i]) 235 destroy_node(p.p4->children[i]); 236 } 237 break; 238 239 default: 240 abort(); 241 } 242 243 // Free ourself on the way up 244 free(n); 245 } 246 247 /** 248 * Destroys an ART tree 249 * @return 0 on success. 250 */ 251 int art_tree_destroy(art_tree *t) { 252 if (t->lock) { 253 if (t->lock) { 254 if (t->fair) { 255 ((RWTicketSpinLock32*)t->lock)->lock(); 256 } else { 257 ((RWSpinLock*)t->lock)->lock(); 258 } 259 } 260 if (t->free) { 261 destroy_node_and_free_value(t->root); 262 } else { 263 destroy_node(t->root); 264 } 265 if (t->lock) { 266 if (t->fair) { 267 ((RWTicketSpinLock32*)t->lock)->unlock(); 268 } else { 269 ((RWSpinLock*)t->lock)->unlock(); 270 } 271 } 272 273 // t->lock_api->destroy(t->lock, NULL, NULL); 274 } else { 275 if (t->free) { 276 destroy_node_and_free_value(t->root); 277 } else { 278 destroy_node(t->root); 279 } 280 } 281 return 0; 282 } 283 284 /** 285 * Returns the size of the ART tree. 286 */ 287 288 #ifndef BROKEN_GCC_C99_INLINE 289 290 extern inline uint64_t art_size(art_tree *t); 291 292 #endif 293 294 static art_node **find_child(art_node *n, unsigned char c) { 295 int i, mask, bitfield; 296 union { 297 art_node4 *p1; 298 art_node16 *p2; 299 art_node48 *p3; 300 art_node256 *p4; 301 } p; 302 switch (n->type) { 303 case NODE4: 304 p.p1 = (art_node4 *) n; 305 for (i = 0; i < n->num_children; i++) { 306 /* this cast works around a bug in gcc 5.1 when unrolling loops 307 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124 308 */ 309 if (((unsigned char *) p.p1->keys)[i] == c) 310 return &p.p1->children[i]; 311 } 312 break; 313 314 { 315 case NODE16: 316 p.p2 = (art_node16 *) n; 317 318 // support non-86 architectures 319 #ifdef __i386__ 320 // Compare the key to all 16 stored keys 321 __m128i cmp; 322 cmp = _mm_cmpeq_epi8(_mm_set1_epi8(c), 323 _mm_loadu_si128((__m128i*)p.p2->keys)); 324 325 // Use a mask to ignore children that don't exist 326 mask = (1 << n->num_children) - 1; 327 bitfield = _mm_movemask_epi8(cmp) & mask; 328 #else 329 #ifdef __amd64__ 330 // Compare the key to all 16 stored keys 331 __m128i cmp; 332 cmp = _mm_cmpeq_epi8(_mm_set1_epi8(c), 333 _mm_loadu_si128((__m128i *) p.p2->keys)); 334 335 // Use a mask to ignore children that don't exist 336 mask = (1 << n->num_children) - 1; 337 bitfield = _mm_movemask_epi8(cmp) & mask; 338 #else 339 // Compare the key to all 16 stored keys 340 bitfield = 0; 341 for (i = 0; i < 16; ++i) { 342 if (p.p2->keys[i] == c) 343 bitfield |= (1 << i); 344 } 345 346 // Use a mask to ignore children that don't exist 347 mask = (1 << n->num_children) - 1; 348 bitfield &= mask; 349 #endif 350 #endif 351 352 /* 353 * If we have a match (any bit set) then we can 354 * return the pointer match using ctz to get 355 * the index. 356 */ 357 if (bitfield) 358 return &p.p2->children[__builtin_ctz(bitfield)]; 359 break; 360 } 361 362 case NODE48: 363 p.p3 = (art_node48 *) n; 364 i = p.p3->keys[c]; 365 if (i) 366 return &p.p3->children[i - 1]; 367 break; 368 369 case NODE256: 370 p.p4 = (art_node256 *) n; 371 if (p.p4->children[c]) 372 return &p.p4->children[c]; 373 break; 374 375 default: 376 abort(); 377 } 378 return NULL; 379 } 380 381 // Simple inlined if 382 static inline int min(int a, int b) { 383 return (a < b) ? a : b; 384 } 385 386 /** 387 * Returns the number of prefix characters shared between 388 * the key and node. 389 */ 390 static int check_prefix(const art_node *n, const unsigned char *key, int key_len, int depth) { 391 int max_cmp = min(min(n->partial_len, MAX_PREFIX_LEN), key_len - depth); 392 int idx; 393 for (idx = 0; idx < max_cmp; idx++) { 394 if (n->partial[idx] != key[depth + idx]) 395 return idx; 396 } 397 return idx; 398 } 399 400 /** 401 * Checks if a leaf matches 402 * @return 0 on success. 403 */ 404 static int leaf_matches(const art_leaf *n, const unsigned char *key, int key_len, int depth) { 405 (void) depth; 406 // Fail if the key lengths are different 407 if (n->key_len != (uint32_t) key_len) return 1; 408 409 // Compare the keys starting at the depth 410 return memcmp(n->key, key, key_len); 411 } 412 413 /** 414 * Searches for a value in the ART tree 415 * @arg t The tree 416 * @arg key The key 417 * @arg key_len The length of the key 418 * @return NULL if the item was not found, otherwise 419 * the value pointer is returned. 420 */ 421 art_search_result art_search(const art_tree *t, const unsigned char *key, int key_len) { 422 if (t->lock) { 423 if (t->fair) { 424 ((RWTicketSpinLock32*)t->lock)->lock_shared(); 425 } else { 426 ((RWSpinLock*)t->lock)->lock_shared(); 427 } 428 } 429 art_node **child; 430 art_node *n = t->root; 431 int prefix_len, depth = 0; 432 while (n) { 433 // Might be a leaf 434 if (IS_LEAF(n)) { 435 n = (art_node *) LEAF_RAW(n); 436 // Check if the expanded path matches 437 if (!leaf_matches((art_leaf *) n, key, key_len, depth)) { 438 if (t->lock) { 439 if (t->fair) { 440 ((RWTicketSpinLock32*)t->lock)->unlock_shared(); 441 } else { 442 ((RWSpinLock*)t->lock)->unlock_shared(); 443 } 444 } 445 return art_search_result{ 446 .value = ((art_leaf *) n)->value, 447 .found=1 448 }; 449 // return ((art_leaf *) n)->value; 450 } 451 if (t->lock) { 452 if (t->fair) { 453 ((RWTicketSpinLock32*)t->lock)->unlock_shared(); 454 } else { 455 ((RWSpinLock*)t->lock)->unlock_shared(); 456 } 457 } 458 return ART_NOT_FOUND; 459 } 460 461 // Bail if the prefix does not match 462 if (n->partial_len) { 463 prefix_len = check_prefix(n, key, key_len, depth); 464 if (prefix_len != min(MAX_PREFIX_LEN, n->partial_len)) { 465 if (t->lock) { 466 if (t->fair) { 467 ((RWTicketSpinLock32*)t->lock)->unlock_shared(); 468 } else { 469 ((RWSpinLock*)t->lock)->unlock_shared(); 470 } 471 } 472 return ART_NOT_FOUND; 473 } 474 depth = depth + n->partial_len; 475 } 476 477 // Recursively search 478 child = find_child(n, key[depth]); 479 n = (child) ? *child : NULL; 480 depth++; 481 } 482 if (t->lock) { 483 if (t->fair) { 484 ((RWTicketSpinLock32*)t->lock)->unlock_shared(); 485 } else { 486 ((RWSpinLock*)t->lock)->unlock_shared(); 487 } 488 } 489 return ART_NOT_FOUND; 490 } 491 492 // Find the minimum leaf under a node 493 static art_leaf *minimum(const art_node *n) { 494 // Handle base cases 495 if (!n) return NULL; 496 if (IS_LEAF(n)) return LEAF_RAW(n); 497 498 int idx; 499 switch (n->type) { 500 case NODE4: 501 return minimum(((const art_node4 *) n)->children[0]); 502 case NODE16: 503 return minimum(((const art_node16 *) n)->children[0]); 504 case NODE48: 505 idx = 0; 506 while (!((const art_node48 *) n)->keys[idx]) idx++; 507 idx = ((const art_node48 *) n)->keys[idx] - 1; 508 return minimum(((const art_node48 *) n)->children[idx]); 509 case NODE256: 510 idx = 0; 511 while (!((const art_node256 *) n)->children[idx]) idx++; 512 return minimum(((const art_node256 *) n)->children[idx]); 513 default: 514 abort(); 515 } 516 } 517 518 // Find the maximum leaf under a node 519 static art_leaf *maximum(const art_node *n) { 520 // Handle base cases 521 if (!n) return NULL; 522 if (IS_LEAF(n)) return LEAF_RAW(n); 523 524 int idx; 525 switch (n->type) { 526 case NODE4: 527 return maximum(((const art_node4 *) n)->children[n->num_children - 1]); 528 case NODE16: 529 return maximum(((const art_node16 *) n)->children[n->num_children - 1]); 530 case NODE48: 531 idx = 255; 532 while (!((const art_node48 *) n)->keys[idx]) idx--; 533 idx = ((const art_node48 *) n)->keys[idx] - 1; 534 return maximum(((const art_node48 *) n)->children[idx]); 535 case NODE256: 536 idx = 255; 537 while (!((const art_node256 *) n)->children[idx]) idx--; 538 return maximum(((const art_node256 *) n)->children[idx]); 539 default: 540 abort(); 541 } 542 } 543 544 /** 545 * Returns the minimum valued leaf 546 */ 547 art_leaf *art_minimum(art_tree *t) { 548 return minimum((art_node *) t->root); 549 } 550 551 /** 552 * Returns the maximum valued leaf 553 */ 554 art_leaf *art_maximum(art_tree *t) { 555 return maximum((art_node *) t->root); 556 } 557 558 static art_leaf *make_leaf(const unsigned char *key, int key_len, art_value value) { 559 art_leaf *l = (art_leaf *) calloc(1, sizeof(art_leaf) + key_len); 560 l->value = value; 561 l->key_len = key_len; 562 memcpy(l->key, key, key_len); 563 return l; 564 } 565 566 static int longest_common_prefix(art_leaf *l1, art_leaf *l2, int depth) { 567 int max_cmp = min(l1->key_len, l2->key_len) - depth; 568 int idx; 569 for (idx = 0; idx < max_cmp; idx++) { 570 if (l1->key[depth + idx] != l2->key[depth + idx]) 571 return idx; 572 } 573 return idx; 574 } 575 576 static void copy_header(art_node *dest, art_node *src) { 577 dest->num_children = src->num_children; 578 dest->partial_len = src->partial_len; 579 memcpy(dest->partial, src->partial, min(MAX_PREFIX_LEN, src->partial_len)); 580 } 581 582 static void add_child256(art_tree *t, art_node256 *n, art_node **ref, unsigned char c, void *child) { 583 (void) ref; 584 n->n.num_children++; 585 n->children[c] = (art_node *) child; 586 } 587 588 static void add_child48(art_tree *t, art_node48 *n, art_node **ref, unsigned char c, void *child) { 589 if (n->n.num_children < 48) { 590 int pos = 0; 591 while (n->children[pos]) pos++; 592 n->children[pos] = (art_node *) child; 593 n->keys[c] = pos + 1; 594 n->n.num_children++; 595 } else { 596 art_node256 *new_node = (art_node256 *) alloc_node(NODE256); 597 for (int i = 0; i < 256; i++) { 598 if (n->keys[i]) { 599 new_node->children[i] = n->children[n->keys[i] - 1]; 600 } 601 } 602 copy_header((art_node *) new_node, (art_node *) n); 603 *ref = (art_node *) new_node; 604 free(n); 605 if (t->calc_memory) { 606 t->memory += sizeof(art_node256) - sizeof(art_node48); 607 } 608 add_child256(t, new_node, ref, c, child); 609 } 610 } 611 612 static void add_child16(art_tree *t, art_node16 *n, art_node **ref, unsigned char c, void *child) { 613 if (n->n.num_children < 16) { 614 unsigned mask = (1 << n->n.num_children) - 1; 615 616 // support non-x86 architectures 617 #ifdef __i386__ 618 __m128i cmp; 619 620 // Compare the key to all 16 stored keys 621 cmp = _mm_cmplt_epi8(_mm_set1_epi8(c), 622 _mm_loadu_si128((__m128i*)n->keys)); 623 624 // Use a mask to ignore children that don't exist 625 unsigned bitfield = _mm_movemask_epi8(cmp) & mask; 626 #else 627 #ifdef __amd64__ 628 __m128i cmp; 629 630 // Compare the key to all 16 stored keys 631 cmp = _mm_cmplt_epi8(_mm_set1_epi8(c), 632 _mm_loadu_si128((__m128i *) n->keys)); 633 634 // Use a mask to ignore children that don't exist 635 unsigned bitfield = _mm_movemask_epi8(cmp) & mask; 636 #else 637 // Compare the key to all 16 stored keys 638 unsigned bitfield = 0; 639 for (short i = 0; i < 16; ++i) { 640 if (c < n->keys[i]) 641 bitfield |= (1 << i); 642 } 643 644 // Use a mask to ignore children that don't exist 645 bitfield &= mask; 646 #endif 647 #endif 648 649 // Check if less than any 650 unsigned idx; 651 if (bitfield) { 652 idx = __builtin_ctz(bitfield); 653 memmove(n->keys + idx + 1, n->keys + idx, n->n.num_children - idx); 654 memmove(n->children + idx + 1, n->children + idx, 655 (n->n.num_children - idx) * sizeof(void *)); 656 } else 657 idx = n->n.num_children; 658 659 // Set the child 660 n->keys[idx] = c; 661 n->children[idx] = (art_node *) child; 662 n->n.num_children++; 663 664 } else { 665 art_node48 *new_node = (art_node48 *) alloc_node(NODE48); 666 667 // Copy the child pointers and populate the key map 668 memcpy(new_node->children, n->children, 669 sizeof(void *) * n->n.num_children); 670 for (int i = 0; i < n->n.num_children; i++) { 671 new_node->keys[n->keys[i]] = i + 1; 672 } 673 copy_header((art_node *) new_node, (art_node *) n); 674 *ref = (art_node *) new_node; 675 free(n); 676 if (t->calc_memory) { 677 t->memory += sizeof(art_node48) - sizeof(art_node16); 678 } 679 add_child48(t, new_node, ref, c, child); 680 } 681 } 682 683 static void add_child4(art_tree *t, art_node4 *n, art_node **ref, unsigned char c, void *child) { 684 if (n->n.num_children < 4) { 685 int idx; 686 for (idx = 0; idx < n->n.num_children; idx++) { 687 if (c < n->keys[idx]) break; 688 } 689 690 // Shift to make room 691 memmove(n->keys + idx + 1, n->keys + idx, n->n.num_children - idx); 692 memmove(n->children + idx + 1, n->children + idx, 693 (n->n.num_children - idx) * sizeof(void *)); 694 695 // Insert element 696 n->keys[idx] = c; 697 n->children[idx] = (art_node *) child; 698 n->n.num_children++; 699 700 } else { 701 art_node16 *new_node = (art_node16 *) alloc_node(NODE16); 702 703 // Copy the child pointers and the key map 704 memcpy(new_node->children, n->children, 705 sizeof(void *) * n->n.num_children); 706 memcpy(new_node->keys, n->keys, 707 sizeof(unsigned char) * n->n.num_children); 708 copy_header((art_node *) new_node, (art_node *) n); 709 *ref = (art_node *) new_node; 710 free(n); 711 if (t->calc_memory) { 712 t->memory += sizeof(art_node16) - sizeof(art_node4); 713 } 714 add_child16(t, new_node, ref, c, child); 715 } 716 } 717 718 static void add_child(art_tree *t, art_node *n, art_node **ref, unsigned char c, void *child) { 719 switch (n->type) { 720 case NODE4: 721 return add_child4(t, (art_node4 *) n, ref, c, child); 722 case NODE16: 723 return add_child16(t, (art_node16 *) n, ref, c, child); 724 case NODE48: 725 return add_child48(t, (art_node48 *) n, ref, c, child); 726 case NODE256: 727 return add_child256(t, (art_node256 *) n, ref, c, child); 728 default: 729 abort(); 730 } 731 } 732 733 /** 734 * Calculates the index at which the prefixes mismatch 735 */ 736 static int prefix_mismatch(const art_node *n, const unsigned char *key, int key_len, int depth) { 737 int max_cmp = min(min(MAX_PREFIX_LEN, n->partial_len), key_len - depth); 738 int idx; 739 for (idx = 0; idx < max_cmp; idx++) { 740 if (n->partial[idx] != key[depth + idx]) 741 return idx; 742 } 743 744 // If the prefix is short we can avoid finding a leaf 745 if (n->partial_len > MAX_PREFIX_LEN) { 746 // Prefix is longer than what we've checked, find a leaf 747 art_leaf *l = minimum(n); 748 max_cmp = min(l->key_len, key_len) - depth; 749 for (; idx < max_cmp; idx++) { 750 if (l->key[idx + depth] != key[depth + idx]) 751 return idx; 752 } 753 } 754 return idx; 755 } 756 757 static art_value 758 recursive_insert(art_tree *t, art_node *n, art_node **ref, const unsigned char *key, int key_len, art_value value, 759 int depth, int *old, int replace) { 760 // If we are at a NULL node, inject a leaf 761 if (!n) { 762 *ref = (art_node *) SET_LEAF(make_leaf(key, key_len, value)); 763 return ART_NULL_VALUE; 764 } 765 766 // If we are at a leaf, we need to replace it with a node 767 if (IS_LEAF(n)) { 768 art_leaf *l = LEAF_RAW(n); 769 770 // Check if we are updating an existing value 771 if (!leaf_matches(l, key, key_len, depth)) { 772 *old = 1; 773 art_value old_val = l->value; 774 if (replace) l->value = value; 775 return old_val; 776 } 777 778 // New value, we must split the leaf into a node4 779 art_node4 *new_node = (art_node4 *) alloc_node(NODE4);\ 780 if (t->calc_memory) { 781 t->memory += sizeof(art_node4); 782 } 783 784 // Create a new leaf 785 art_leaf *l2 = make_leaf(key, key_len, value); 786 787 // Determine longest prefix 788 int longest_prefix = longest_common_prefix(l, l2, depth); 789 new_node->n.partial_len = longest_prefix; 790 memcpy(new_node->n.partial, key + depth, min(MAX_PREFIX_LEN, longest_prefix)); 791 // Add the leafs to the new node4 792 *ref = (art_node *) new_node; 793 add_child4(t, new_node, ref, l->key[depth + longest_prefix], SET_LEAF(l)); 794 add_child4(t, new_node, ref, l2->key[depth + longest_prefix], SET_LEAF(l2)); 795 return ART_NULL_VALUE; 796 } 797 798 // Check if given node has a prefix 799 if (n->partial_len) { 800 // Determine if the prefixes differ, since we need to split 801 int prefix_diff = prefix_mismatch(n, key, key_len, depth); 802 if ((uint32_t) prefix_diff >= n->partial_len) { 803 depth += n->partial_len; 804 goto RECURSE_SEARCH; 805 } 806 807 // Create a new node 808 art_node4 *new_node = (art_node4 *) alloc_node(NODE4); 809 if (t->calc_memory) { 810 t->memory += sizeof(art_node4); 811 } 812 *ref = (art_node *) new_node; 813 new_node->n.partial_len = prefix_diff; 814 memcpy(new_node->n.partial, n->partial, min(MAX_PREFIX_LEN, prefix_diff)); 815 816 // Adjust the prefix of the old node 817 if (n->partial_len <= MAX_PREFIX_LEN) { 818 add_child4(t, new_node, ref, n->partial[prefix_diff], n); 819 n->partial_len -= (prefix_diff + 1); 820 memmove(n->partial, n->partial + prefix_diff + 1, 821 min(MAX_PREFIX_LEN, n->partial_len)); 822 } else { 823 n->partial_len -= (prefix_diff + 1); 824 art_leaf *l = minimum(n); 825 add_child4(t, new_node, ref, l->key[depth + prefix_diff], n); 826 memcpy(n->partial, l->key + depth + prefix_diff + 1, 827 min(MAX_PREFIX_LEN, n->partial_len)); 828 } 829 830 // Insert the new leaf 831 art_leaf *l = make_leaf(key, key_len, value); 832 add_child4(t, new_node, ref, key[depth + prefix_diff], SET_LEAF(l)); 833 return ART_NULL_VALUE; 834 } 835 836 RECURSE_SEARCH:; 837 838 // Find a child to recurse to 839 art_node **child = find_child(n, key[depth]); 840 if (child) { 841 return recursive_insert(t, *child, child, key, key_len, value, depth + 1, old, replace); 842 } 843 844 // No child, node goes within us 845 art_leaf *l = make_leaf(key, key_len, value); 846 add_child(t, n, ref, key[depth], SET_LEAF(l)); 847 return ART_NULL_VALUE; 848 } 849 850 /** 851 * inserts a new value into the art tree 852 * @arg t the tree 853 * @arg key the key 854 * @arg key_len the length of the key 855 * @arg value opaque value. 856 * @return null if the item was newly inserted, otherwise 857 * the old value pointer is returned. 858 */ 859 art_value art_insert(art_tree *t, const unsigned char *key, int key_len, art_value value) { 860 if (t->lock) { 861 if (t->fair) { 862 ((RWTicketSpinLock32*)t->lock)->lock(); 863 } else { 864 ((RWSpinLock*)t->lock)->lock(); 865 } 866 } 867 int old_val = 0; 868 art_value old = recursive_insert(t, t->root, &t->root, key, key_len, value, 0, &old_val, 1); 869 if (!old_val) { 870 t->size++; 871 if (t->calc_memory) { 872 t->memory += (uint64_t) sizeof(art_leaf); 873 } 874 } 875 if (t->lock) { 876 if (t->fair) { 877 ((RWTicketSpinLock32*)t->lock)->unlock(); 878 } else { 879 ((RWSpinLock*)t->lock)->unlock(); 880 } 881 } 882 return old; 883 } 884 885 art_search_result art_insert_value(art_tree *t, const unsigned char *key, int key_len, art_value value) { 886 if (t->lock) { 887 if (t->fair) { 888 ((RWTicketSpinLock32*)t->lock)->lock(); 889 } else { 890 ((RWSpinLock*)t->lock)->lock(); 891 } 892 } 893 int old_val = 0; 894 art_value old = recursive_insert(t, t->root, &t->root, key, key_len, value, 0, &old_val, 1); 895 if (!old_val) { 896 t->size++; 897 if (t->calc_memory) { 898 t->memory += (uint64_t) sizeof(art_leaf); 899 } 900 } 901 if (t->lock) { 902 if (t->fair) { 903 ((RWTicketSpinLock32*)t->lock)->unlock(); 904 } else { 905 ((RWSpinLock*)t->lock)->unlock(); 906 } 907 } 908 if (!old_val) { 909 return ART_NOT_FOUND; 910 } 911 return art_search_result{ 912 .value=old, 913 .found=1 914 }; 915 } 916 917 /** 918 * inserts a new value into the art tree (no replace) 919 * @arg t the tree 920 * @arg key the key 921 * @arg key_len the length of the key 922 * @arg value opaque value. 923 * @return null if the item was newly inserted, otherwise 924 * the old value pointer is returned. 925 */ 926 art_value art_insert_no_replace(art_tree *t, const unsigned char *key, int key_len, art_value value) { 927 if (t->lock) { 928 if (t->fair) { 929 ((RWTicketSpinLock32*)t->lock)->lock(); 930 } else { 931 ((RWSpinLock*)t->lock)->lock(); 932 } 933 } 934 int old_val = 0; 935 art_value old = recursive_insert(t, t->root, &t->root, key, key_len, value, 0, &old_val, 0); 936 if (!old_val) { 937 t->size++; 938 if (t->calc_memory) { 939 t->memory += (uint64_t) sizeof(art_leaf); 940 } 941 } 942 943 if (t->lock) { 944 if (t->fair) { 945 ((RWTicketSpinLock32*)t->lock)->unlock(); 946 } else { 947 ((RWSpinLock*)t->lock)->unlock(); 948 } 949 } 950 return old; 951 } 952 953 art_search_result art_insert_no_replace_value(art_tree *t, const unsigned char *key, int key_len, art_value value) { 954 if (t->lock) { 955 if (t->fair) { 956 ((RWTicketSpinLock32*)t->lock)->lock(); 957 } else { 958 ((RWSpinLock*)t->lock)->lock(); 959 } 960 } 961 moontrade_ordered_rwlock_lock((size_t)((void*)(&t->lock)), 0); 962 int old_val = 0; 963 art_value old = recursive_insert(t, t->root, &t->root, key, key_len, value, 0, &old_val, 0); 964 if (!old_val) { 965 t->size++; 966 if (t->calc_memory) { 967 t->memory += (uint64_t) sizeof(art_leaf); 968 } 969 } 970 971 if (t->lock) { 972 if (t->fair) { 973 ((RWTicketSpinLock32*)t->lock)->unlock(); 974 } else { 975 ((RWSpinLock*)t->lock)->unlock(); 976 } 977 } 978 if (!old_val) { 979 return ART_NOT_FOUND; 980 } 981 return art_search_result{ 982 .value=old, 983 .found=1 984 }; 985 } 986 987 static void remove_child256(art_tree *t, art_node256 *n, art_node **ref, unsigned char c) { 988 n->children[c] = NULL; 989 n->n.num_children--; 990 991 // Resize to a node48 on underflow, not immediately to prevent 992 // trashing if we sit on the 48/49 boundary 993 if (n->n.num_children == 37) { 994 art_node48 *new_node = (art_node48 *) alloc_node(NODE48); 995 *ref = (art_node *) new_node; 996 copy_header((art_node *) new_node, (art_node *) n); 997 998 int pos = 0; 999 for (int i = 0; i < 256; i++) { 1000 if (n->children[i]) { 1001 new_node->children[pos] = n->children[i]; 1002 new_node->keys[i] = pos + 1; 1003 pos++; 1004 } 1005 } 1006 free(n); 1007 t->memory -= (uint64_t) sizeof(art_node256) - (uint64_t) sizeof(art_node48); 1008 } 1009 } 1010 1011 static void remove_child48(art_tree *t, art_node48 *n, art_node **ref, unsigned char c) { 1012 int pos = n->keys[c]; 1013 n->keys[c] = 0; 1014 n->children[pos - 1] = NULL; 1015 n->n.num_children--; 1016 1017 if (n->n.num_children == 12) { 1018 art_node16 *new_node = (art_node16 *) alloc_node(NODE16); 1019 *ref = (art_node *) new_node; 1020 copy_header((art_node *) new_node, (art_node *) n); 1021 1022 int child = 0; 1023 for (int i = 0; i < 256; i++) { 1024 pos = n->keys[i]; 1025 if (pos) { 1026 new_node->keys[child] = i; 1027 new_node->children[child] = n->children[pos - 1]; 1028 child++; 1029 } 1030 } 1031 free(n); 1032 t->memory -= (uint64_t) sizeof(art_node48) - (uint64_t) sizeof(art_node16); 1033 } 1034 } 1035 1036 static void remove_child16(art_tree *t, art_node16 *n, art_node **ref, art_node **l) { 1037 int pos = l - n->children; 1038 memmove(n->keys + pos, n->keys + pos + 1, n->n.num_children - 1 - pos); 1039 memmove(n->children + pos, n->children + pos + 1, (n->n.num_children - 1 - pos) * sizeof(void *)); 1040 n->n.num_children--; 1041 1042 if (n->n.num_children == 3) { 1043 art_node4 *new_node = (art_node4 *) alloc_node(NODE4); 1044 *ref = (art_node *) new_node; 1045 copy_header((art_node *) new_node, (art_node *) n); 1046 memcpy(new_node->keys, n->keys, 4); 1047 memcpy(new_node->children, n->children, 4 * sizeof(void *)); 1048 free(n); 1049 t->memory -= (uint64_t) sizeof(art_node16) - (uint64_t) sizeof(art_node4); 1050 } 1051 } 1052 1053 static void remove_child4(art_tree *t, art_node4 *n, art_node **ref, art_node **l) { 1054 int pos = l - n->children; 1055 memmove(n->keys + pos, n->keys + pos + 1, n->n.num_children - 1 - pos); 1056 memmove(n->children + pos, n->children + pos + 1, (n->n.num_children - 1 - pos) * sizeof(void *)); 1057 n->n.num_children--; 1058 1059 // Remove nodes with only a single child 1060 if (n->n.num_children == 1) { 1061 art_node *child = n->children[0]; 1062 if (!IS_LEAF(child)) { 1063 // Concatenate the prefixes 1064 int prefix = n->n.partial_len; 1065 if (prefix < MAX_PREFIX_LEN) { 1066 n->n.partial[prefix] = n->keys[0]; 1067 prefix++; 1068 } 1069 if (prefix < MAX_PREFIX_LEN) { 1070 int sub_prefix = min(child->partial_len, MAX_PREFIX_LEN - prefix); 1071 memcpy(n->n.partial + prefix, child->partial, sub_prefix); 1072 prefix += sub_prefix; 1073 } 1074 1075 // Store the prefix in the child 1076 memcpy(child->partial, n->n.partial, min(prefix, MAX_PREFIX_LEN)); 1077 child->partial_len += n->n.partial_len + 1; 1078 } 1079 *ref = child; 1080 free(n); 1081 t->memory -= (uint64_t) sizeof(art_node4); 1082 } 1083 } 1084 1085 static void remove_child(art_tree *t, art_node *n, art_node **ref, unsigned char c, art_node **l) { 1086 switch (n->type) { 1087 case NODE4: 1088 return remove_child4(t, (art_node4 *) n, ref, l); 1089 case NODE16: 1090 return remove_child16(t, (art_node16 *) n, ref, l); 1091 case NODE48: 1092 return remove_child48(t, (art_node48 *) n, ref, c); 1093 case NODE256: 1094 return remove_child256(t, (art_node256 *) n, ref, c); 1095 default: 1096 abort(); 1097 } 1098 } 1099 1100 static art_leaf * 1101 recursive_delete(art_tree *t, art_node *n, art_node **ref, const unsigned char *key, int key_len, int depth) { 1102 // Search terminated 1103 if (!n) return NULL; 1104 1105 // Handle hitting a leaf node 1106 if (IS_LEAF(n)) { 1107 art_leaf *l = LEAF_RAW(n); 1108 if (!leaf_matches(l, key, key_len, depth)) { 1109 *ref = NULL; 1110 return l; 1111 } 1112 return NULL; 1113 } 1114 1115 // Bail if the prefix does not match 1116 if (n->partial_len) { 1117 int prefix_len = check_prefix(n, key, key_len, depth); 1118 if (prefix_len != min(MAX_PREFIX_LEN, n->partial_len)) { 1119 return NULL; 1120 } 1121 depth = depth + n->partial_len; 1122 } 1123 1124 // Find child node 1125 art_node **child = find_child(n, key[depth]); 1126 if (!child) return NULL; 1127 1128 // If the child is leaf, delete from this node 1129 if (IS_LEAF(*child)) { 1130 art_leaf *l = LEAF_RAW(*child); 1131 if (!leaf_matches(l, key, key_len, depth)) { 1132 remove_child(t, n, ref, key[depth], child); 1133 return l; 1134 } 1135 return NULL; 1136 1137 // Recurse 1138 } else { 1139 return recursive_delete(t, *child, child, key, key_len, depth + 1); 1140 } 1141 } 1142 1143 /** 1144 * Deletes a value from the ART tree 1145 * @arg t The tree 1146 * @arg key The key 1147 * @arg key_len The length of the key 1148 * @return NULL if the item was not found, otherwise 1149 * the value pointer is returned. 1150 */ 1151 art_value art_delete(art_tree *t, const unsigned char *key, int key_len) { 1152 if (t->lock) { 1153 if (t->fair) { 1154 ((RWTicketSpinLock32*)t->lock)->lock(); 1155 } else { 1156 ((RWSpinLock*)t->lock)->lock(); 1157 } 1158 } 1159 art_leaf *l = recursive_delete(t, t->root, &t->root, key, key_len, 0); 1160 if (l) { 1161 t->size--; 1162 t->memory -= (uint64_t) sizeof(art_leaf) + (uint64_t) l->key_len; 1163 art_value old = l->value; 1164 if (t->lock) { 1165 if (t->fair) { 1166 ((RWTicketSpinLock32*)t->lock)->unlock(); 1167 } else { 1168 ((RWSpinLock*)t->lock)->unlock(); 1169 } 1170 } 1171 free(l); 1172 return old; 1173 } 1174 if (t->lock) { 1175 if (t->fair) { 1176 ((RWTicketSpinLock32*)t->lock)->unlock(); 1177 } else { 1178 ((RWSpinLock*)t->lock)->unlock(); 1179 } 1180 } 1181 return ART_NULL_VALUE; 1182 } 1183 1184 art_search_result art_delete_value(art_tree *t, const unsigned char *key, int key_len) { 1185 if (t->lock) { 1186 if (t->fair) { 1187 ((RWTicketSpinLock32*)t->lock)->lock(); 1188 } else { 1189 ((RWSpinLock*)t->lock)->lock(); 1190 } 1191 } 1192 art_leaf *l = recursive_delete(t, t->root, &t->root, key, key_len, 0); 1193 if (l) { 1194 t->size--; 1195 t->memory -= (uint64_t) sizeof(art_leaf) + (uint64_t) l->key_len; 1196 art_value old = l->value; 1197 if (t->lock) { 1198 if (t->fair) { 1199 ((RWTicketSpinLock32*)t->lock)->unlock(); 1200 } else { 1201 ((RWSpinLock*)t->lock)->unlock(); 1202 } 1203 } 1204 free(l); 1205 return art_search_result{ 1206 .value=old, 1207 .found=1 1208 }; 1209 } 1210 if (t->lock) { 1211 if (t->fair) { 1212 ((RWTicketSpinLock32*)t->lock)->unlock(); 1213 } else { 1214 ((RWSpinLock*)t->lock)->unlock(); 1215 } 1216 } 1217 return ART_NOT_FOUND; 1218 } 1219 1220 // Recursively iterates over the tree 1221 static int recursive_iter(art_node *n, art_callback cb, void *data) { 1222 // Handle base cases 1223 if (!n) return 0; 1224 if (IS_LEAF(n)) { 1225 art_leaf *l = LEAF_RAW(n); 1226 return cb(data, (const unsigned char *) l->key, l->key_len, l->value); 1227 } 1228 1229 int idx, res; 1230 switch (n->type) { 1231 case NODE4: 1232 for (int i = 0; i < n->num_children; i++) { 1233 res = recursive_iter(((art_node4 *) n)->children[i], cb, data); 1234 if (res) return res; 1235 } 1236 break; 1237 1238 case NODE16: 1239 for (int i = 0; i < n->num_children; i++) { 1240 res = recursive_iter(((art_node16 *) n)->children[i], cb, data); 1241 if (res) return res; 1242 } 1243 break; 1244 1245 case NODE48: 1246 for (int i = 0; i < 256; i++) { 1247 idx = ((art_node48 *) n)->keys[i]; 1248 if (!idx) continue; 1249 1250 res = recursive_iter(((art_node48 *) n)->children[idx - 1], cb, data); 1251 if (res) return res; 1252 } 1253 break; 1254 1255 case NODE256: 1256 for (int i = 0; i < 256; i++) { 1257 if (!((art_node256 *) n)->children[i]) continue; 1258 res = recursive_iter(((art_node256 *) n)->children[i], cb, data); 1259 if (res) return res; 1260 } 1261 break; 1262 1263 default: 1264 abort(); 1265 } 1266 return 0; 1267 } 1268 1269 /** 1270 * Iterates through the entries pairs in the map, 1271 * invoking a callback for each. The call back gets a 1272 * key, value for each and returns an integer stop value. 1273 * If the callback returns non-zero, then the iteration stops. 1274 * @arg t The tree to iterate over 1275 * @arg cb The callback function to invoke 1276 * @arg data Opaque handle passed to the callback 1277 * @return 0 on success, or the return of the callback. 1278 */ 1279 int art_iter(art_tree *t, art_callback cb, void *data) { 1280 if (t->lock) { 1281 if (t->fair) { 1282 ((RWTicketSpinLock32*)t->lock)->lock_shared(); 1283 } else { 1284 ((RWSpinLock*)t->lock)->lock_shared(); 1285 } 1286 } 1287 int result = recursive_iter(t->root, cb, data); 1288 if (t->lock) { 1289 if (t->fair) { 1290 ((RWTicketSpinLock32*)t->lock)->unlock_shared(); 1291 } else { 1292 ((RWSpinLock*)t->lock)->unlock_shared(); 1293 } 1294 } 1295 return result; 1296 } 1297 1298 /** 1299 * Checks if a leaf prefix matches 1300 * @return 0 on success. 1301 */ 1302 static int leaf_prefix_matches(const art_leaf *n, const unsigned char *prefix, int prefix_len) { 1303 // Fail if the key length is too short 1304 if (n->key_len < (uint32_t) prefix_len) return 1; 1305 1306 // Compare the keys 1307 return memcmp(n->key, prefix, prefix_len); 1308 } 1309 1310 /** 1311 * Iterates through the entries pairs in the map, 1312 * invoking a callback for each that matches a given prefix. 1313 * The call back gets a key, value for each and returns an integer stop value. 1314 * If the callback returns non-zero, then the iteration stops. 1315 * @arg t The tree to iterate over 1316 * @arg prefix The prefix of keys to read 1317 * @arg prefix_len The length of the prefix 1318 * @arg cb The callback function to invoke 1319 * @arg data Opaque handle passed to the callback 1320 * @return 0 on success, or the return of the callback. 1321 */ 1322 int art_iter_prefix(art_tree *t, const unsigned char *key, int key_len, art_callback cb, void *data) { 1323 if (t->lock) { 1324 if (t->fair) { 1325 ((RWTicketSpinLock32*)t->lock)->lock_shared(); 1326 } else { 1327 ((RWSpinLock*)t->lock)->lock_shared(); 1328 } 1329 } 1330 art_node **child; 1331 art_node *n = t->root; 1332 int prefix_len, depth = 0; 1333 while (n) { 1334 // Might be a leaf 1335 if (IS_LEAF(n)) { 1336 n = (art_node *) LEAF_RAW(n); 1337 // Check if the expanded path matches 1338 if (!leaf_prefix_matches((art_leaf *) n, key, key_len)) { 1339 art_leaf *l = (art_leaf *) n; 1340 int result = cb(data, (const unsigned char *) l->key, l->key_len, l->value); 1341 if (t->lock) { 1342 if (t->fair) { 1343 ((RWTicketSpinLock32*)t->lock)->unlock_shared(); 1344 } else { 1345 ((RWSpinLock*)t->lock)->unlock_shared(); 1346 } 1347 } 1348 return result; 1349 } 1350 return 0; 1351 } 1352 1353 // If the depth matches the prefix, we need to handle this node 1354 if (depth == key_len) { 1355 art_leaf *l = minimum(n); 1356 if (!leaf_prefix_matches(l, key, key_len)) { 1357 int result = recursive_iter(n, cb, data); 1358 if (t->lock) { 1359 if (t->fair) { 1360 ((RWTicketSpinLock32*)t->lock)->unlock_shared(); 1361 } else { 1362 ((RWSpinLock*)t->lock)->unlock_shared(); 1363 } 1364 } 1365 return result; 1366 } 1367 if (t->lock) { 1368 if (t->fair) { 1369 ((RWTicketSpinLock32*)t->lock)->unlock_shared(); 1370 } else { 1371 ((RWSpinLock*)t->lock)->unlock_shared(); 1372 } 1373 } 1374 return 0; 1375 } 1376 1377 // Bail if the prefix does not match 1378 if (n->partial_len) { 1379 prefix_len = prefix_mismatch(n, key, key_len, depth); 1380 1381 // Guard if the mis-match is longer than the MAX_PREFIX_LEN 1382 if ((uint32_t) prefix_len > n->partial_len) { 1383 prefix_len = n->partial_len; 1384 } 1385 1386 // If there is no match, search is terminated 1387 if (!prefix_len) { 1388 if (t->lock) { 1389 if (t->fair) { 1390 ((RWTicketSpinLock32*)t->lock)->unlock_shared(); 1391 } else { 1392 ((RWSpinLock*)t->lock)->unlock_shared(); 1393 } 1394 } 1395 return 0; 1396 // If we've matched the prefix, iterate on this node 1397 } else if (depth + prefix_len == key_len) { 1398 int result = recursive_iter(n, cb, data); 1399 if (t->lock) { 1400 if (t->fair) { 1401 ((RWTicketSpinLock32*)t->lock)->unlock_shared(); 1402 } else { 1403 ((RWSpinLock*)t->lock)->unlock_shared(); 1404 } 1405 } 1406 return result; 1407 } 1408 1409 // if there is a full match, go deeper 1410 depth = depth + n->partial_len; 1411 } 1412 1413 // Recursively search 1414 child = find_child(n, key[depth]); 1415 n = (child) ? *child : NULL; 1416 depth++; 1417 } 1418 if (t->lock) { 1419 if (t->fair) { 1420 ((RWTicketSpinLock32*)t->lock)->unlock(); 1421 } else { 1422 ((RWSpinLock*)t->lock)->unlock(); 1423 } 1424 } 1425 return 0; 1426 }