int tcam_cache_purge(tcam_cache_t *cache) { int removed = 0; pthread_mutex_lock(&cache->lock); int i, j; cache_entry_t *entry; time_t now = time(NULL); unsigned long used; int trailing_zeros; for(i = 0; i < cache->bitmap_size; i++) { used = cache->bitmap_used[i]; trailing_zeros = __builtin_ctzl(used); for(j = trailing_zeros; j < sizeof(unsigned long); j++) { if(used & (1 << j)){ entry = &cache->entries[sizeof(unsigned long) * i + j]; if ((now - entry->last_access) > cache->expiration_secs) { cache->bitmap_used[i] &= ~(1 << j); tommy_hashtable_remove_existing(&cache->hashtable, &entry->node); removed++; } } } } cache->nb_entries -= removed; pthread_mutex_unlock(&cache->lock); return removed; }
void test_hashtable(void) { tommy_list list; tommy_hashtable hashtable; struct object_hash* HASH; unsigned i, n; tommy_node* p; unsigned limit; unsigned count; HASH = malloc(MAX * sizeof(struct object_hash)); for(i=0;i<MAX;++i) { HASH[i].value = i; } START("hashtable stack"); limit = 10 * sqrt(MAX); for(n=0;n<limit;++n) { tommy_list_init(&list); tommy_hashtable_init(&hashtable, limit / 2); /* insert */ for(i=0;i<n;++i) { tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashtable_insert(&hashtable, &HASH[i].hashnode, &HASH[i], HASH[i].value); } count = 0; tommy_hashtable_foreach_arg(&hashtable, count_arg, &count); if (count != n) abort(); /* remove */ p = tommy_list_head(&list); while (p) { struct object_hash* obj = p->data; p = p->next; tommy_hashtable_remove_existing(&hashtable, &obj->hashnode); } tommy_hashtable_done(&hashtable); } STOP(); START("hashtable queue"); limit = sqrt(MAX) / 8; for(n=0;n<limit;++n) { tommy_list_init(&list); tommy_hashtable_init(&hashtable, limit / 2); /* insert first run */ for(i=0;i<n;++i) { tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashtable_insert(&hashtable, &HASH[i].hashnode, &HASH[i], HASH[i].value); } count = 0; tommy_hashtable_foreach_arg(&hashtable, count_arg, &count); if (count != n) abort(); /* insert all the others */ for(;i<MAX;++i) { struct object_hash* obj; /* insert one */ tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashtable_insert(&hashtable, &HASH[i].hashnode, &HASH[i], HASH[i].value); /* remove one */ p = tommy_list_head(&list); obj = p->data; tommy_list_remove_existing(&list, p); tommy_hashtable_remove_existing(&hashtable, &obj->hashnode); } /* remove remaining */ p = tommy_list_head(&list); while (p) { struct object_hash* obj = p->data; p = p->next; tommy_hashtable_remove_existing(&hashtable, &obj->hashnode); } tommy_hashtable_done(&hashtable); } STOP(); }