5 static void remove_entry(flxCache *c, flxCacheEntry *e, gboolean remove_from_hash_table) {
9 if (remove_from_hash_table) {
11 t = g_hash_table_lookup(c->hash_table, &e->record->key);
12 FLX_LLIST_REMOVE(flxCacheEntry, by_name, t, e);
14 g_hash_table_replace(c->hash_table, &t->record->key, t);
16 g_hash_table_remove(c->hash_table, &e->record->key);
19 flx_record_unref(e->record);
23 flxCache *flx_cache_new(flxServer *server, flxInterface *iface) {
27 c = g_new(flxCache, 1);
30 c->hash_table = g_hash_table_new((GHashFunc) flx_key_hash, (GEqualFunc) flx_key_equal);
35 gboolean remove_func(gpointer key, gpointer value, gpointer user_data) {
36 flxCacheEntry *e, *next;
38 for (e = value; e; e = next) {
39 next = e->by_name_next;
40 remove_entry(user_data, e, FALSE);
46 void flx_cache_free(flxCache *c) {
49 g_hash_table_foreach_remove(c->hash_table, remove_func, c);
50 g_hash_table_destroy(c->hash_table);
55 flxCacheEntry *flx_cache_lookup_key(flxCache *c, flxKey *k) {
59 return g_hash_table_lookup(c->hash_table, k);
62 flxCacheEntry *flx_cache_lookup_record(flxCache *c, flxRecord *r) {
67 for (e = flx_cache_lookup_key(c, r->key); e; e = e->by_name_next)
68 if (e->record->size == r->size && !memcmp(e->record->data, r->data, r->size))
74 flxCacheEntry *flx_cache_update(flxCache *c, flxRecord *r, gboolean unique, const flxAddress *a) {
80 if ((t = e = flx_cache_lookup_key(c, r->key))) {
84 /* Drop all entries but the first which we replace */
86 while (e->by_name_next)
87 remove_entry(c, e->by_name_next, TRUE);
89 g_free(e->record->data);
90 e->record->data = g_memdup(r->data, r->size);
91 e->record->size = r->size;
92 e->record->ttl = r->ttl;
95 /* Look for exactly the same entry */
97 for (; e; e = e->by_name_next) {
98 if (e->record->size == r->size &&
99 !memcmp(e->record->data, r->data, r->size)) {
101 /* We found it, so let's update the TTL */
102 e->record->ttl = r->ttl;
110 /* No entry found, therefore we create a new one */
112 e = g_new(flxCacheEntry, 1);
115 e->record = flx_record_ref(r);
116 FLX_LLIST_PREPEND(flxCacheEntry, by_name, t, e);
117 g_hash_table_replace(c->hash_table, e->record->key, e);
122 g_get_current_time(&e->timestamp);
123 e->expiry = e->timestamp;
124 g_time_val_add(&e->expiry, e->record->ttl * 1000000);
126 e->state = FLX_CACHE_VALID;
131 void flx_cache_drop_key(flxCache *c, flxKey *k) {
137 while ((e = flx_cache_lookup_key(c, k)))
138 remove_entry(c, e, TRUE);
141 void flx_cache_drop_record(flxCache *c, flxRecord *r) {
147 if ((e = flx_cache_lookup_record(c, r)))
148 remove_entry(c, e, TRUE);