core: use default hash/comparison callback for keys of type integer/pointer/time in hashtable

v2.8-utf8proc
Sebastien Helleu 2013-01-26 18:48:26 +01:00
parent a5aaed89d2
commit f4dce04723
6 changed files with 100 additions and 44 deletions

View File

@ -1,12 +1,14 @@
WeeChat ChangeLog
=================
Sébastien Helleu <flashcode@flashtux.org>
v0.4.1-dev, 2013-01-25
v0.4.1-dev, 2013-01-26
Version 0.4.1 (under dev!)
--------------------------
* core: use default hash/comparison callback for keys of type
integer/pointer/time in hashtable
* guile: fix compilation with guile 2.0
* irc: add color in output of /names when result is on server buffer (channel
not joined) (bug #38070)

View File

@ -3248,14 +3248,14 @@ Arguments:
** 'WEECHAT_HASHTABLE_BUFFER'
** 'WEECHAT_HASHTABLE_TIME'
* 'callback_hash_key': callback used to "hash" a key (key as integer value), can
be NULL if key type is "string" (a default function is used for strings, and
only for strings), arguments and return value:
be NULL if key type is not "buffer" (a default hash function is used),
arguments and return value:
** 'struct t_hashtable *hashtable': hashtable pointer
** 'const void *key': key
** return value: hash of the key
* 'callback_keycmp': callback used to compare two keys, can be NULL if value
type is "string" (a default comparison function is used for strings, and only
for strings), arguments and return value:
* 'callback_keycmp': callback used to compare two keys, can be NULL if key type
is not "buffer" (a default comparison function is used), arguments and return
value:
** 'struct t_hashtable *hashtable': hashtable pointer
** 'const void *key1': first key
** 'const void *key2': second key

View File

@ -3287,15 +3287,15 @@ Paramètres :
** 'WEECHAT_HASHTABLE_BUFFER'
** 'WEECHAT_HASHTABLE_TIME'
* 'callback_hash_key' : fonction appelée pour rendre le "hash" d'une clé (la clé
sous forme de nombre entier), peut être NULL si le type de clé est "string"
(une fonction par défaut est utilisée pour les chaînes, et seulement pour les
chaînes). Paramètres et valeur de retour :
sous forme de nombre entier), peut être NULL si le type de clé n'est pas
"buffer" (une fonction de hash par défaut est utilisée), paramètres et valeur
de retour :
** 'struct t_hashtable *hashtable' : pointeur vers la hashtable
** 'const void *key' : clé
** valeur de retour : "hash" de la clé
* 'callback_keycmp' : fonction appelée pour comparer deux clés, peut être NULL
si le type de valeur est "string" (une fonction par défaut est utilisée pour
les chaînes, et seulement pour les chaînes). Paramètres et valeur de retour :
si le type de clé n'est pas "buffer" (une fonction de comparaison par défaut
est utilisée), paramètres et valeur de retour :
** 'struct t_hashtable *hashtable' : pointeur vers la hashtable
** 'const void *key1' : première clé
** 'const void *key2' : seconde clé

View File

@ -3246,16 +3246,17 @@ Argomenti:
** 'WEECHAT_HASHTABLE_POINTER'
** 'WEECHAT_HASHTABLE_BUFFER'
** 'WEECHAT_HASHTABLE_TIME'
* 'callback_hash_key': callback utilizzata per effettuare un "hash" di una
chiave (chiave come valore intero), può essere NULL se il tipo della chiave è
"string" (viene usata una funzione predefinita per le stringhe, e solo per le
stringhe), argomenti e valore restituito:
// TRANSLATION MISSING
* 'callback_hash_key': callback used to "hash" a key (key as integer value), can
be NULL if key type is not "buffer" (a default hash function is used),
arguments and return value:
** 'struct t_hashtable *hashtable': puntatore alla tabella hash
** 'const void *key': chiave
** return value: hash della chiave
* 'callback_keycmp': callback utilizzata per comparare due chiavi, può essere
NULL se il tipo di valore è "string" (una funzione di confronto predefinita è
usata per le stringhe e solo per le stringhe), argomenti e valore restituito:
// TRANSLATION MISSING
* 'callback_keycmp': callback used to compare two keys, can be NULL if key type
is not "buffer" (a default comparison function is used), arguments and return
value:
** 'struct t_hashtable *hashtable': puntatore alla tabella hash
** 'const void *key1': prima chiave
** 'const void *key2': seconda chiave

View File

