]> granicus.if.org Git - libnl/commitdiff
Add hash support in cache mngr
authorroopa <roopa@cumulusnetworks.com>
Fri, 9 Nov 2012 22:41:33 +0000 (14:41 -0800)
committerThomas Graf <tgraf@redhat.com>
Fri, 9 Nov 2012 23:12:44 +0000 (00:12 +0100)
This patch adds support to create, delete modify hash table for a cache

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>
include/netlink-types.h
include/netlink/cache-api.h
include/netlink/cache.h
lib/cache.c

index 23930b8e5502d5455a28b9412554dfe86749653a..0be58d1049f3eddb070d3625636c66a1b7057f56 100644 (file)
@@ -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;
 };
 
index 390cbea9e73eb18236e4155bea64549cb158b93e..aa5eeb6a965ce771789a2468964eaf09d9d52714 100644 (file)
@@ -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;
        
index fd137e1781a3c59dbf3410fc9852e44924fb9864..c919e6bed8f0b9edbc0834f99f31d853e15917e0 100644 (file)
@@ -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 */
index f73fedf8750cfac661c3a35f2f9c927222ab7a49..af4ee950939f07156fcc788e4dea4309f0639860 100644 (file)
@@ -53,6 +53,7 @@
 #include <netlink/netlink.h>
 #include <netlink/cache.h>
 #include <netlink/object.h>
+#include <netlink/hashtable.h>
 #include <netlink/utils.h>
 
 /**
@@ -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);