From 60ead7c24466f0da3f97f331cd4e647d8b819295 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Fri, 17 Nov 2017 14:31:21 -0800 Subject: [PATCH] hash_table: new structure to support counters and eviction modes Signed-off-by: Eduardo Silva --- include/fluent-bit/flb_hash.h | 16 ++++++++++++++-- src/flb_hash.c | 27 ++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/include/fluent-bit/flb_hash.h b/include/fluent-bit/flb_hash.h index d8f3b4c6961..ecc6b861af5 100644 --- a/include/fluent-bit/flb_hash.h +++ b/include/fluent-bit/flb_hash.h @@ -26,12 +26,20 @@ #include #include +/* Eviction modes when the table reach full capacity (if any) */ +#define FLB_HASH_EVICT_NONE 0 +#define FLB_HASH_EVICT_OLDER 1 +#define FLB_HASH_EVICT_LESS_USED 2 + struct flb_hash_entry { + time_t created; + uint64_t hits; char *key; size_t key_len; char *val; size_t val_size; - struct mk_list _head; + struct mk_list _head; /* link to flb_hash_table->chains */ + struct mk_list _head_parent; /* link to flb_hash->entries */ }; struct flb_hash_table { @@ -40,11 +48,15 @@ struct flb_hash_table { }; struct flb_hash { + int evict_mode; + int max_entries; + int total_count; size_t size; + struct mk_list entries; struct flb_hash_table *table; }; -struct flb_hash *flb_hash_create(size_t size); +struct flb_hash *flb_hash_create(int evict_mode, size_t size, int max_entries); void flb_hash_destroy(struct flb_hash *ht); int flb_hash_add(struct flb_hash *ht, char *key, int key_len, diff --git a/src/flb_hash.c b/src/flb_hash.c index a3124fe598b..68591afbc61 100644 --- a/src/flb_hash.c +++ b/src/flb_hash.c @@ -87,12 +87,13 @@ static unsigned int gen_hash(const void *key, int len) static inline void flb_hash_entry_free(struct flb_hash_entry *entry) { mk_list_del(&entry->_head); + mk_list_del(&entry->_head_parent); flb_free(entry->key); flb_free(entry->val); flb_free(entry); } -struct flb_hash *flb_hash_create(size_t size) +struct flb_hash *flb_hash_create(int evict_mode, size_t size, int max_entries) { int i; struct flb_hash_table *tmp; @@ -108,6 +109,10 @@ struct flb_hash *flb_hash_create(size_t size) return NULL; } + mk_list_init(&ht->entries); + ht->evict_mode = evict_mode; + ht->max_entries = max_entries; + ht->total_count = 0; ht->size = size; ht->table = flb_calloc(1, sizeof(struct flb_hash_table) * size); if (!ht->table) { @@ -162,6 +167,20 @@ int flb_hash_add(struct flb_hash *ht, char *key, int key_len, return -1; } + /* Check capacity */ + if (ht->max_entries > 0 && ht->total_count >= ht->max_entries) { + /* FIXME: handle eviction mode */ + if (ht->evict_mode == FLB_HASH_EVICT_NONE) { + + } + else if (ht->evict_mode == FLB_HASH_EVICT_OLDER) { + + } + else if (ht->evict_mode == FLB_HASH_EVICT_LESS_USED) { + + } + } + /* Generate hash number */ hash = gen_hash(key, key_len); id = (hash % ht->size); @@ -172,6 +191,8 @@ int flb_hash_add(struct flb_hash *ht, char *key, int key_len, flb_errno(); return -1; } + entry->created = time(NULL); + entry->hits = 0; /* Store the key and value as a new memory region */ entry->key = flb_strdup(key); @@ -183,6 +204,7 @@ int flb_hash_add(struct flb_hash *ht, char *key, int key_len, flb_free(entry); return -1; } + /* * Copy the buffer and append a NULL byte in case the caller set and * expects a string. @@ -197,6 +219,7 @@ int flb_hash_add(struct flb_hash *ht, char *key, int key_len, /* Check if the new key already exists */ if (table->count == 0) { mk_list_add(&entry->_head, &table->chains); + mk_list_add(&entry->_head_parent, &ht->entries); } else { mk_list_foreach_safe(head, tmp, &table->chains) { @@ -208,6 +231,7 @@ int flb_hash_add(struct flb_hash *ht, char *key, int key_len, } } mk_list_add(&entry->_head, &table->chains); + mk_list_add(&entry->_head_parent, &ht->entries); } table->count++; @@ -270,6 +294,7 @@ int flb_hash_get(struct flb_hash *ht, char *key, int key_len, return -1; } + entry->hits++; *out_buf = entry->val; *out_size = entry->val_size;