@ -67,43 +67,97 @@ hashtable_get_type (const char *type)
}
/*
* Hashes a string key (default callback).
* Hashes a key (default callback).
*
* Returns an unsigned integer between 0 and size-1.
*/
unsigned int
hashtable_hash_key_string_cb (struct t_hashtable *hashtable, const void *key)
hashtable_hash_key_default_cb (struct t_hashtable *hashtable, const void *key)
{
const char *ptr_key;
unsigned long hash;
const char *ptr_key;
/* variant of djb2 hash */
hash = 5381;
for (ptr_key = (const char *)key; ptr_key[0]; ptr_key++)
hash = 0;
switch (hashtable->type_keys)
{
hash ^= (hash << 5) + (hash >> 2) + (int)(ptr_key[0]);
case HASHTABLE_INTEGER:
hash = (unsigned long)(*((int *)key));
break;
case HASHTABLE_STRING:
/* variant of djb2 hash */
hash = 5381;
for (ptr_key = (const char *)key; ptr_key[0]; ptr_key++)
{
hash ^= (hash << 5) + (hash >> 2) + (int)(ptr_key[0]);
}
break;
case HASHTABLE_POINTER:
hash = (unsigned long)((void *)key);
break;
case HASHTABLE_BUFFER:
break;
case HASHTABLE_TIME:
hash = (unsigned long)(*((time_t *)key));
break;
case HASHTABLE_NUM_TYPES:
break;
}
return hash % hashtable->size;
}
/*
* Compares two string keys (default callback).
* Compares two keys (default callback).
*
* Returns:
* -1: key1 < key2
* 0: key1 == key2
* 1: key1 > key2
* < 0: key1 < key2
* 0: key1 == key2
* > 0: key1 > key2
*/
int
hashtable_keycmp_string_cb (struct t_hashtable *hashtable,
const void *key1, const void *key2)
hashtable_keycmp_default_cb (struct t_hashtable *hashtable,
const void *key1, const void *key2)
{
int rc;
/* make C compiler happy */
(void) hashtable;
return strcmp ((const char *)key1, (const char *)key2);
rc = 0;
switch (hashtable->type_keys)
{
case HASHTABLE_INTEGER:
if (*((int *)key1) < *((int *)key2))
rc = -1;
else if (*((int *)key1) > *((int *)key2))
rc = 1;
break;
case HASHTABLE_STRING:
rc = strcmp ((const char *)key1, (const char *)key2);
break;
case HASHTABLE_POINTER:
if (key1 < key2)
rc = -1;
else if (key1 > key2)
rc = 1;
break;
case HASHTABLE_BUFFER:
break;
case HASHTABLE_TIME:
if (*((time_t *)key1) < *((time_t *)key2))
rc = -1;
else if (*((time_t *)key1) > *((time_t *)key2))
rc = 1;
break;
case HASHTABLE_NUM_TYPES:
break;
}
return rc;
}
/*
@ -126,6 +180,9 @@ hashtable_new (int size,
struct t_hashtable *new_hashtable;
int i, type_keys_int, type_values_int;
if (size <= 0)
return NULL;
type_keys_int = hashtable_get_type (type_keys);
if (type_keys_int < 0)
return NULL;
@ -133,7 +190,8 @@ hashtable_new (int size,
if (type_values_int < 0)
return NULL;
if ((type_keys_int != HASHTABLE_STRING) && (!callback_hash_key || !callback_keycmp))
/* the two callbacks are mandatory if type of keys is "buffer" */
if ((type_keys_int == HASHTABLE_BUFFER) && (!callback_hash_key || !callback_keycmp))
return NULL;
new_hashtable = malloc (sizeof (*new_hashtable));
@ -155,15 +213,10 @@ hashtable_new (int size,
}
new_hashtable->items_count = 0;
if ((type_keys_int == HASHTABLE_STRING) && !callback_hash_key)
new_hashtable->callback_hash_key = &hashtable_hash_key_string_cb;
else
new_hashtable->callback_hash_key = callback_hash_key;
if ((type_keys_int == HASHTABLE_STRING) && !callback_keycmp)
new_hashtable->callback_keycmp = &hashtable_keycmp_string_cb;
else
new_hashtable->callback_keycmp = callback_keycmp;
new_hashtable->callback_hash_key = (callback_hash_key) ?
callback_hash_key : &hashtable_hash_key_default_cb;
new_hashtable->callback_keycmp = (callback_keycmp) ?
callback_keycmp : &hashtable_keycmp_default_cb;
new_hashtable->callback_free_value = NULL;
}

View File

@ -57,13 +57,13 @@ typedef void (t_hashtable_map_string)(void *data,
* +-----+
* | 3 | --> "fast" --> "light"
* +-----+
* | 4 | --> "weechat"
* | 4 |
* +-----+
* | 5 | --> "chat"
* +-----+
* | 6 | --> "client"
* +-----+
* | 7 |
* | 7 | --> "weechat"
* +-----+
*/