Skip to content

Commit

Permalink
Staging: batman-adv: Make hash_iterate inlineable
Browse files Browse the repository at this point in the history
hash_iterate is next to the function pointers the most called function
related to hashes which benefits from inlining as it is uses in loops.

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>
  • Loading branch information
Sven Eckelmann authored and Greg Kroah-Hartman committed Nov 29, 2010
1 parent 60eb502 commit a3238c3
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 77 deletions.
1 change: 0 additions & 1 deletion drivers/staging/batman-adv/TODO
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
* remove own list functionality from hash
* use hlist_head, hlist_node in hash
* think about more efficient ways instead of abstraction of hash
* Request a new review
* Process the comments from the review
* Move into mainline proper
Expand Down
72 changes: 0 additions & 72 deletions drivers/staging/batman-adv/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,78 +40,6 @@ void hash_destroy(struct hashtable_t *hash)
kfree(hash);
}

/* iterate though the hash. First element is selected if an iterator
* initialized with HASHIT() is supplied as iter. Use the returned
* (or supplied) iterator to access the elements until hash_iterate returns
* NULL. */

struct hash_it_t *hash_iterate(struct hashtable_t *hash,
struct hash_it_t *iter)
{
if (!hash)
return NULL;
if (!iter)
return NULL;

/* sanity checks first (if our bucket got deleted in the last
* iteration): */
if (iter->bucket != NULL) {
if (iter->first_bucket != NULL) {
/* we're on the first element and it got removed after
* the last iteration. */
if ((*iter->first_bucket) != iter->bucket) {
/* there are still other elements in the list */
if ((*iter->first_bucket) != NULL) {
iter->prev_bucket = NULL;
iter->bucket = (*iter->first_bucket);
iter->first_bucket =
&hash->table[iter->index];
return iter;
} else {
iter->bucket = NULL;
}
}
} else if (iter->prev_bucket != NULL) {
/*
* we're not on the first element, and the bucket got
* removed after the last iteration. the last bucket's
* next pointer is not pointing to our actual bucket
* anymore. select the next.
*/
if (iter->prev_bucket->next != iter->bucket)
iter->bucket = iter->prev_bucket;
}
}

/* now as we are sane, select the next one if there is some */
if (iter->bucket != NULL) {
if (iter->bucket->next != NULL) {
iter->prev_bucket = iter->bucket;
iter->bucket = iter->bucket->next;
iter->first_bucket = NULL;
return iter;
}
}

/* if not returned yet, we've reached the last one on the index and have
* to search forward */
iter->index++;
/* go through the entries of the hash table */
while (iter->index < hash->size) {
if ((hash->table[iter->index]) != NULL) {
iter->prev_bucket = NULL;
iter->bucket = hash->table[iter->index];
iter->first_bucket = &hash->table[iter->index];
return iter;
} else {
iter->index++;
}
}

/* nothing to iterate over anymore */
return NULL;
}

/* allocates and clears the hash */
struct hashtable_t *hash_new(int size)
{
Expand Down
74 changes: 70 additions & 4 deletions drivers/staging/batman-adv/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,75 @@ static inline struct hashtable_t *hash_resize(struct hashtable_t *hash,
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. */
struct hash_it_t *hash_iterate(struct hashtable_t *hash,
struct hash_it_t *iter_in);
/* iterate though the hash. First element is selected if an iterator
* initialized with HASHIT() is supplied as iter. Use the returned
* (or supplied) iterator to access the elements until hash_iterate returns
* NULL. */
static inline struct hash_it_t *hash_iterate(struct hashtable_t *hash,
struct hash_it_t *iter)
{
if (!hash)
return NULL;
if (!iter)
return NULL;

/* sanity checks first (if our bucket got deleted in the last
* iteration): */
if (iter->bucket != NULL) {
if (iter->first_bucket != NULL) {
/* we're on the first element and it got removed after
* the last iteration. */
if ((*iter->first_bucket) != iter->bucket) {
/* there are still other elements in the list */
if ((*iter->first_bucket) != NULL) {
iter->prev_bucket = NULL;
iter->bucket = (*iter->first_bucket);
iter->first_bucket =
&hash->table[iter->index];
return iter;
} else {
iter->bucket = NULL;
}
}
} else if (iter->prev_bucket != NULL) {
/*
* we're not on the first element, and the bucket got
* removed after the last iteration. the last bucket's
* next pointer is not pointing to our actual bucket
* anymore. select the next.
*/
if (iter->prev_bucket->next != iter->bucket)
iter->bucket = iter->prev_bucket;
}
}

/* now as we are sane, select the next one if there is some */
if (iter->bucket != NULL) {
if (iter->bucket->next != NULL) {
iter->prev_bucket = iter->bucket;
iter->bucket = iter->bucket->next;
iter->first_bucket = NULL;
return iter;
}
}

/* if not returned yet, we've reached the last one on the index and have
* to search forward */
iter->index++;
/* go through the entries of the hash table */
while (iter->index < hash->size) {
if ((hash->table[iter->index]) != NULL) {
iter->prev_bucket = NULL;
iter->bucket = hash->table[iter->index];
iter->first_bucket = &hash->table[iter->index];
return iter;
} else {
iter->index++;
}
}

/* nothing to iterate over anymore */
return NULL;
}

#endif /* _NET_BATMAN_ADV_HASH_H_ */

0 comments on commit a3238c3

Please sign in to comment.