Staging: batman-adv: Move hash callback related function to header
authorSven Eckelmann <sven.eckelmann@gmx.de>
Sun, 21 Nov 2010 23:55:58 +0000 (00:55 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 29 Nov 2010 19:09:12 +0000 (11:09 -0800)
To enable inlining of the function pointers hashdata_choose_cb,
hashdata_choose_cb and hashdata_free_cb, also the hash functions which
uses them must be inlined by the called function.

This should increase the performance, but also increases the size of the
generated machine code slightly.

Reported-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/batman-adv/hash.c
drivers/staging/batman-adv/hash.h

index 6361a317552084df126b485f620aa02f2f0cb1f5..7d0498754afdadda18b2edc6d4295f25a4179315 100644 (file)
@@ -33,30 +33,6 @@ static void hash_init(struct hashtable_t *hash)
                hash->table[i] = NULL;
 }
 
-/* remove the hash structure. if hashdata_free_cb != NULL, this function will be
- * called to remove the elements inside of the hash.  if you don't remove the
- * elements, memory might be leaked. */
-void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg)
-{
-       struct element_t *bucket, *last_bucket;
-       int i;
-
-       for (i = 0; i < hash->size; i++) {
-               bucket = hash->table[i];
-
-               while (bucket != NULL) {
-                       if (free_cb != NULL)
-                               free_cb(bucket->data, arg);
-
-                       last_bucket = bucket;
-                       bucket = bucket->next;
-                       kfree(last_bucket);
-               }
-       }
-
-       hash_destroy(hash);
-}
-
 /* free only the hashtable and the hash itself. */
 void hash_destroy(struct hashtable_t *hash)
 {
@@ -159,70 +135,6 @@ struct hashtable_t *hash_new(int size)
        return hash;
 }
 
-/* adds data to the hashtable. returns 0 on success, -1 on error */
-int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare,
-            hashdata_choose_cb choose, void *data)
-{
-       int index;
-       struct element_t *bucket, *prev_bucket = NULL;
-
-       if (!hash)
-               return -1;
-
-       index = choose(data, hash->size);
-       bucket = hash->table[index];
-
-       while (bucket != NULL) {
-               if (compare(bucket->data, data))
-                       return -1;
-
-               prev_bucket = bucket;
-               bucket = bucket->next;
-       }
-
-       /* found the tail of the list, add new element */
-       bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC);
-
-       if (bucket == NULL)
-               return -1;
-
-       bucket->data = data;
-       bucket->next = NULL;
-
-       /* and link it */
-       if (prev_bucket == NULL)
-               hash->table[index] = bucket;
-       else
-               prev_bucket->next = bucket;
-
-       hash->elements++;
-       return 0;
-}
-
-/* finds data, based on the key in keydata. returns the found data on success,
- * or NULL on error */
-void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare,
-               hashdata_choose_cb choose, void *keydata)
-{
-       int index;
-       struct element_t *bucket;
-
-       if (!hash)
-               return NULL;
-
-       index = choose(keydata , hash->size);
-       bucket = hash->table[index];
-
-       while (bucket != NULL) {
-               if (compare(bucket->data, keydata))
-                       return bucket->data;
-
-               bucket = bucket->next;
-       }
-
-       return NULL;
-}
-
 /* remove bucket (this might be used in hash_iterate() if you already found the
  * bucket you want to delete and don't need the overhead to find it again with
  * hash_remove(). But usually, you don't want to use this function, as it
@@ -243,65 +155,3 @@ void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t)
 
        return data_save;
 }
-
-/* removes data from hash, if found. returns pointer do data on success, so you
- * can remove the used structure yourself, or NULL on error .  data could be the
- * structure you use with just the key filled, we just need the key for
- * comparing. */
-void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare,
-                 hashdata_choose_cb choose, void *data)
-{
-       struct hash_it_t hash_it_t;
-
-       hash_it_t.index = choose(data, hash->size);
-       hash_it_t.bucket = hash->table[hash_it_t.index];
-       hash_it_t.prev_bucket = NULL;
-
-       while (hash_it_t.bucket != NULL) {
-               if (compare(hash_it_t.bucket->data, data)) {
-                       hash_it_t.first_bucket =
-                               (hash_it_t.bucket ==
-                                hash->table[hash_it_t.index] ?
-                                &hash->table[hash_it_t.index] : NULL);
-                       return hash_remove_bucket(hash, &hash_it_t);
-               }
-
-               hash_it_t.prev_bucket = hash_it_t.bucket;
-               hash_it_t.bucket = hash_it_t.bucket->next;
-       }
-
-       return NULL;
-}
-
-/* resize the hash, returns the pointer to the new hash or NULL on
- * error. removes the old hash on success. */
-struct hashtable_t *hash_resize(struct hashtable_t *hash,
-                               hashdata_compare_cb compare,
-                               hashdata_choose_cb choose, int size)
-{
-       struct hashtable_t *new_hash;
-       struct element_t *bucket;
-       int i;
-
-       /* initialize a new hash with the new size */
-       new_hash = hash_new(size);
-
-       if (new_hash == NULL)
-               return NULL;
-
-       /* copy the elements */
-       for (i = 0; i < hash->size; i++) {
-               bucket = hash->table[i];
-
-               while (bucket != NULL) {
-                       hash_add(new_hash, compare, choose, bucket->data);
-                       bucket = bucket->next;
-               }
-       }
-
-       /* remove hash and eventual overflow buckets but not the content
-        * itself. */
-       hash_delete(hash, NULL, NULL);
-
-       return new_hash;
-}
index 85ee12b0779aa010bbe3d2fe0a8ded2a7ea38711..efc4c28f7c15391272a71b6f08387501920bd2b9 100644 (file)
@@ -66,35 +66,163 @@ struct hashtable_t *hash_new(int size);
  * fiddles with hash-internals. */
 void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t);
 
