const char * metacache_add_string (const char *str) { // printf ("n_strings=%d, n_inserts=%d, n_buckets=%d\n", n_strings, n_inserts, n_buckets); uint32_t h = metacache_get_hash_sdbm (str); metacache_str_t *data = metacache_find_in_bucket (h % HASH_SIZE, str); n_inserts++; if (data) { data->refcount++; return data->str; } metacache_hash_t *bucket = &hash[h % HASH_SIZE]; if (!bucket->chain) { n_buckets++; } size_t len = strlen (str); data = malloc (sizeof (metacache_str_t) + len); memset (data, 0, sizeof (metacache_str_t) + len); data->refcount = 1; memcpy (data->str, str, len+1); data->next = bucket->chain; bucket->chain = data; n_strings++; return data->str; }
void metacache_remove_string (const char *str) { uint32_t h = metacache_get_hash_sdbm (str); metacache_hash_t *bucket = &hash[h % HASH_SIZE]; metacache_str_t *chain = bucket->chain; metacache_str_t *prev = NULL; while (chain) { if (!strcmp (chain->str, str)) { chain->refcount--; if (chain->refcount == 0) { if (prev) { prev->next = chain->next; } else { bucket->chain = chain->next; } free (chain); } break; } prev = chain; chain = chain->next; } }
void metacache_remove_value (const char *value, size_t valuesize) { uint32_t h = metacache_get_hash_sdbm (value, valuesize); metacache_hash_t *bucket = &hash[h % HASH_SIZE]; metacache_str_t *chain = bucket->chain; metacache_str_t *prev = NULL; while (chain) { if (chain->value_length == valuesize && !memcmp (chain->str, value, valuesize)) { chain->refcount--; if (chain->refcount == 0) { if (prev) { prev->next = chain->next; } else { bucket->chain = chain->next; } free (chain); } break; } prev = chain; chain = chain->next; } }