+Wed May 16 23:03:30 EEST 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+ * Added entry_count field to the SilcHashTable to keep the number
+ of the entries in the table. Implemented the function
+ silc_hash_table_rehash. Added new function
+ silc_hash_table_count. Affected file lib/silcutil/silchashtable.c.
+
+ Fixed a minor bug in silc_hash_table_free.
+
+ * Added silc_hash_string, silc_hash_uint, silc_hash_ptr,
+ silc_hash_client_id, silc_hash_server_id and silc_hash_channel_id
+ into the lib/silcutil/silcutil.[ch].
+
Wed May 16 20:02:47 EEST 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
* Implemented a collision resistant hash table into the
o The CAST cipher is not compiled currently due to compilation errors;
check those. Cast is in lib/silccrypt/cast.c.
- o silc_hash_table_rehash is not implemented in lib/silcutil/silchashtable.c.
-
o All payload parsing (decoding) functions should take unsigned char *
and uint32 as data and data length as arguments. Now some of the
routines do already that but most of the routines use SilcBuffer.
struct SilcHashTableStruct {
SilcHashTableEntry *table;
uint32 table_size;
+ uint32 entry_count;
SilcHashFunction hash;
SilcHashCompare compare;
SilcHashDestructor destructor;
void silc_hash_table_free(SilcHashTable ht)
{
+ SilcHashTableEntry e, tmp;
int i;
- for (i = 0; i < primesize[ht->table_size]; i++)
- if (ht->table[i]) {
+ for (i = 0; i < primesize[ht->table_size]; i++) {
+ e = ht->table[i];
+ while (e) {
if (ht->destructor)
- ht->destructor(ht->table[i]->key, ht->table[i]->context);
- silc_free(ht->table[i]);
+ ht->destructor(e->key, e->context);
+ tmp = e;
+ e = e->next;
+ silc_free(tmp);
}
+ }
silc_free(ht->table);
silc_free(ht);
return primesize[ht->table_size];
}
+/* Returns the number of the entires in the hash table. If there is more
+ entries in the table thatn the size of the hash table calling the
+ silc_hash_table_rehash is recommended. */
+
+uint32 silc_hash_table_count(SilcHashTable ht)
+{
+ return ht->entry_count;
+}
+
/* Adds new entry to the hash table. The `key' is hashed using the
hash function and the both `key' and `context' will be saved to the
hash table. This function quarantees that the entry is always added
e->next = silc_calloc(1, sizeof(*e->next));
e->next->key = key;
e->next->context = context;
+ ht->entry_count++;
} else {
/* New key */
*entry = silc_calloc(1, sizeof(**entry));
(*entry)->key = key;
(*entry)->context = context;
+ ht->entry_count++;
}
}
} else {
/* New key */
*entry = silc_calloc(1, sizeof(**entry));
+ ht->entry_count++;
}
(*entry)->key = key;
ht->destructor(e->key, e->context);
silc_free(e);
+ ht->entry_count--;
+
return TRUE;
}
void silc_hash_table_rehash(SilcHashTable ht, uint32 new_size)
{
+ int i;
+ SilcHashTableEntry *table, e, tmp;
+ uint32 table_size, size_index;
+
+ /* Take old hash table */
+ table = ht->table;
+ table_size = ht->table_size;
+
+ /* Allocate new table */
+ ht->table = silc_calloc(new_size ? silc_hash_table_primesize(new_size,
+ &size_index) :
+ silc_hash_table_primesize(ht->entry_count,
+ &size_index),
+ sizeof(*ht->table));
+ ht->table_size = size_index;
+
+ /* Rehash */
+ for (i = 0; i < primesize[table_size]; i++) {
+ e = table[i];
+ while (e) {
+ silc_hash_table_add(ht, e->key, e->context);
+ tmp = e;
+ e = e->next;
+
+ /* Remove old entry */
+ silc_free(tmp);
+ }
+ }
+ /* Remove old table */
+ silc_free(table);
}
SilcHashDestructor destructor);
void silc_hash_table_free(SilcHashTable ht);
uint32 silc_hash_table_size(SilcHashTable ht);
+uint32 silc_hash_table_count(SilcHashTable ht);
void silc_hash_table_add(SilcHashTable ht, void *key, void *context);
void silc_hash_table_replace(SilcHashTable ht, void *key, void *context);
bool silc_hash_table_del(SilcHashTable ht, void *key);
return realname;
}
+
+/* Basic has function to hash strings. May be used with the SilcHashTable. */
+
+uint32 silc_hash_string(void *key)
+{
+ char *s = (char *)key;
+ uint32 h = 0, g;
+
+ while (*s != '\0') {
+ h = (h << 4) + toupper(*s);
+ if ((g = h & 0xf0000000)) {
+ h = h ^ (g >> 24);
+ h = h ^ g;
+ }
+ s++;
+ }
+
+ return h;
+}
+
+/* Basic hash function to hash integers. May be used with the SilcHashTable. */
+
+uint32 silc_hash_uint(void *key)
+{
+ return *(uint32 *)key;
+}
+
+/* Basic hash funtion to hash pointers. May be used with the SilcHashTable. */
+
+uint32 silc_hash_ptr(void *key)
+{
+ return (uint32)key;
+}
+
+/* Hash a Server ID. */
+
+uint32 silc_hash_server_id(void *key)
+{
+ SilcServerID *id = (SilcServerID *)key;
+ int i;
+ uint32 h;
+
+ h = id->port * id->rnd;
+ for (i = 0; i < id->ip.data_len; i++)
+ h ^= id->ip.data[i];
+
+ return h;
+}
+
+/* Hash a Client ID. */
+
+uint32 silc_hash_client_id(void *key)
+{
+ SilcClientID *id = (SilcClientID *)key;
+ int i;
+ uint32 h;
+
+ h = id->rnd;
+ for (i = 0; i < sizeof(id->hash); i++)
+ h ^= id->hash[i];
+ for (i = 0; i < id->ip.data_len; i++)
+ h ^= id->ip.data[i];
+
+ return h;
+}
+
+/* Hash a Channel ID. */
+
+uint32 silc_hash_channel_id(void *key)
+{
+ SilcChannelID *id = (SilcChannelID *)key;
+ int i;
+ uint32 h;
+
+ h = id->port * id->rnd;
+ for (i = 0; i < id->ip.data_len; i++)
+ h ^= id->ip.data[i];
+
+ return h;
+}
int silc_string_match(const char *string1, const char *string2);
char *silc_get_username();
char *silc_get_real_name();
+uint32 silc_hash_string(void *key);
+uint32 silc_hash_uint(void *key);
+uint32 silc_hash_ptr(void *key);
+uint32 silc_hash_server_id(void *key);
+uint32 silc_hash_client_id(void *key);
+uint32 silc_hash_channel_id(void *key);
#endif