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  }