Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2003 Pekka Riikonen
+ Copyright (C) 2001 - 2006 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
hash table. */
/* $Id$ */
-#include "silcincludes.h"
+#include "silc.h"
#include "silchashtable.h"
/* Define to 1 if you want hash table debug enabled */
#endif
/* Default size of the hash table (index to prime table) */
-#define SILC_HASH_TABLE_SIZE 3
+#define SILC_HASH_TABLE_SIZE 2
/* Produce the index by hashing the key */
#define SILC_HASH_TABLE_HASH(f, c) \
/* Prime sizes for the hash table. The size of the table will always
be one of these. */
-const SilcUInt32 primesize[42] =
+const SilcUInt32 primesize[] =
{
- 1, 3, 5, 11, 17, 37, 67, 109, 131, 163, 257, 367, 521, 823, 1031,
- 1237, 2053, 2777, 4099, 6247, 8209, 14057, 16411, 21089, 32771, 47431,
- 65537, 106721, 131101, 262147, 360163, 524309, 810343, 1048583, 2097169,
- 4194319, 6153409, 8388617, 13845163, 16777259, 33554467, 67108879
+ 3, 5, 11, 17, 37, 67, 109, 131, 163, 257, 367, 521, 823, 1031,
+ 1237, 1447, 2053, 2389, 2777, 3323, 4099, 5059, 6247, 7001, 8209, 10993,
+ 14057, 16411, 19181, 21089, 25033, 32771, 40009, 47431, 65537, 106721,
+ 131101, 262147, 360163, 524309, 810343, 1048583, 2097169, 4194319,
+ 6153409, 8388617, 13845163, 16777259, 33554467, 67108879
};
/* Find appropriate size for the hash table. The size will be a prime. */
void *foreach_user_context)
{
SilcHashTableEntry e, tmp;
- bool auto_rehash, found = FALSE;
+ SilcBool auto_rehash, found = FALSE;
SilcUInt32 i = SILC_HASH_TABLE_HASH(hash, hash_user_context);
SILC_HT_DEBUG(("index %d key %p", i, key));
/* Internal routine to add new key to the hash table */
-static inline bool
+static inline SilcBool
silc_hash_table_add_internal(SilcHashTable ht, void *key, void *context,
SilcHashFunction hash,
void *hash_user_context)
/* Internal routine to replace old key with new one (if it exists) */
-static inline bool
+static inline SilcBool
silc_hash_table_replace_internal(SilcHashTable ht, void *key, void *context,
SilcHashFunction hash,
void *hash_user_context)
void *compare_user_context,
SilcHashDestructor destructor,
void *destructor_user_context,
- bool auto_rehash)
+ SilcBool auto_rehash)
{
SilcHashTable ht;
SilcUInt32 size_index = SILC_HASH_TABLE_SIZE;
hash table. This function quarantees that the entry is always added
to the hash table reliably (it is collision resistant). */
-void silc_hash_table_add(SilcHashTable ht, void *key, void *context)
+SilcBool silc_hash_table_add(SilcHashTable ht, void *key, void *context)
{
- silc_hash_table_add_internal(ht, key, context, ht->hash,
- ht->hash_user_context);
+ return silc_hash_table_add_internal(ht, key, context, ht->hash,
+ ht->hash_user_context);
}
/* Same as above but with specific hash function and user context. */
-void silc_hash_table_add_ext(SilcHashTable ht, void *key, void *context,
- SilcHashFunction hash, void *hash_user_context)
+SilcBool silc_hash_table_add_ext(SilcHashTable ht, void *key, void *context,
+ SilcHashFunction hash,
+ void *hash_user_context)
{
- silc_hash_table_add_internal(ht, key, context, hash, hash_user_context);
+ return silc_hash_table_add_internal(ht, key, context,
+ hash, hash_user_context);
}
/* Same as above but if the `key' already exists in the hash table
the `context. The destructor function will be called for the
replaced key and context. */
-void silc_hash_table_replace(SilcHashTable ht, void *key, void *context)
+SilcBool silc_hash_table_replace(SilcHashTable ht, void *key, void *context)
{
- silc_hash_table_replace_internal(ht, key, context, ht->hash,
- ht->hash_user_context);
+ return silc_hash_table_replace_internal(ht, key, context, ht->hash,
+ ht->hash_user_context);
}
/* Same as above but with specific hash function. */
-void silc_hash_table_replace_ext(SilcHashTable ht, void *key, void *context,
- SilcHashFunction hash,
- void *hash_user_context)
+SilcBool silc_hash_table_replace_ext(SilcHashTable ht, void *key,
+ void *context,
+ SilcHashFunction hash,
+ void *hash_user_context)
{
- silc_hash_table_replace_internal(ht, key, context, hash, hash_user_context);
+ return silc_hash_table_replace_internal(ht, key, context,
+ hash, hash_user_context);
}
/* Removes the entry from the hash table by the provided `key'. This will
call the destructor funtion for the found entry. Return TRUE if the
entry was removed successfully and FALSE otherwise. */
-bool silc_hash_table_del(SilcHashTable ht, void *key)
+SilcBool silc_hash_table_del(SilcHashTable ht, void *key)
{
SilcHashTableEntry *entry, prev, e;
/* Same as above but with specific hash and compare functions. */
-bool silc_hash_table_del_ext(SilcHashTable ht, void *key,
- SilcHashFunction hash,
- void *hash_user_context,
- SilcHashCompare compare,
- void *compare_user_context,
- SilcHashDestructor destructor,
- void *destructor_user_context)
+SilcBool silc_hash_table_del_ext(SilcHashTable ht, void *key,
+ SilcHashFunction hash,
+ void *hash_user_context,
+ SilcHashCompare compare,
+ void *compare_user_context,
+ SilcHashDestructor destructor,
+ void *destructor_user_context)
{
SilcHashTableEntry *entry, prev, e;
have duplicate keys. In that case the `context' may be used to check
whether the correct entry is being deleted. */
-bool silc_hash_table_del_by_context(SilcHashTable ht, void *key,
- void *context)
+SilcBool silc_hash_table_del_by_context(SilcHashTable ht, void *key,
+ void *context)
{
SilcHashTableEntry *entry, prev, e;
/* Same as above but with specific hash and compare functions. */
-bool silc_hash_table_del_by_context_ext(SilcHashTable ht, void *key,
- void *context,
- SilcHashFunction hash,
- void *hash_user_context,
- SilcHashCompare compare,
- void *compare_user_context,
- SilcHashDestructor destructor,
- void *destructor_user_context)
+SilcBool silc_hash_table_del_by_context_ext(SilcHashTable ht, void *key,
+ void *context,
+ SilcHashFunction hash,
+ void *hash_user_context,
+ SilcHashCompare compare,
+ void *compare_user_context,
+ SilcHashDestructor destructor,
+ void *destructor_user_context)
{
SilcHashTableEntry *entry, prev, e;
respectively. If the `ret_key and `ret_context' are NULL then this
maybe used only to check whether given key exists in the table. */
-bool silc_hash_table_find(SilcHashTable ht, void *key,
- void **ret_key, void **ret_context)
+SilcBool silc_hash_table_find(SilcHashTable ht, void *key,
+ void **ret_key, void **ret_context)
{
- SilcHashTableEntry *entry;
-
- entry = silc_hash_table_find_internal_simple(ht, key, ht->hash,
- ht->hash_user_context,
- ht->compare,
- ht->compare_user_context);
- if (*entry == NULL)
- return FALSE;
-
- if (ret_key)
- *ret_key = (*entry)->key;
- if (ret_context)
- *ret_context = (*entry)->context;
-
- return TRUE;
+ return silc_hash_table_find_ext(ht, key, ret_key, ret_context,
+ NULL, NULL, NULL, NULL);
}
/* Same as above but with specified hash and comparison functions. */
-bool silc_hash_table_find_ext(SilcHashTable ht, void *key,
- void **ret_key, void **ret_context,
- SilcHashFunction hash,
- void *hash_user_context,
- SilcHashCompare compare,
- void *compare_user_context)
+SilcBool silc_hash_table_find_ext(SilcHashTable ht, void *key,
+ void **ret_key, void **ret_context,
+ SilcHashFunction hash,
+ void *hash_user_context,
+ SilcHashCompare compare,
+ void *compare_user_context)
{
SilcHashTableEntry *entry;
/* Same as silc_hash_table_find but finds with specific context. */
-bool silc_hash_table_find_by_context(SilcHashTable ht, void *key,
- void *context, void **ret_key)
+SilcBool silc_hash_table_find_by_context(SilcHashTable ht, void *key,
+ void *context, void **ret_key)
+{
+ return silc_hash_table_find_by_context_ext(ht, key, context, ret_key,
+ NULL, NULL, NULL, NULL);
+}
+
+/* Same as above but with specified hash and comparison functions. */
+
+SilcBool silc_hash_table_find_by_context_ext(SilcHashTable ht, void *key,
+ void *context, void **ret_key,
+ SilcHashFunction hash,
+ void *hash_user_context,
+ SilcHashCompare compare,
+ void *compare_user_context)
{
SilcHashTableEntry *entry;
entry = silc_hash_table_find_internal_context(ht, key, context, NULL,
- ht->hash,
+ hash ? hash : ht->hash,
+ hash_user_context ?
+ hash_user_context :
ht->hash_user_context,
+ compare ? compare :
ht->compare,
+ compare_user_context ?
+ compare_user_context :
ht->compare_user_context);
if (!entry || !(*entry))
return FALSE;
{
SilcHashTableEntry e, tmp;
int i;
- bool auto_rehash;
+ SilcBool auto_rehash;
if (!foreach)
return;
int i;
SilcHashTableEntry *table, e, tmp;
SilcUInt32 table_size, size_index;
- bool auto_rehash;
+ SilcBool auto_rehash;
SILC_HT_DEBUG(("Start"));
int i;
SilcHashTableEntry *table, e, tmp;
SilcUInt32 table_size, size_index;
- bool auto_rehash;
+ SilcBool auto_rehash;
SILC_HT_DEBUG(("Start"));
`context' and TRUE. If this returns FALSE then there are no anymore
any entrys. Usage: while (silc_hash_table_get(&htl, &key, &context)) */
-bool silc_hash_table_get(SilcHashTableList *htl, void **key, void **context)
+SilcBool silc_hash_table_get(SilcHashTableList *htl, void **key,
+ void **context)
{
SilcHashTableEntry entry = (SilcHashTableEntry)htl->entry;