static table_entry_t table_find(table_t table, void *key, int skip_deleted) { ulong hash; size_t i; hash = table_hash(key) & (table->length - 1); i = hash; do { switch (table->array[i].status) { case TABLE_ACTIVE: if (table->array[i].key == key) { return &table->array[i]; } break; case TABLE_DELETED: if (!skip_deleted) { return &table->array[i]; } break; case TABLE_UNUSED: return &table->array[i]; break; default: assert(0); } i = (i + (hash | 1)) & (table->length - 1); } while (i != hash); return NULL; }
xsbBucket *search_bucket(Cell name, xsbHashTable *table, enum xsbHashSearchOp search_op) { xsbBucket *bucket, *prev; if (! table->initted) init_hashtable(table); prev = NULL; bucket = get_top_bucket(table,table_hash(name,table->length)); while (bucket && bucket->name) { if (bucket->name == name) { if (search_op == hashtable_delete) { if (!prev) { /* if deleting a top bucket, copy the next bucket into the top one and delete that next bucket. If no next, then just nullify name */ prev = bucket; bucket=bucket->next; if (bucket) { /* use memcpy() because client bucket might have extra fields */ memcpy(prev, bucket, table->bucket_size); free(bucket); } else { mark_bucket_free(prev,table->bucket_size); xsb_dbgmsg((LOG_HASHTABLE, "SEARCH_BUCKET: Destroying storage handle for %s\n", string_val(name))); xsb_dbgmsg((LOG_HASHTABLE, "SEARCH_BUCKET: Bucket nameptr is %p, next bucket %p\n", prev->name, prev->next)); } } else { /* Not top bucket: rearrange pointers & free space */ prev->next = bucket->next; free(bucket); } return NULL; } else return bucket; } prev = bucket; bucket = bucket->next; } /* not found */ if (search_op != hashtable_insert) return NULL; /* else create new bucket */ /* calloc nullifies the allocated space; CLIENTS RELY ON THIS */ if (!bucket) { /* i.e., it is not a top bucket */ bucket = (xsbBucket *)calloc(1,table->bucket_size); if (!bucket) xsb_exit("Out of Memory: Can't allocate hash bucket"); prev->next = bucket; /* NOTE: not necessary to nullify bucket->next because of calloc() */ } bucket->name = name; return bucket; }
void *table_get(table *t, void *key) { size_t h, i; binding *b; assert(t != NULL); assert(key != NULL); h = table_hash(t, key); for (i = 0; i < t->slotslen; i += 1) { b = t->slots[(h + i) % t->slotslen]; if (b->key == NULL) { return NULL; } else if (table_hash(t, b->key) != h) { return NULL; } else if (!t->cmp(key, b->key)) { return b->value; } } return NULL; }
static size_t table_find (value table, value null, value obj) { size_t mask = table_mask (table); size_t index = table_hash (obj) & mask; while (1) { value v = Field(table, index * 2); if (v == null || v == obj) return index; index = (index + 1) & mask; } }
void *table_put(table *t, void *key, void *value) { size_t h, i; assert(t != NULL); assert(key != NULL); h = table_hash(t, key); for (i = 0; } void **table_to_array(table *t) { assert(t != NULL); return NULL; }