diff options
author | roopa <roopa@cumulusnetworks.com> | 2012-11-09 14:41:32 -0800 |
---|---|---|
committer | Thomas Graf <tgraf@redhat.com> | 2012-11-10 00:12:36 +0100 |
commit | c6f89ed02f04ac4984be34418774a7b06ff54f79 (patch) | |
tree | 4e8197ac2af4e9199180aa961483e31c5a3885df /lib/hashtable.c | |
parent | a8741fab8e48e55fe10cfb080ba4b28ed4441fb0 (diff) | |
download | libnl-c6f89ed02f04ac4984be34418774a7b06ff54f79.tar.gz |
Add nl hashtable structures and access functions
This patch adds the required structures and access functions to create
and manage hashtables for netlink cache objects
Signed-off-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: Nolan Leake <nolan@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Reviewed-by: Wilson Kok <wkok@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Diffstat (limited to 'lib/hashtable.c')
-rw-r--r-- | lib/hashtable.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/lib/hashtable.c b/lib/hashtable.c new file mode 100644 index 0000000..59cd91e --- /dev/null +++ b/lib/hashtable.c @@ -0,0 +1,141 @@ +/* + * netlink/hashtable.c Netlink hashtable Utilities + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2012 Cumulus Networks, Inc + */ +#include <string.h> +#include <netlink-local.h> +#include <netlink/object.h> +#include <netlink/hash.h> +#include <netlink/hashtable.h> + +nl_hash_table_t *nl_hash_table_alloc(int size) +{ + nl_hash_table_t *ht; + + ht = calloc(1, sizeof (*ht)); + if (!ht) + goto errout; + + ht->nodes = calloc(size, sizeof (*ht->nodes)); + if (!ht->nodes) { + free(ht); + goto errout; + } + + ht->size = size; + + return ht; +errout: + return NULL; +} + +void nl_hash_table_free(nl_hash_table_t *ht) +{ + int i; + + for(i = 0; i < ht->size; i++) { + nl_hash_node_t *node = ht->nodes[i]; + nl_hash_node_t *saved_node; + + while (node) { + saved_node = node; + node = node->next; + free(saved_node); + } + } + + free(ht->nodes); + free(ht); +} + +struct nl_object* nl_hash_table_lookup(nl_hash_table_t *ht, + struct nl_object *obj) +{ + nl_hash_node_t *node; + uint32_t key_hash; + + nl_object_keygen(obj, &key_hash, ht->size); + node = ht->nodes[key_hash]; + + while (node) { + if (nl_object_identical(node->obj, obj)) + return node->obj; + node = node->next; + } + + return NULL; +} + +int nl_hash_table_add(nl_hash_table_t *ht, struct nl_object *obj) +{ + nl_hash_node_t *node; + uint32_t key_hash; + + nl_object_keygen(obj, &key_hash, ht->size); + node = ht->nodes[key_hash]; + + while (node) { + if (nl_object_identical(node->obj, obj)) { + NL_DBG(2, "Warning: Add to hashtable found duplicate...\n"); + return -NLE_EXIST; + } + node = node->next; + } + + NL_DBG (5, "adding cache entry of obj %p in table %p, with hash 0x%x\n", + obj, ht, key_hash); + + node = malloc(sizeof(nl_hash_node_t)); + if (!node) + return -NLE_NOMEM; + nl_object_get(obj); + node->obj = obj; + node->key = key_hash; + node->key_size = sizeof(uint32_t); + node->next = ht->nodes[key_hash]; + ht->nodes[key_hash] = node; + + return 0; +} + +int nl_hash_table_del(nl_hash_table_t *ht, struct nl_object *obj) +{ + nl_hash_node_t *node, *prev; + uint32_t key_hash; + + nl_object_keygen(obj, &key_hash, ht->size); + prev = node = ht->nodes[key_hash]; + + while (node) { + if (nl_object_identical(node->obj, obj)) { + nl_object_put(obj); + + NL_DBG (5, "deleting cache entry of obj %p in table %p, with" + " hash 0x%x\n", obj, ht, key_hash); + + if (node == ht->nodes[key_hash]) + ht->nodes[key_hash] = node->next; + else + prev->next = node->next; + + free(node); + + return 0; + } + prev = node; + node = node->next; + } + + return -1; +} + +uint32_t nl_hash(void *k, size_t length, uint32_t initval) +{ + return(hash(k, length, initval)); +} |