From 40c3aedf8d221b0f8b9c34aef27bcbce199bc3ff Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 9 Sep 2007 17:19:52 +0000 Subject: [PATCH] * Added hash_count_elements() and hash_count_used_slots() (mainly for diagnostic purposes). * hash_init() adjusts the table size to a prime number, which should result in a better element distribution, particularly since usually a power of two is passed. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22210 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/util/khash.h | 2 ++ src/system/kernel/util/khash.c | 43 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/headers/private/kernel/util/khash.h b/headers/private/kernel/util/khash.h index d130b4ed85..71057b339b 100644 --- a/headers/private/kernel/util/khash.h +++ b/headers/private/kernel/util/khash.h @@ -38,6 +38,8 @@ struct hash_iterator *hash_open(struct hash_table *table, struct hash_iterator * void hash_close(struct hash_table *table, struct hash_iterator *i, bool free_iterator); void *hash_next(struct hash_table *table, struct hash_iterator *i); void hash_rewind(struct hash_table *table, struct hash_iterator *i); +uint32 hash_count_elements(struct hash_table *table); +uint32 hash_count_used_slots(struct hash_table *table); /* function pointers must look like this: * diff --git a/src/system/kernel/util/khash.c b/src/system/kernel/util/khash.c index 18e9846b82..37407f2f87 100644 --- a/src/system/kernel/util/khash.c +++ b/src/system/kernel/util/khash.c @@ -43,6 +43,27 @@ struct hash_table { #define PUT_IN_NEXT(t, e, val) (*(unsigned long *)NEXT_ADDR(t, e) = (long)(val)) +const uint32 kPrimes [] = { + 13, 31, 61, 127, 251, + 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139, + 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393, 67108859, + 134217689, 268435399, 536870909, 1073741789, 2147483647, 0 +}; + + +static uint32 +get_prime_table_size(uint32 size) +{ + int i; + for (i = 0; kPrimes[i] != 0; i++) { + if (kPrimes[i] > size) + return kPrimes[i]; + } + + return kPrimes[i - 1]; +} + + static inline void * next_element(hash_table *table, void *element) { @@ -59,6 +80,8 @@ hash_init(uint32 table_size, int next_ptr_offset, struct hash_table *t; unsigned int i; + table_size = get_prime_table_size(table_size); + if (compare_func == NULL || hash_func == NULL) { dprintf("hash_init() called with NULL function pointer\n"); return NULL; @@ -303,3 +326,23 @@ hash_hash_string(const char *string) return hash; } + +uint32 +hash_count_elements(struct hash_table *table) +{ + return table->num_elements; +} + + +uint32 +hash_count_used_slots(struct hash_table *table) +{ + uint32 usedSlots = 0; + uint32 i; + for (i = 0; i < table->table_size; i++) { + if (table->table[i] != NULL) + usedSlots++; + } + + return usedSlots; +}