]> source.dussan.org Git - rspamd.git/commitdiff
Store keys inside elements.
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 1 Nov 2011 18:39:54 +0000 (21:39 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 1 Nov 2011 18:39:54 +0000 (21:39 +0300)
src/kvstorage.c
src/kvstorage.h
src/kvstorage_bdb.c
src/kvstorage_server.c

index ef774dd7da99fe54d7bf60c726a5ccb46eb5e0c4..f1862f27500b5160ccd86a26752b465b264305a8 100644 (file)
@@ -237,7 +237,8 @@ rspamd_kv_storage_lookup (struct rspamd_kv_storage *storage, gpointer key, time_
                belt = storage->backend->lookup_func (storage->backend, key);
                if (belt) {
                        /* Put this element into cache */
-                       rspamd_kv_storage_insert_internal (storage, belt->key, belt->data, belt->size, belt->flags,
+                       rspamd_kv_storage_insert_internal (storage, ELT_KEY (belt), ELT_DATA (belt),
+                                       belt->size, belt->flags,
                                        belt->expire, &elt);
                        if ((belt->flags & KV_ELT_DIRTY) == 0) {
                                g_free (belt);
@@ -466,14 +467,14 @@ rspamd_lru_expire_step (struct rspamd_kv_expire *e, struct rspamd_kv_storage *st
                        }
                        else {
                                /* This element is already expired */
-                               rspamd_kv_storage_delete (storage, elt->key);
+                               rspamd_kv_storage_delete (storage, ELT_KEY (elt));
                                res = TRUE;
                                /* Check other elements in this queue */
                                TAILQ_FOREACH_SAFE (elt, &expire->heads[i], entry, temp) {
                                        if ((elt->flags & KV_ELT_PERSISTENT) != 0 || elt->expire < (now - elt->age)) {
                                                break;
                                        }
-                                       rspamd_kv_storage_delete (storage, elt->key);
+                                       rspamd_kv_storage_delete (storage, ELT_KEY (elt));
                                }
                                break;
                        }
@@ -482,7 +483,7 @@ rspamd_lru_expire_step (struct rspamd_kv_expire *e, struct rspamd_kv_storage *st
 
        if (!res) {
                /* Oust the oldest element from cache */
-               storage->cache->delete_func (storage->cache, oldest_elt->key);
+               storage->cache->delete_func (storage->cache, ELT_KEY (oldest_elt));
                oldest_elt->flags |= KV_ELT_OUSTED;
                storage->memory -= oldest_elt->size + sizeof (*elt);
                storage->elts --;
@@ -554,15 +555,18 @@ rspamd_kv_hash_insert (struct rspamd_kv_cache *c, gpointer key, gpointer value,
 {
        struct rspamd_kv_element                        *elt;
        struct rspamd_kv_hash_cache                     *cache = (struct rspamd_kv_hash_cache *)c;
+       guint                                                            keylen;
 
        if ((elt = g_hash_table_lookup (cache->hash, key)) == NULL) {
-               elt = g_slice_alloc0 (sizeof (struct rspamd_kv_element) + len);
+               keylen = strlen (key);
+               elt = g_slice_alloc0 (sizeof (struct rspamd_kv_element) + len + keylen + 1);
                elt->age = time (NULL);
-               elt->key = key;
+               elt->keylen = keylen;
                elt->size = len;
                elt->hash = rspamd_strcase_hash (key);
-               memcpy (elt->data, value, len);
-               g_hash_table_insert (cache->hash, key, elt);
+               memcpy (elt->data, key, keylen + 1);
+               memcpy (ELT_DATA (elt), value, len);
+               g_hash_table_insert (cache->hash, ELT_KEY (elt), elt);
        }
 
        return elt;
@@ -639,7 +643,7 @@ rspamd_kv_hash_new (void)
        struct rspamd_kv_hash_cache                     *new;
 
        new = g_slice_alloc (sizeof (struct rspamd_kv_hash_cache));
-       new->hash = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal, NULL, kv_elt_destroy_func);
+       new->hash = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal, NULL, NULL);
        new->init_func = NULL;
        new->insert_func = rspamd_kv_hash_insert;
        new->lookup_func = rspamd_kv_hash_lookup;
@@ -687,18 +691,20 @@ rspamd_kv_radix_insert (struct rspamd_kv_cache *c, gpointer key, gpointer value,
        struct rspamd_kv_element                        *elt;
        struct rspamd_kv_radix_cache            *cache = (struct rspamd_kv_radix_cache *)c;
        guint32                                                          rkey = rspamd_kv_radix_validate (key);
+       guint                                                            keylen;
 
        if (rkey == 0) {
                return NULL;
        }
        elt = (struct rspamd_kv_element *)radix32tree_find (cache->tree, rkey);
        if ((uintptr_t)elt == RADIX_NO_VALUE) {
-               elt = g_slice_alloc0 (sizeof (struct rspamd_kv_element) + len);
+               keylen = strlen (key);
+               elt = g_slice_alloc0 (sizeof (struct rspamd_kv_element) + len + keylen + 1);
                elt->age = time (NULL);
-               elt->key = key;
                elt->size = len;
                elt->hash = rkey;
-               memcpy (elt->data, value, len);
+               memcpy (elt->data, key, keylen + 1);
+               memcpy (ELT_DATA (elt), value, len);
                radix32tree_insert (cache->tree, rkey, 0xffffffff, (uintptr_t)elt);
        }
 
index d13e93079de992b0de4dac20123b7ee558f1a121..5a5f8f8ffd799f73b18d7ce4a91500cf955e9432 100644 (file)
@@ -64,6 +64,10 @@ enum rspamd_kv_flags {
        KV_ELT_OUSTED = 1 << 3
 };
 
+#define ELT_DATA(elt) (gchar *)(elt)->data + (elt)->keylen + 1
+#define ELT_KEY(elt) (gchar *)(elt)->data
+#define ELT_SIZE(elt) elt->size + sizeof(struct rspamd_kv_element) + elt->keylen + 1
+
 /* Common structures description */
 
 struct rspamd_kv_element {
@@ -73,7 +77,7 @@ struct rspamd_kv_element {
        gsize size;                                                                     /*< size of element */
        TAILQ_ENTRY (rspamd_kv_element) entry;          /*< list entry */
        guint32 hash;                                                           /*< numeric hash */
-       gpointer key;                                                           /*< pointer to key */
+       guint keylen;                                                           /*< length of key */
 
        gchar data[1];                                                          /*< expandable data */
 };
index fb1a34a83cc1e41adac3b6d9dfed6bf867c8c283..6e82c502db8e9f91cac2a6b303ea3d3cb9c0362f 100644 (file)
@@ -64,9 +64,10 @@ bdb_process_single_op (struct rspamd_bdb_backend *db, DB_TXN *txn, DBC *cursorp,
 
        memset (&db_key, 0, sizeof(DBT));
        memset (&db_data, 0, sizeof(DBT));
-       db_key.size = strlen (op->elt->key);
-       db_key.data = op->elt->key;
-       db_data.size = op->elt->size + sizeof (struct rspamd_kv_element);
+
+       db_key.size = op->elt->keylen;
+       db_key.data = ELT_KEY (op->elt);
+       db_data.size = op->elt->size + sizeof (struct rspamd_kv_element) + op->elt->keylen + 1;
        db_data.data = op->elt;
 
        switch (op->op) {
@@ -101,7 +102,7 @@ bdb_process_queue (struct rspamd_bdb_backend *db)
        struct bdb_op                                                           *op;
        DBC                                                                             *cursorp;
        DB_TXN                                                                          *txn = NULL;
-       GList                                                                           *cur, *tmp;
+       GList                                                                           *cur;
 
        /* Start transaction */
        if (db->envp->txn_begin (db->envp, NULL, &txn, 0) != 0) {
@@ -132,17 +133,17 @@ bdb_process_queue (struct rspamd_bdb_backend *db)
        cur = db->ops_queue->head;
        while (cur) {
                op = cur->data;
-               tmp = cur;
-               g_hash_table_remove (db->ops_hash, op->elt->key);
                if (op->op == BDB_OP_DELETE) {
                        /* Also clean memory */
-                       g_slice_free1 (sizeof (struct rspamd_kv_element) + op->elt->size, op->elt);
+                       g_slice_free1 (ELT_SIZE (op->elt), op->elt);
                }
-               cur = g_list_next (cur);
-               g_queue_delete_link (db->ops_queue, tmp);
                g_slice_free1 (sizeof (struct bdb_op), op);
+               cur = g_list_next (cur);
        }
 
+       g_hash_table_remove_all (db->ops_hash);
+       g_queue_clear (db->ops_queue);
+
        return TRUE;
 
 }
@@ -219,7 +220,7 @@ rspamd_bdb_insert (struct rspamd_kv_backend *backend, gpointer key, struct rspam
        elt->flags |= KV_ELT_DIRTY;
 
        g_queue_push_head (db->ops_queue, op);
-       g_hash_table_insert (db->ops_hash, key, op);
+       g_hash_table_insert (db->ops_hash, ELT_KEY (elt), op);
 
        if (g_queue_get_length (db->ops_queue) >= db->sync_ops) {
                return bdb_process_queue (db);
@@ -244,7 +245,7 @@ rspamd_bdb_replace (struct rspamd_kv_backend *backend, gpointer key, struct rspa
        elt->flags |= KV_ELT_DIRTY;
 
        g_queue_push_head (db->ops_queue, op);
-       g_hash_table_insert (db->ops_hash, key, op);
+       g_hash_table_insert (db->ops_hash, ELT_KEY (elt), op);
 
        if (g_queue_get_length (db->ops_queue) >= db->sync_ops) {
                return bdb_process_queue (db);
@@ -286,7 +287,6 @@ rspamd_bdb_lookup (struct rspamd_kv_backend *backend, gpointer key)
 
        if (cursorp->get (cursorp, &db_key, &db_data, DB_SET) == 0) {
                elt = db_data.data;
-               elt->key = key;
                elt->flags &= ~KV_ELT_DIRTY;
        }
 
@@ -319,8 +319,8 @@ rspamd_bdb_delete (struct rspamd_kv_backend *backend, gpointer key)
        op->elt = elt;
        elt->flags |= KV_ELT_DIRTY;
 
-       g_queue_push_head (db->ops_queue, elt);
-       g_hash_table_insert (db->ops_hash, key, elt);
+       g_queue_push_head (db->ops_queue, op);
+       g_hash_table_insert (db->ops_hash, ELT_KEY(elt), op);
 
        if (g_queue_get_length (db->ops_queue) >= db->sync_ops) {
                bdb_process_queue (db);
index afdc8b1631052365c0f8e80b5475676f4bea28ad..50497f919989e981f6f26f5f0c7ce2442a216920 100644 (file)
@@ -353,12 +353,12 @@ kvstorage_read_socket (f_str_t * in, void *arg)
                                }
                                else {
                                        r = rspamd_snprintf (outbuf, sizeof (outbuf), "VALUE %s %ud %ud" CRLF,
-                                                       elt->key, elt->flags, elt->size);
+                                                       ELT_KEY (elt), elt->flags, elt->size);
                                        if (!rspamd_dispatcher_write (session->dispather, outbuf,
                                                                                                                                r, TRUE, FALSE)) {
                                                return FALSE;
                                        }
-                                       if (!rspamd_dispatcher_write (session->dispather, elt->data, elt->size, TRUE, TRUE)) {
+                                       if (!rspamd_dispatcher_write (session->dispather, ELT_DATA(elt), elt->size, TRUE, TRUE)) {
                                                return FALSE;
                                        }
                                        return rspamd_dispatcher_write (session->dispather, CRLF "END" CRLF,
@@ -371,7 +371,7 @@ kvstorage_read_socket (f_str_t * in, void *arg)
                                if (elt != NULL) {
                                        if ((elt->flags & KV_ELT_DIRTY) == 0) {
                                                /* Free memory if backend has deleted this element */
-                                               g_slice_free1 (elt->size + sizeof (struct rspamd_kv_element), elt);
+                                               g_slice_free1 (ELT_SIZE (elt), elt);
                                        }
                                        g_static_rw_lock_writer_unlock (&session->cf->storage->rwlock);
                                        return rspamd_dispatcher_write (session->dispather, "DELETED" CRLF,