From: roopa Date: Fri, 9 Nov 2012 22:41:33 +0000 (-0800) Subject: Add hash support in cache mngr X-Git-Tag: libnl3_2_15~38 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=55c0e036b04b567a81cca441117b4e2ce5e22ef2;p=libnl Add hash support in cache mngr This patch adds support to create, delete modify hash table for a cache Signed-off-by: Shrijeet Mukherjee Signed-off-by: Nolan Leake Signed-off-by: Roopa Prabhu Reviewed-by: Wilson Kok Signed-off-by: Thomas Graf --- diff --git a/include/netlink-types.h b/include/netlink-types.h index 23930b8..0be58d1 100644 --- a/include/netlink-types.h +++ b/include/netlink-types.h @@ -30,6 +30,7 @@ struct nl_cache_ops; struct nl_sock; struct nl_object; +struct nl_hash_table; struct nl_cb { @@ -78,6 +79,7 @@ struct nl_cache int c_nitems; int c_iarg1; int c_iarg2; + struct nl_hash_table * hashtable; struct nl_cache_ops * c_ops; }; diff --git a/include/netlink/cache-api.h b/include/netlink/cache-api.h index 390cbea..aa5eeb6 100644 --- a/include/netlink/cache-api.h +++ b/include/netlink/cache-api.h @@ -186,6 +186,9 @@ struct nl_cache_ops /** Netlink protocol */ int co_protocol; + /** cache object hash size **/ + int co_hash_size; + /** Group definition */ struct nl_af_group * co_groups; diff --git a/include/netlink/cache.h b/include/netlink/cache.h index fd137e1..c919e6b 100644 --- a/include/netlink/cache.h +++ b/include/netlink/cache.h @@ -71,6 +71,8 @@ extern void nl_cache_set_arg2(struct nl_cache *, int); extern int nl_cache_is_empty(struct nl_cache *); extern struct nl_object * nl_cache_search(struct nl_cache *, struct nl_object *); +extern struct nl_object * nl_cache_lookup(struct nl_cache *, + struct nl_object *); extern void nl_cache_mark_all(struct nl_cache *); /* Dumping */ diff --git a/lib/cache.c b/lib/cache.c index f73fedf..af4ee95 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -53,6 +53,7 @@ #include #include #include +#include #include /** @@ -190,6 +191,22 @@ struct nl_cache *nl_cache_alloc(struct nl_cache_ops *ops) nl_init_list_head(&cache->c_items); cache->c_ops = ops; + /* + * If object type provides a hash keygen + * functions, allocate a hash table for the + * cache objects for faster lookups + */ + if (ops->co_obj_ops->oo_keygen) { + int hashtable_size; + + if (ops->co_hash_size) + hashtable_size = ops->co_hash_size; + else + hashtable_size = NL_MAX_HASH_ENTRIES; + + cache->hashtable = nl_hash_table_alloc(hashtable_size); + } + NL_DBG(2, "Allocated cache %p <%s>.\n", cache, nl_cache_name(cache)); return cache; @@ -362,6 +379,10 @@ void nl_cache_free(struct nl_cache *cache) return; nl_cache_clear(cache); + + if (cache->hashtable) + nl_hash_table_free(cache->hashtable); + NL_DBG(1, "Freeing cache %p <%s>...\n", cache, nl_cache_name(cache)); free(cache); } @@ -375,8 +396,18 @@ void nl_cache_free(struct nl_cache *cache) static int __cache_add(struct nl_cache *cache, struct nl_object *obj) { + int ret; + obj->ce_cache = cache; + if (cache->hashtable) { + ret = nl_hash_table_add(cache->hashtable, obj); + if (ret < 0) { + obj->ce_cache = NULL; + return ret; + } + } + nl_list_add_tail(&obj->ce_list, &cache->c_items); cache->c_nitems++; @@ -411,6 +442,7 @@ static int __cache_add(struct nl_cache *cache, struct nl_object *obj) int nl_cache_add(struct nl_cache *cache, struct nl_object *obj) { struct nl_object *new; + int ret = 0; if (cache->c_ops->co_obj_ops != obj->ce_ops) return -NLE_OBJ_MISMATCH; @@ -424,7 +456,11 @@ int nl_cache_add(struct nl_cache *cache, struct nl_object *obj) new = obj; } - return __cache_add(cache, new); + ret = __cache_add(cache, new); + if (ret < 0) + nl_object_put(new); + + return ret; } /** @@ -474,11 +510,19 @@ int nl_cache_move(struct nl_cache *cache, struct nl_object *obj) */ void nl_cache_remove(struct nl_object *obj) { + int ret; struct nl_cache *cache = obj->ce_cache; if (cache == NULL) return; + if (cache->hashtable) { + ret = nl_hash_table_del(cache->hashtable, obj); + if (ret < 0) + NL_DBG(3, "Failed to delete %p from cache %p <%s>.\n", + obj, cache, nl_cache_name(cache)); + } + nl_list_del(&obj->ce_list); obj->ce_cache = NULL; nl_object_put(obj); @@ -566,8 +610,13 @@ struct update_xdata { static int update_msg_parser(struct nl_msg *msg, void *arg) { struct update_xdata *x = arg; - - return nl_cache_parse(x->ops, &msg->nm_src, msg->nm_nlh, x->params); + int ret = 0; + + ret = nl_cache_parse(x->ops, &msg->nm_src, msg->nm_nlh, x->params); + if (ret == -NLE_EXIST) + return NL_SKIP; + else + return ret; } /** @endcond */ @@ -842,6 +891,19 @@ restart: * @name Utillities * @{ */ +static struct nl_object *__cache_fast_lookup(struct nl_cache *cache, + struct nl_object *needle) +{ + struct nl_object *obj; + + obj = nl_hash_table_lookup(cache->hashtable, needle); + if (obj) { + nl_object_get(obj); + return obj; + } + + return NULL; +} /** * Search object in cache @@ -863,6 +925,9 @@ struct nl_object *nl_cache_search(struct nl_cache *cache, { struct nl_object *obj; + if (cache->hashtable) + return __cache_fast_lookup(cache, needle); + nl_list_for_each_entry(obj, &cache->c_items, ce_list) { if (nl_object_identical(obj, needle)) { nl_object_get(obj);