Returns the node that holds the indicated key if it exists. When it does not * exist, it returns either NULL (when data_when_new is NULL), or it returns a * new node with its node->data set to the indicated value. * * If your code doesn't know the data value for a new node in advance (usually * because it doesn't know if a node is new or not) you should pass in a unique * (non-0) value that
| 78 | * This return is a void* just because it might be pointing at a ht_int32_node |
| 79 | * or a ht_int64_node, and that makes the caller's assignment a little easier. */ |
| 80 | void *hashtable_find(struct hashtable *tbl, int64 key, void *data_when_new) |
| 81 | { |
| 82 | int key64 = tbl->key64; |
| 83 | struct ht_int32_node *node; |
| 84 | uint32 ndx; |
| 85 | |
| 86 | if (key64 ? key == 0 : (int32)key == 0) { |
| 87 | rprintf(FERROR, "Internal hashtable error: illegal key supplied!\n"); |
| 88 | exit_cleanup(RERR_MESSAGEIO); |
| 89 | } |
| 90 | |
| 91 | if (data_when_new && tbl->entries > HASH_LOAD_LIMIT(tbl->size)) { |
| 92 | void *old_nodes = tbl->nodes; |
| 93 | int size = tbl->size * 2; |
| 94 | int i; |
| 95 | |
| 96 | tbl->nodes = new_array0(char, size * tbl->node_size); |
| 97 | tbl->size = size; |
| 98 | tbl->entries = 0; |
| 99 | |
| 100 | if (DEBUG_GTE(HASH, 1)) { |
| 101 | rprintf(FINFO, "[%s] growing hashtable %lx (size: %d, keys: %d-bit)\n", |
| 102 | who_am_i(), (long)tbl, size, key64 ? 64 : 32); |
| 103 | } |
| 104 | |
| 105 | for (i = size / 2; i-- > 0; ) { |
| 106 | struct ht_int32_node *move_node = HT_NODE(tbl, old_nodes, i); |
| 107 | int64 move_key = HT_KEY(move_node, key64); |
| 108 | if (move_key == 0) |
| 109 | continue; |
| 110 | if (move_node->data) |
| 111 | hashtable_find(tbl, move_key, move_node->data); |
| 112 | else { |
| 113 | node = hashtable_find(tbl, move_key, ""); |
| 114 | node->data = 0; |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | free(old_nodes); |
| 119 | } |
| 120 | |
| 121 | if (!key64) { |
| 122 | /* Based on Jenkins One-at-a-time hash. */ |
| 123 | uchar buf[4], *keyp = buf; |
| 124 | int i; |
| 125 | |
| 126 | SIVALu(buf, 0, key); |
| 127 | for (ndx = 0, i = 0; i < 4; i++) { |
| 128 | ndx += keyp[i]; |
| 129 | ndx += (ndx << 10); |
| 130 | ndx ^= (ndx >> 6); |
| 131 | } |
| 132 | ndx += (ndx << 3); |
| 133 | ndx ^= (ndx >> 11); |
| 134 | ndx += (ndx << 15); |
| 135 | } else { |
| 136 | /* Based on Jenkins hashword() from lookup3.c. */ |
| 137 | uint32 a, b, c; |
no test coverage detected