8#include "hashtable-api.h"
10#include <netlink/object.h>
11#include <netlink/hash.h>
12#include <netlink/hashtable.h>
14#include "nl-aux-core/nl-core.h"
23static nl_hash_table_t *_nl_hash_table_init(nl_hash_table_t *ht,
int size)
25 ht->nodes = calloc(size,
sizeof(*ht->nodes));
45 ht = calloc(1,
sizeof(*ht));
49 return _nl_hash_table_init(ht, size);
53static void _nl_hash_table_free(nl_hash_table_t *ht)
57 for (i = 0; i < ht->size; i++) {
58 nl_hash_node_t *node = ht->nodes[i];
59 nl_hash_node_t *saved_node;
80 _nl_hash_table_free(ht);
95 struct nl_object *obj)
101 node = ht->nodes[key_hash];
127 nl_hash_node_t *node;
131 node = ht->nodes[key_hash];
136 "Warning: Add to hashtable found duplicate...\n");
142 NL_DBG(5,
"adding cache entry of obj %p in table %p, with hash 0x%x\n",
145 node = malloc(
sizeof(nl_hash_node_t));
150 node->key = key_hash;
151 node->key_size =
sizeof(uint32_t);
152 node->next = ht->nodes[key_hash];
153 ht->nodes[key_hash] = node;
172 nl_hash_node_t *node, *prev;
176 prev = node = ht->nodes[key_hash];
183 "deleting cache entry of obj %p in table %p, with"
187 if (node == ht->nodes[key_hash])
188 ht->nodes[key_hash] = node->next;
190 prev->next = node->next;
200 return -NLE_OBJ_NOTFOUND;
203uint32_t nl_hash(
void *k,
size_t length, uint32_t initval)
205 return (__nl_hash((
char *)k, length, initval));
225#define NL_HT_LOAD_NUM 3
226#define NL_HT_LOAD_DEN 4
235static int nl_rhash_table_resize(nl_rhash_table_t *ht,
int new_size)
237 nl_hash_node_t **new_nodes;
243 new_nodes = calloc(new_size,
sizeof(*new_nodes));
248 for (i = 0; i < ht->hash_table.size; i++) {
249 nl_hash_node_t *node = ht->hash_table.nodes[i];
251 nl_hash_node_t *next = node->next;
255 node->key = new_hash;
258 node->next = new_nodes[new_hash];
259 new_nodes[new_hash] = node;
265 free(ht->hash_table.nodes);
266 ht->hash_table.nodes = new_nodes;
267 ht->hash_table.size = new_size;
272#define NL_INIT_RHASH_ENTRIES 8
281 nl_rhash_table_t *ht;
283 ht = calloc(1,
sizeof(*ht));
287 if (!_nl_hash_table_init(&ht->hash_table, NL_INIT_RHASH_ENTRIES)) {
291 ht->orig_size = NL_INIT_RHASH_ENTRIES;
308 _nl_hash_table_free(&ht->hash_table);
323 struct nl_object *obj)
350 if (obj->ce_ops->oo_keygen == NULL)
356 size = ht->hash_table.size;
357 if (ht->nelements * NL_HT_LOAD_DEN > size * NL_HT_LOAD_NUM) {
361 nl_rhash_table_resize(ht, size * 2);
388 if (obj->ce_ops->oo_keygen == NULL)
395 if (ht->nelements > 0) {
398 size = ht->hash_table.size;
399 if (size > ht->orig_size &&
400 ht->nelements * NL_HT_LOAD_DEN < (size / 4) * NL_HT_LOAD_NUM) {
401 int new_size = size / 2;
403 if (new_size < ht->orig_size)
404 new_size = ht->orig_size;
406 nl_rhash_table_resize(ht, new_size);
void nl_rhash_table_free(nl_rhash_table_t *ht)
Free resizeable hashtable including all nodes.
int nl_hash_table_del(nl_hash_table_t *ht, struct nl_object *obj)
Remove object from hashtable.
nl_hash_table_t * nl_hash_table_alloc(int size)
Allocate hashtable.
void nl_hash_table_free(nl_hash_table_t *ht)
Free hashtable including all nodes.
int nl_rhash_table_add(nl_rhash_table_t *ht, struct nl_object *obj)
Add object to resizeable hashtable.
int nl_rhash_table_del(nl_rhash_table_t *ht, struct nl_object *obj)
Remove object from resizeable hashtable.
int nl_hash_table_add(nl_hash_table_t *ht, struct nl_object *obj)
Add object to hashtable.
struct nl_object * nl_rhash_table_lookup(nl_rhash_table_t *ht, struct nl_object *obj)
Lookup identical object in resizeable hashtable.
nl_rhash_table_t * nl_rhash_table_alloc()
Allocate resizeable hashtable.
struct nl_object * nl_hash_table_lookup(nl_hash_table_t *ht, struct nl_object *obj)
Lookup identical object in hashtable.
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
int nl_object_identical(struct nl_object *a, struct nl_object *b)
Check if the identifiers of two objects are identical.
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
void nl_object_keygen(struct nl_object *obj, uint32_t *hashkey, uint32_t hashtbl_sz)
Generate object hash key.