extern BOOL table_define(table_t table, void *key, void *value) { table_entry_t entry = table_find(table, key, 1 /* skip deleted */); if (entry != NULL && entry->status == TABLE_ACTIVE) { return FALSE; } if (entry == NULL) { BOOL res; entry = table_find(table, key, 0 /* do not skip deletions */); if (entry == NULL) { /* table is full. Must grow the table to make room. */ res = table_grow(table); if (res != TRUE) return res; entry = table_find(table, key, 0 /* do not skip deletions */); } } assert(entry != NULL && entry->status != TABLE_ACTIVE); entry->status = TABLE_ACTIVE; entry->key = key; entry->value = value; ++table->count; return TRUE; }
void lruhash_insert(struct lruhash *table, hashvalue_t hash, struct lruhash_entry *entry, void *data) { struct lruhash_bucket *bucket; struct lruhash_entry *found, *reclaimlist=NULL; size_t need_size; need_size = table->sizefunc(entry->key, data); //find bucket lock_basic_lock(&table->lock); bucket = &table->array[hash & table->size_mask]; //see if entry exists if(!(found=bucket_find_entry(table, bucket, hash, entry->key))) { //if not found: add to bucket entry->overflow_next = bucket->overflow_list; bucket->overflow_list = entry; lru_front(table, entry); table->num++; table->space_used += need_size; } else { //if found: update data table->space_used += need_size - (*table->sizefunc)(found->key, found->data); (*table->delkeyfunc)(entry->key); lru_touch(table, found); lock_basic_lock(&found->lock); (*table->deldatafunc)(found->data); found->data = data; lock_basic_unlock(&found->lock); } if(table->space_used > table->space_max) reclaim_space(table, &reclaimlist); if(table->num >= table->size) table_grow(table); lock_basic_unlock(&table->lock); //del reclaim without lock while(reclaimlist) { struct lruhash_entry *n = reclaimlist->overflow_next; void *d = reclaimlist->data; (*table->delkeyfunc)(reclaimlist->key); (*table->deldatafunc)(d); reclaimlist = n; } }
int table_set(table *t, void *v) { uint h, b, len=0; tlink *n, *cur, *tail = NULL; int status = 0; assert(v); assert(t); h = t->hash(v); b = h % t->sz; n = ALLOC(sizeof(tlink)); n->next = NULL; n->v = v; /* If the table is already at the max size, just put it at the * head, don't bother walking the whole chain. */ if (t->sz == t->ms) { cur = t->b[b]; t->b[b] = n; n->next = cur; return TABLE_SET | TABLE_FULL; } /* Otherwise, note the length, to see if it's time to resize. */ for (cur = t->b[b]; cur != NULL; cur=cur->next) { len++; tail = cur; } if (tail) { tail->next = n; } else { t->b[b] = n; } status |= TABLE_SET; if (len > t->mcl) { status |= table_grow(t); if (DEBUG) table_stats(t, 0); } return status; }