Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 228184
b: refs/heads/master
c: 60eb502
h: refs/heads/master
v: v3
  • Loading branch information
Sven Eckelmann authored and Greg Kroah-Hartman committed Nov 29, 2010
1 parent 7dd716d commit 85e5752
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 163 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6d5e654240dc14ded3d74aa5df6857572ba9f5e3
refs/heads/master: 60eb502436910fb8118639e2ce4d7a4f732b6754
150 changes: 0 additions & 150 deletions trunk/drivers/staging/batman-adv/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
152 changes: 140 additions & 12 deletions trunk/drivers/staging/batman-adv/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down

0 comments on commit 85e5752

Please sign in to comment.