core: use default hash/comparison callback for keys of type integer/pointer/time in hashtable
parent
a5aaed89d2
commit
f4dce04723
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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é
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
* +-----+
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue