/* First try to search it in cache */
elt = storage->cache->lookup_func (storage->cache, key);
if (elt) {
+ storage->cache->steal_func (storage->cache, elt);
if (elt->flags & KV_ELT_DIRTY) {
/* Element is in backend storage queue */
elt->flags |= KV_ELT_NEED_FREE;
cache_replace replace_func; /*< this callback is called when element is replace */
cache_lookup lookup_func; /*< this callback is used for lookup of element */
cache_delete delete_func; /*< this callback is called when an element is deleted */
+ cache_steal steal_func; /*< this callback is used to replace duplicates in cache */
cache_destroy destroy_func; /*< this callback is used for destroying all elements inside cache */
GHashTable *hash;
};
return elt;
}
+/**
+ * Steal an element from cache
+ */
+static void
+rspamd_kv_hash_steal (struct rspamd_kv_cache *c, struct rspamd_kv_element *elt)
+{
+ struct rspamd_kv_hash_cache *cache = (struct rspamd_kv_hash_cache *)c;
+
+ g_hash_table_steal (cache->hash, ELT_KEY (elt));
+}
+
/**
* Destroy the whole cache
*/
new->lookup_func = rspamd_kv_hash_lookup;
new->replace_func = rspamd_kv_hash_replace;
new->delete_func = rspamd_kv_hash_delete;
+ new->steal_func = rspamd_kv_hash_steal;
new->destroy_func = rspamd_kv_hash_destroy;
return (struct rspamd_kv_cache *)new;
cache_replace replace_func; /*< this callback is called when element is replace */
cache_lookup lookup_func; /*< this callback is used for lookup of element */
cache_delete delete_func; /*< this callback is called when an element is deleted */
+ cache_steal steal_func; /*< this callback is used to replace duplicates in cache */
cache_destroy destroy_func; /*< this callback is used for destroying all elements inside cache */
radix_tree_t *tree;
};
return elt;
}
+/**
+ * Delete an element from cache
+ */
+static void
+rspamd_kv_radix_steal (struct rspamd_kv_cache *c, struct rspamd_kv_element *elt)
+{
+ struct rspamd_kv_radix_cache *cache = (struct rspamd_kv_radix_cache *)c;
+ guint32 rkey = rspamd_kv_radix_validate (ELT_KEY (elt));
+
+
+ radix32tree_delete (cache->tree, rkey, 0xffffffff);
+}
+
/**
* Destroy the whole cache
*/
new->lookup_func = rspamd_kv_radix_lookup;
new->replace_func = rspamd_kv_radix_replace;
new->delete_func = rspamd_kv_radix_delete;
+ new->steal_func = rspamd_kv_radix_steal;
new->destroy_func = rspamd_kv_radix_destroy;
return (struct rspamd_kv_cache *)new;
typedef gboolean (*cache_replace)(struct rspamd_kv_cache *cache, gpointer key, struct rspamd_kv_element *elt);
typedef struct rspamd_kv_element* (*cache_lookup)(struct rspamd_kv_cache *cache, gpointer key);
typedef struct rspamd_kv_element* (*cache_delete)(struct rspamd_kv_cache *cache, gpointer key);
+typedef void (*cache_steal)(struct rspamd_kv_cache *cache, struct rspamd_kv_element* elt);
typedef void (*cache_destroy)(struct rspamd_kv_cache *cache);
/* Callbacks for backend */
cache_replace replace_func; /*< this callback is called when element is replace */
cache_lookup lookup_func; /*< this callback is used for lookup of element */
cache_delete delete_func; /*< this callback is called when an element is deleted */
+ cache_steal steal_func; /*< this callback is used to replace duplicates in cache */
cache_destroy destroy_func; /*< this callback is used for destroying all elements inside cache */
};
struct rspamd_kv_backend {