diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/kvstorage.c | 30 | ||||
-rw-r--r-- | src/kvstorage.h | 6 | ||||
-rw-r--r-- | src/kvstorage_bdb.c | 28 | ||||
-rw-r--r-- | src/kvstorage_server.c | 6 |
4 files changed, 40 insertions, 30 deletions
diff --git a/src/kvstorage.c b/src/kvstorage.c index ef774dd7d..f1862f275 100644 --- a/src/kvstorage.c +++ b/src/kvstorage.c @@ -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); } diff --git a/src/kvstorage.h b/src/kvstorage.h index d13e93079..5a5f8f8ff 100644 --- a/src/kvstorage.h +++ b/src/kvstorage.h @@ -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 */ }; diff --git a/src/kvstorage_bdb.c b/src/kvstorage_bdb.c index fb1a34a83..6e82c502d 100644 --- a/src/kvstorage_bdb.c +++ b/src/kvstorage_bdb.c @@ -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); diff --git a/src/kvstorage_server.c b/src/kvstorage_server.c index afdc8b163..50497f919 100644 --- a/src/kvstorage_server.c +++ b/src/kvstorage_server.c @@ -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, |