aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kvstorage.c30
-rw-r--r--src/kvstorage.h6
-rw-r--r--src/kvstorage_bdb.c28
-rw-r--r--src/kvstorage_server.c6
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,