123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- /* Copyright (c) 2011, Vsevolod Stakhov
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- #ifndef KVSTORAGE_H_
- #define KVSTORAGE_H_
-
- #include "config.h"
-
- struct rspamd_kv_cache;
- struct rspamd_kv_backend;
- struct rspamd_kv_storage;
- struct rspamd_kv_expire;
- struct rspamd_kv_element;
-
- /* Locking definitions */
- #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30))
- #define RW_R_LOCK g_rw_lock_reader_lock
- #define RW_R_UNLOCK g_rw_lock_reader_unlock
- #define RW_W_LOCK g_rw_lock_writer_lock
- #define RW_W_UNLOCK g_rw_lock_writer_unlock
- #else
- #define RW_R_LOCK g_static_rw_lock_reader_lock
- #define RW_R_UNLOCK g_static_rw_lock_reader_unlock
- #define RW_W_LOCK g_static_rw_lock_writer_lock
- #define RW_W_UNLOCK g_static_rw_lock_writer_unlock
- #endif
-
- /* Callbacks for cache */
- typedef void (*cache_init)(struct rspamd_kv_cache *cache);
- typedef struct rspamd_kv_element * (*cache_insert)(struct rspamd_kv_cache *cache,
- gpointer key, guint keylen, gpointer value, gsize len);
- typedef gboolean (*cache_replace)(struct rspamd_kv_cache *cache, gpointer key,
- guint keylen,
- struct rspamd_kv_element *elt);
- typedef struct rspamd_kv_element * (*cache_lookup)(struct rspamd_kv_cache *cache,
- gpointer key, guint keylen);
- typedef struct rspamd_kv_element * (*cache_delete)(struct rspamd_kv_cache *cache,
- gpointer key, guint keylen);
- 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 */
- typedef void (*backend_init)(struct rspamd_kv_backend *backend);
- typedef gboolean (*backend_insert)(struct rspamd_kv_backend *backend,
- gpointer key, guint keylen,
- struct rspamd_kv_element *elt);
- typedef gboolean (*backend_replace)(struct rspamd_kv_backend *backend,
- gpointer key, guint keylen,
- struct rspamd_kv_element *elt);
- typedef struct rspamd_kv_element * (*backend_lookup)(struct rspamd_kv_backend *
- backend, gpointer key,
- guint keylen);
- typedef void (*backend_delete)(struct rspamd_kv_backend *backend, gpointer key,
- guint keylen);
- typedef gboolean (*backend_sync)(struct rspamd_kv_backend *backend);
- typedef gboolean (*backend_incref)(struct rspamd_kv_backend *backend,
- gpointer key, guint keylen);
- typedef void (*backend_destroy)(struct rspamd_kv_backend *backend);
-
- /* Callbacks for expire */
- typedef void (*expire_init)(struct rspamd_kv_expire *expire);
- typedef void (*expire_insert)(struct rspamd_kv_expire *expire,
- struct rspamd_kv_element *elt);
- typedef void (*expire_delete)(struct rspamd_kv_expire *expire,
- struct rspamd_kv_element *elt);
- typedef gboolean (*expire_step)(struct rspamd_kv_expire *expire,
- struct rspamd_kv_storage *storage,
- time_t now, gboolean forced);
- typedef void (*expire_destroy)(struct rspamd_kv_expire *expire);
-
-
- /* Flags of element */
- enum rspamd_kv_flags {
- KV_ELT_ARRAY = 1 << 0,
- KV_ELT_PERSISTENT = 1 << 1,
- KV_ELT_DIRTY = 1 << 2,
- KV_ELT_OUSTED = 1 << 3,
- KV_ELT_NEED_FREE = 1 << 4,
- KV_ELT_INTEGER = 1 << 5,
- KV_ELT_NEED_INSERT = 1 << 6,
- KV_ELT_NEED_EXPIRE = 1 << 7
- };
-
- #define ELT_DATA(elt) (gchar *)(elt)->data + (elt)->keylen + 1
- #define ELT_LONG(elt) *((glong *)((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 {
- time_t age; /*< age of element */
- guint32 expire; /*< expire of element */
- gint flags; /*< element flags */
- gsize size; /*< size of element */
- TAILQ_ENTRY (rspamd_kv_element) entry; /*< list entry */
- guint keylen; /*< length of key */
-
- gpointer p; /*< pointer to data */
- gchar data[1]; /*< expandable data */
- };
-
- struct rspamd_kv_cache {
- cache_init init_func; /*< this callback is called on kv storage initialization */
- cache_insert insert_func; /*< this callback is called when element is inserted */
- 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 {
- backend_init init_func; /*< this callback is called on kv storage initialization */
- backend_insert insert_func; /*< this callback is called when element is inserted */
- backend_replace replace_func; /*< this callback is called when element is replaced */
- backend_lookup lookup_func; /*< this callback is used for lookup of element */
- backend_delete delete_func; /*< this callback is called when an element is deleted */
- backend_sync sync_func; /*< this callback is called when backend need to be synced */
- backend_incref incref_func; /*< this callback is called when element must be ref'd */
- backend_destroy destroy_func; /*< this callback is used for destroying all elements inside backend */
- };
- struct rspamd_kv_expire {
- expire_init init_func; /*< this callback is called on kv storage initialization */
- expire_insert insert_func; /*< this callback is called when element is inserted */
- expire_step step_func; /*< this callback is used when cache is full */
- expire_delete delete_func; /*< this callback is called when an element is deleted */
- expire_destroy destroy_func; /*< this callback is used for destroying all elements inside expire */
- };
-
- /* Main kv storage structure */
-
- struct rspamd_kv_storage {
- struct rspamd_kv_cache *cache;
- struct rspamd_kv_backend *backend;
- struct rspamd_kv_expire *expire;
-
- gsize elts; /*< current elements count in a storage */
- gsize max_elts; /*< maximum number of elements in a storage */
-
- gsize memory; /*< memory eaten */
- gsize max_memory; /*< memory limit */
-
- gint id; /* char ID */
- gchar *name; /* numeric ID */
-
- gboolean no_overwrite; /* do not overwrite data with the same keys */
- #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION > 30))
- GRWLock rwlock; /* rwlock in new glib */
- #else
- GStaticRWLock rwlock; /* rwlock for threaded access */
- #endif
- };
-
- /** Create new kv storage */
- struct rspamd_kv_storage * rspamd_kv_storage_new (gint id, const gchar *name,
- struct rspamd_kv_cache *cache, struct rspamd_kv_backend *backend,
- struct rspamd_kv_expire *expire,
- gsize max_elts, gsize max_memory, gboolean no_overwrite);
-
- /** Insert new element to the kv storage */
- gboolean rspamd_kv_storage_insert (struct rspamd_kv_storage *storage,
- gpointer key,
- guint keylen,
- gpointer data,
- gsize len,
- gint flags,
- guint expire);
-
- /** Insert element only in cache */
- gboolean rspamd_kv_storage_insert_cache (struct rspamd_kv_storage *storage,
- gpointer key,
- guint keylen,
- gpointer data,
- gsize len,
- gint flags,
- guint expire,
- struct rspamd_kv_element **pelt);
-
- /** Replace an element in the kv storage */
- gboolean rspamd_kv_storage_replace (struct rspamd_kv_storage *storage,
- gpointer key,
- guint keylen,
- struct rspamd_kv_element *elt);
-
- /** Increment value in kvstorage */
- gboolean rspamd_kv_storage_increment (struct rspamd_kv_storage *storage,
- gpointer key,
- guint keylen,
- glong *value);
-
- /** Lookup an element inside kv storage */
- struct rspamd_kv_element * rspamd_kv_storage_lookup (
- struct rspamd_kv_storage *storage,
- gpointer key,
- guint keylen,
- time_t now);
-
- /** Expire an element from kv storage */
- struct rspamd_kv_element * rspamd_kv_storage_delete (
- struct rspamd_kv_storage *storage,
- gpointer key,
- guint keylen);
-
- /** Destroy kv storage */
- void rspamd_kv_storage_destroy (struct rspamd_kv_storage *storage);
-
- /** Insert array */
- gboolean rspamd_kv_storage_insert_array (struct rspamd_kv_storage *storage,
- gpointer key,
- guint keylen,
- guint elt_size,
- gpointer data,
- gsize len,
- gint flags,
- guint expire);
-
- /** Set element inside array */
- gboolean rspamd_kv_storage_set_array (struct rspamd_kv_storage *storage,
- gpointer key,
- guint keylen,
- guint elt_num,
- gpointer data,
- gsize len,
- time_t now);
-
- /** Get element inside array */
- gboolean rspamd_kv_storage_get_array (struct rspamd_kv_storage *storage,
- gpointer key,
- guint keylen,
- guint elt_num,
- gpointer *data,
- gsize *len,
- time_t now);
-
- /* Hash table functions */
- guint kv_elt_hash_func (gconstpointer e);
- gboolean kv_elt_compare_func (gconstpointer e1, gconstpointer e2);
-
- /**
- * LRU expire
- */
- struct rspamd_kv_expire * rspamd_lru_expire_new (void);
-
- /**
- * Ordinary hash
- */
- struct rspamd_kv_cache * rspamd_kv_hash_new (void);
-
- /**
- * Radix tree
- */
- struct rspamd_kv_cache * rspamd_kv_radix_new (void);
-
- #ifdef WITH_JUDY
- /**
- * Judy tree
- */
- struct rspamd_kv_cache * rspamd_kv_judy_new (void);
- #endif
-
- #endif /* KVSTORAGE_H_ */
|