+/* free only the hashtable and the hash itself. */
+void hash_destroy(struct hashtable_t *hash);
+
 /* remove the hash structure. if hashdata_free_cb != NULL, this function will be
  * called to remove the elements inside of the hash.  if you don't remove the
  * elements, memory might be leaked. */
-void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg);
+static inline void hash_delete(struct hashtable_t *hash,
+                              hashdata_free_cb free_cb, void *arg)
+{
+       struct element_t *bucket, *last_bucket;
+       int i;
 
-/* free only the hashtable and the hash itself. */
-void hash_destroy(struct hashtable_t *hash);
+       for (i = 0; i < hash->size; i++) {
+               bucket = hash->table[i];
+
+               while (bucket != NULL) {
+                       if (free_cb != NULL)
+                               free_cb(bucket->data, arg);
+
+                       last_bucket = bucket;
+                       bucket = bucket->next;
+                       kfree(last_bucket);
+               }
+       }
+
+       hash_destroy(hash);
+}
 
 /* adds data to the hashtable. returns 0 on success, -1 on error */
-int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare,
-            hashdata_choose_cb choose, void *data);
+static inline int hash_add(struct hashtable_t *hash,
+                          hashdata_compare_cb compare,
+                          hashdata_choose_cb choose, void *data)
+{
+       int index;
+       struct element_t *bucket, *prev_bucket = NULL;
+
+       if (!hash)
+               return -1;
+
+       index = choose(data, hash->size);
+       bucket = hash->table[index];
+
+       while (bucket != NULL) {
+               if (compare(bucket->data, data))
+                       return -1;
+
+               prev_bucket = bucket;
+               bucket = bucket->next;
+       }
+
+       /* found the tail of the list, add new element */
+       bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC);
+
+       if (bucket == NULL)
+               return -1;
+
+       bucket->data = data;
+       bucket->next = NULL;
+
+       /* and link it */
+       if (prev_bucket == NULL)
+               hash->table[index] = bucket;
+       else
+               prev_bucket->next = bucket;
+
+       hash->elements++;
+       return 0;
+}
 
 /* removes data from hash, if found. returns pointer do data on success, so you
  * can remove the used structure yourself, or NULL on error .  data could be the
  * structure you use with just the key filled, we just need the key for
  * comparing. */
-void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare,
-                 hashdata_choose_cb choose, void *data);
+static inline void *hash_remove(struct hashtable_t *hash,
+                               hashdata_compare_cb compare,
+                               hashdata_choose_cb choose, void *data)
+{
+       struct hash_it_t hash_it_t;
+
+       hash_it_t.index = choose(data, hash->size);
+       hash_it_t.bucket = hash->table[hash_it_t.index];
+       hash_it_t.prev_bucket = NULL;
+
+       while (hash_it_t.bucket != NULL) {
+               if (compare(hash_it_t.bucket->data, data)) {
+                       hash_it_t.first_bucket =
+                               (hash_it_t.bucket ==
+                                hash->table[hash_it_t.index] ?
+                                &hash->table[hash_it_t.index] : NULL);
+                       return hash_remove_bucket(hash, &hash_it_t);
+               }
+
+               hash_it_t.prev_bucket = hash_it_t.bucket;
+               hash_it_t.bucket = hash_it_t.bucket->next;
+       }
+
+       return NULL;
+}
 
 /* finds data, based on the key in keydata. returns the found data on success,
  * or NULL on error */
-void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare,
-               hashdata_choose_cb choose, void *keydata);
+static inline void *hash_find(struct hashtable_t *hash,
+                             hashdata_compare_cb compare,
+                             hashdata_choose_cb choose, void *keydata)
+{
+       int index;
+       struct element_t *bucket;
+
+       if (!hash)
+               return NULL;
+
+       index = choose(keydata , hash->size);
+       bucket = hash->table[index];
+
+       while (bucket != NULL) {
+               if (compare(bucket->data, keydata))
+                       return bucket->data;
+
+               bucket = bucket->next;
+       }
+
+       return NULL;
+}
 
 /* resize the hash, returns the pointer to the new hash or NULL on
  * error. removes the old hash on success */
-struct hashtable_t *hash_resize(struct hashtable_t *hash,
-                               hashdata_compare_cb compare,
-                               hashdata_choose_cb choose, int size);
+static inline struct hashtable_t *hash_resize(struct hashtable_t *hash,
+                                             hashdata_compare_cb compare,
+                                             hashdata_choose_cb choose,
+                                             int size)
+{
+       struct hashtable_t *new_hash;
+       struct element_t *bucket;
+       int i;
+
+       /* initialize a new hash with the new size */
+       new_hash = hash_new(size);
+
+       if (new_hash == NULL)
+               return NULL;
+
+       /* copy the elements */
+       for (i = 0; i < hash->size; i++) {
+               bucket = hash->table[i];
+
+               while (bucket != NULL) {
+                       hash_add(new_hash, compare, choose, bucket->data);
+                       bucket = bucket->next;
+               }
+       }
+
+       /* remove hash and eventual overflow buckets but not the content
+        * itself. */
+       hash_delete(hash, NULL, NULL);
+
+       return new_hash;
+}
 
 /* iterate though the hash. first element is selected with iter_in NULL.  use
  * the returned iterator to access the elements until hash_it_t returns NULL. */
This page took 0.03168 seconds and 5 git commands to generate.