aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-04-11 12:26:54 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-04-11 12:26:54 +0100
commite332d676926f23417c1efccdca72470de6008a46 (patch)
tree50c5cb71527e5599c193176072e653b699675e3c
parent401e5b9b11ae0098723639bf241f54e12f8d14c2 (diff)
downloadrspamd-e332d676926f23417c1efccdca72470de6008a46.tar.gz
rspamd-e332d676926f23417c1efccdca72470de6008a46.zip
[Feature] Use less frequent use strategy for caches
-rw-r--r--src/libutil/hash.c34
-rw-r--r--src/libutil/hash.h2
2 files changed, 30 insertions, 6 deletions
diff --git a/src/libutil/hash.c b/src/libutil/hash.c
index fc6c9cda2..30ecdd85b 100644
--- a/src/libutil/hash.c
+++ b/src/libutil/hash.c
@@ -21,9 +21,10 @@
* LRU hashing
*/
+static const guint expire_aggressive_count = 10;
+
struct rspamd_lru_hash_s {
- gint maxsize;
- gint maxage;
+ guint maxsize;
GDestroyNotify value_destroy;
GDestroyNotify key_destroy;
struct rspamd_min_heap *heap;
@@ -47,6 +48,19 @@ rspamd_lru_destroy_node (gpointer value)
}
}
+static inline guint
+rspamd_lru_priority (guint ttl, guint usages)
+{
+ /* 1 day */
+ static const guint max_ttl = 3600 * 24;
+
+ if (ttl > 0 && usages > 0) {
+ return G_MAXUINT / (MIN (max_ttl, ttl) * usages);
+ }
+
+ return G_MAXUINT;
+}
+
static rspamd_lru_element_t *
rspamd_lru_create_node (rspamd_lru_hash_t *hash,
gpointer key,
@@ -62,6 +76,9 @@ rspamd_lru_create_node (rspamd_lru_hash_t *hash,
node->ttl = ttl;
node->helt.pri = now;
node->hash = hash;
+ node->usages = 1;
+ node->storage = now;
+ node->helt.pri = rspamd_lru_priority (ttl, 1);
return node;
}
@@ -112,7 +129,8 @@ rspamd_lru_hash_lookup (rspamd_lru_hash_t *hash, gconstpointer key, time_t now)
}
}
- rspamd_min_heap_update_elt (hash->heap, &res->helt, now);
+ rspamd_min_heap_update_elt (hash->heap, &res->helt,
+ rspamd_lru_priority (res->ttl, ++res->usages));
return res->data;
}
@@ -125,6 +143,7 @@ rspamd_lru_hash_insert (rspamd_lru_hash_t *hash, gpointer key, gpointer value,
time_t now, guint ttl)
{
rspamd_lru_element_t *res;
+ guint i;
res = g_hash_table_lookup (hash->tbl, key);
if (res != NULL) {
@@ -132,9 +151,12 @@ rspamd_lru_hash_insert (rspamd_lru_hash_t *hash, gpointer key, gpointer value,
}
else {
if (hash->maxsize > 0 &&
- (gint)g_hash_table_size (hash->tbl) >= hash->maxsize) {
- res = (rspamd_lru_element_t *)rspamd_min_heap_pop (hash->heap);
- g_hash_table_remove (hash->tbl, res->key);
+ g_hash_table_size (hash->tbl) >= hash->maxsize) {
+
+ for (i = 0; i < MIN (hash->maxsize, expire_aggressive_count); i ++) {
+ res = (rspamd_lru_element_t *)rspamd_min_heap_pop (hash->heap);
+ g_hash_table_remove (hash->tbl, res->key);
+ }
}
}
diff --git a/src/libutil/hash.h b/src/libutil/hash.h
index a7a2a3a26..30c0c99ac 100644
--- a/src/libutil/hash.h
+++ b/src/libutil/hash.h
@@ -16,6 +16,8 @@ typedef struct rspamd_lru_hash_s rspamd_lru_hash_t;
typedef struct rspamd_lru_element_s {
struct rspamd_min_heap_elt helt;
guint ttl;
+ guint usages;
+ time_t storage;
gpointer data;
gpointer key;
rspamd_lru_hash_t *hash;