core: change type of hashtable key hash to unsigned long, return item pointer in functions hashtable_set(_with_size)

The key hash has been changed from unsigned int to unsigned long, and now the
callback can return any value (not only between 0 and size-1), the modulo is
computed after the call to the callback by the hashtable functions.

Functions hashtable_set and hashtable_set_with_size were returning 1 if OK,
0 if error. Now they return pointer to hashtable item, or NULL if error.
v2.8-utf8proc
Sebastien Helleu 2013-08-10 09:35:06 +02:00
parent e407c41c5c
commit d12c9efdbc
6 changed files with 105 additions and 80 deletions

View File

@ -3281,8 +3281,8 @@ Prototype:
struct t_hashtable *weechat_hashtable_new (int size,
const char *type_keys,
const char *type_values,
unsigned int (*callback_hash_key)(struct t_hashtable *hashtable,
const void *key),
unsigned long (*callback_hash_key)(struct t_hashtable *hashtable,
const void *key),
int (*callback_keycmp)(struct t_hashtable *hashtable,
const void *key1,
const void *key2));
@ -3343,7 +3343,7 @@ This function is not available in scripting API.
weechat_hashtable_set_with_size
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_New in version 0.3.3._
_New in version 0.3.3, updated in 0.4.2._
Add or update item in a hashtable with size for key and value.
@ -3351,9 +3351,9 @@ Prototype:
[source,C]
----------------------------------------
int weechat_hashtable_set_with_size (struct t_hashtable *hashtable,
const void *key, int key_size,
const void *value, int value_size);
struct t_hashtable_item *weechat_hashtable_set_with_size (struct t_hashtable *hashtable,
const void *key, int key_size,
const void *value, int value_size);
----------------------------------------
Arguments:
@ -3368,7 +3368,7 @@ Arguments:
Return value:
* 1 if ok, 0 if error
* pointer to item created/updated, NULL if error
C example:
@ -3384,7 +3384,7 @@ This function is not available in scripting API.
weechat_hashtable_set
^^^^^^^^^^^^^^^^^^^^^
_New in version 0.3.3._
_New in version 0.3.3, updated in 0.4.2._
Add or update item in a hashtable.
@ -3392,8 +3392,8 @@ Prototype:
[source,C]
----------------------------------------
int weechat_hashtable_set (struct t_hashtable *hashtable,
const void *key, const void *value);
struct t_hashtable_item *weechat_hashtable_set (struct t_hashtable *hashtable,
const void *key, const void *value);
----------------------------------------
Arguments:
@ -3404,7 +3404,7 @@ Arguments:
Return value:
* 1 if ok, 0 if error
* pointer to item created/updated, NULL if error
C example:

View File

@ -3320,8 +3320,8 @@ Prototype :
struct t_hashtable *weechat_hashtable_new (int size,
const char *type_keys,
const char *type_values,
unsigned int (*callback_hash_key)(struct t_hashtable *hashtable,
const void *key),
unsigned long (*callback_hash_key)(struct t_hashtable *hashtable,
const void *key),
int (*callback_keycmp)(struct t_hashtable *hashtable,
const void *key1,
const void *key2));
@ -3384,7 +3384,7 @@ Cette fonction n'est pas disponible dans l'API script.
weechat_hashtable_set_with_size
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_Nouveau dans la version 0.3.3._
_Nouveau dans la version 0.3.3, mis à jour dans la 0.4.2._
Ajoute ou met à jour une entrée dans une hashtable avec une taille pour la clé
et la valeur.
@ -3393,9 +3393,9 @@ Prototype :
[source,C]
----------------------------------------
int weechat_hashtable_set_with_size (struct t_hashtable *hashtable,
const void *key, int key_size,
const void *value, int value_size);
struct t_hashtable_item *weechat_hashtable_set_with_size (struct t_hashtable *hashtable,
const void *key, int key_size,
const void *value, int value_size);
----------------------------------------
Paramètres :
@ -3410,7 +3410,7 @@ Paramètres :
Valeur de retour :
* 1 si ok, 0 en cas d'erreur
* pointeur vers l'item créé/mis à jour, NULL en cas d'erreur
Exemple en C :
@ -3426,7 +3426,7 @@ Cette fonction n'est pas disponible dans l'API script.
weechat_hashtable_set
^^^^^^^^^^^^^^^^^^^^^
_Nouveau dans la version 0.3.3._
_Nouveau dans la version 0.3.3, mis à jour dans la 0.4.2._
Ajoute ou met à jour une entrée dans la hashtable.
@ -3434,8 +3434,8 @@ Prototype :
[source,C]
----------------------------------------
int weechat_hashtable_set (struct t_hashtable *hashtable,
const void *key, const void *value);
struct t_hashtable_item *weechat_hashtable_set (struct t_hashtable *hashtable,
const void *key, const void *value);
----------------------------------------
Paramètres :
@ -3446,7 +3446,7 @@ Paramètres :
Valeur de retour :
* 1 si ok, 0 en cas d'erreur
* pointeur vers l'item créé/mis à jour, NULL en cas d'erreur
Exemple en C :

View File

@ -3284,8 +3284,8 @@ Prototipo:
struct t_hashtable *weechat_hashtable_new (int size,
const char *type_keys,
const char *type_values,
unsigned int (*callback_hash_key)(struct t_hashtable *hashtable,
const void *key),
unsigned long (*callback_hash_key)(struct t_hashtable *hashtable,
const void *key),
int (*callback_keycmp)(struct t_hashtable *hashtable,
const void *key1,
const void *key2));
@ -3348,7 +3348,8 @@ Questa funzione non è disponibile nelle API per lo scripting.
weechat_hashtable_set_with_size
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_Novità nella versione 0.3.3._
// TRANSLATION MISSING
_Novità nella versione 0.3.3, updated in 0.4.2._
Aggiunge o aggiorna un elemento nella tabella hash con la dimensione per la
chiave ed il valore.
@ -3357,9 +3358,9 @@ Prototipo:
[source,C]
----------------------------------------
int weechat_hashtable_set_with_size (struct t_hashtable *hashtable,
const void *key, int key_size,
const void *value, int value_size);
struct t_hashtable_item *weechat_hashtable_set_with_size (struct t_hashtable *hashtable,
const void *key, int key_size,
const void *value, int value_size);
----------------------------------------
Argomenti:
@ -3374,7 +3375,8 @@ Argomenti:
Valore restituito:
* 1 se ok, 0 in caso di errore
// TRANSLATION MISSING
* pointer to item created/updated, NULL if error
Esempio in C:
@ -3390,7 +3392,8 @@ Questa funzione non è disponibile nelle API per lo scripting.
weechat_hashtable_set
^^^^^^^^^^^^^^^^^^^^^
_Novità nella versione 0.3.3._
// TRANSLATION MISSING
_Novità nella versione 0.3.3, updated in 0.4.2._
Aggiunge o aggiorna un elemento nella tabella hash.
@ -3398,8 +3401,8 @@ Prototipo:
[source,C]
----------------------------------------
int weechat_hashtable_set (struct t_hashtable *hashtable,
const void *key, const void *value);
struct t_hashtable_item *weechat_hashtable_set (struct t_hashtable *hashtable,
const void *key, const void *value);
----------------------------------------
Argomenti:
@ -3410,7 +3413,8 @@ Argomenti:
Valore restituito:
* 1 se ok, 0 in caso di errore
// TRANSLATION MISSING
* pointer to item created/updated, NULL if error
Esempio in C:

View File

@ -67,16 +67,36 @@ hashtable_get_type (const char *type)
}
/*
* Hashes a key (default callback).
* Hashes a string using a variant of djb2 hash.
*
* Returns an unsigned integer between 0 and size-1.
* Returns the hash of the string.
*/
unsigned int
unsigned long
hashtable_hash_key_djb2 (const char *string)
{
unsigned long hash;
const char *ptr_string;
hash = 5381;
for (ptr_string = string; ptr_string[0]; ptr_string++)
{
hash ^= (hash << 5) + (hash >> 2) + (int)(ptr_string[0]);
}
return hash;
}
/*
* Hashes a key (default callback).
*
* Returns the hash of the key, depending on the type.
*/
unsigned long
hashtable_hash_key_default_cb (struct t_hashtable *hashtable, const void *key)
{
unsigned long hash;
const char *ptr_key;
hash = 0;
@ -86,12 +106,7 @@ hashtable_hash_key_default_cb (struct t_hashtable *hashtable, const void *key)
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]);
}
hash = hashtable_hash_key_djb2 ((const char *)key);
break;
case HASHTABLE_POINTER:
hash = (unsigned long)((void *)key);
@ -105,7 +120,7 @@ hashtable_hash_key_default_cb (struct t_hashtable *hashtable, const void *key)
break;
}
return hash % hashtable->size;
return hash;
}
/*
@ -352,28 +367,26 @@ hashtable_free_value (struct t_hashtable *hashtable,
*
* The size arguments are used only for type "buffer".
*
* Returns:
* 1: OK
* 0: error
* Returns pointer to item created/updated, NULL if error.
*/
int
struct t_hashtable_item *
hashtable_set_with_size (struct t_hashtable *hashtable,
const void *key, int key_size,
const void *value, int value_size)
{
unsigned int hash;
unsigned long hash;
struct t_hashtable_item *ptr_item, *pos_item, *new_item;
if (!hashtable || !key
|| ((hashtable->type_keys == HASHTABLE_BUFFER) && (key_size <= 0))
|| ((hashtable->type_values == HASHTABLE_BUFFER) && (value_size <= 0)))
{
return 0;
return NULL;
}
/* search position for item in hashtable */
hash = hashtable->callback_hash_key (hashtable, key);
hash = hashtable->callback_hash_key (hashtable, key) % hashtable->size;
pos_item = NULL;
for (ptr_item = hashtable->htable[hash];
ptr_item
@ -390,13 +403,13 @@ hashtable_set_with_size (struct t_hashtable *hashtable,
hashtable_alloc_type (hashtable->type_values,
value, value_size,
&ptr_item->value, &ptr_item->value_size);
return 1;
return ptr_item;
}
/* create new item */
new_item = malloc (sizeof (*new_item));
if (!new_item)
return 0;
return NULL;
/* set key and value */
hashtable_alloc_type (hashtable->type_keys,
@ -428,7 +441,7 @@ hashtable_set_with_size (struct t_hashtable *hashtable,
hashtable->items_count++;
return 1;
return new_item;
}
/*
@ -437,12 +450,10 @@ hashtable_set_with_size (struct t_hashtable *hashtable,
* Note: this function can be called *only* if key AND value are *not* of type
* "buffer".
*
* Returns:
* 1: OK
* 0: error
* Returns pointer to item created/updated, NULL if error.
*/
int
struct t_hashtable_item *
hashtable_set (struct t_hashtable *hashtable,
const void *key, const void *value)
{
@ -458,15 +469,15 @@ hashtable_set (struct t_hashtable *hashtable,
struct t_hashtable_item *
hashtable_get_item (struct t_hashtable *hashtable, const void *key,
unsigned int *hash)
unsigned long *hash)
{
unsigned int key_hash;
unsigned long key_hash;
struct t_hashtable_item *ptr_item;
if (!hashtable || !key)
return NULL;
key_hash = hashtable->callback_hash_key (hashtable, key);
key_hash = hashtable->callback_hash_key (hashtable, key) % hashtable->size;
if (hash)
*hash = key_hash;
for (ptr_item = hashtable->htable[key_hash];
@ -1098,7 +1109,7 @@ hashtable_add_to_infolist (struct t_hashtable *hashtable,
void
hashtable_remove_item (struct t_hashtable *hashtable,
struct t_hashtable_item *item,
unsigned int hash)
unsigned long hash)
{
if (!hashtable || !item)
return;
@ -1128,7 +1139,7 @@ void
hashtable_remove (struct t_hashtable *hashtable, const void *key)
{
struct t_hashtable_item *ptr_item;
unsigned int hash;
unsigned long hash;
if (!hashtable || !key)
return;

View File

@ -23,8 +23,8 @@
struct t_hashtable;
struct t_infolist_item;
typedef unsigned int (t_hashtable_hash_key)(struct t_hashtable *hashtable,
const void *key);
typedef unsigned long (t_hashtable_hash_key)(struct t_hashtable *hashtable,
const void *key);
typedef int (t_hashtable_keycmp)(struct t_hashtable *hashtable,
const void *key1, const void *key2);
typedef void (t_hashtable_free_key)(struct t_hashtable *hashtable,
@ -40,9 +40,9 @@ typedef void (t_hashtable_map_string)(void *data,
/*
* Hashtable is a structure with an array "htable", each entry is a pointer
* to a linked list, and it is read with hashed key (as unsigned int).
* to a linked list, and it is read with hashed key (as unsigned long).
* Keys with same hashed key are grouped in a linked list pointed by htable.
* htable is not sorted, linked list is sorted.
* The htable is not sorted, the linked list is sorted.
*
* Example of a hashtable with size 8 and 6 items added inside, items are:
* "weechat", "fast", "light", "extensible", "chat", "client"
@ -112,16 +112,23 @@ struct t_hashtable
/* never asked) */
};
extern unsigned long hashtable_hash_key_djb2 (const char *string);
extern struct t_hashtable *hashtable_new (int size,
const char *type_keys,
const char *type_values,
t_hashtable_hash_key *hash_key_cb,
t_hashtable_keycmp *keycmp_cb);
extern int hashtable_set_with_size (struct t_hashtable *hashtable,
const void *key, int key_size,
const void *value, int value_size);
extern int hashtable_set (struct t_hashtable *hashtable, const void *key,
const void *value);
extern struct t_hashtable_item *hashtable_set_with_size (struct t_hashtable *hashtable,
const void *key,
int key_size,
const void *value,
int value_size);
extern struct t_hashtable_item *hashtable_set (struct t_hashtable *hashtable,
const void *key,
const void *value);
extern struct t_hashtable_item *hashtable_get_item (struct t_hashtable *hashtable,
const void *key,
unsigned long *hash);
extern void *hashtable_get (struct t_hashtable *hashtable, const void *key);
extern int hashtable_has_key (struct t_hashtable *hashtable, const void *key);
extern void hashtable_map (struct t_hashtable *hashtable,

View File

@ -52,7 +52,7 @@ struct timeval;
* please change the date with current one; for a second change at same
* date, increment the 01, otherwise please keep 01.
*/
#define WEECHAT_PLUGIN_API_VERSION "20130804-01"
#define WEECHAT_PLUGIN_API_VERSION "20130810-01"
/* macros for defining plugin infos */
#define WEECHAT_PLUGIN_NAME(__name) \
@ -323,16 +323,19 @@ struct t_weechat_plugin
struct t_hashtable *(*hashtable_new) (int size,
const char *type_keys,
const char *type_values,
unsigned int (*callback_hash_key)(struct t_hashtable *hashtable,
const void *key),
unsigned long (*callback_hash_key)(struct t_hashtable *hashtable,
const void *key),
int (*callback_keycmp)(struct t_hashtable *hashtable,
const void *key1,
const void *key2));
int (*hashtable_set_with_size) (struct t_hashtable *hashtable,
const void *key, int key_size,
const void *value, int value_size);
int (*hashtable_set) (struct t_hashtable *hashtable, const void *key,
const void *value);
struct t_hashtable_item *(*hashtable_set_with_size) (struct t_hashtable *hashtable,
const void *key,
int key_size,
const void *value,
int value_size);
struct t_hashtable_item *(*hashtable_set) (struct t_hashtable *hashtable,
const void *key,
const void *value);
void *(*hashtable_get) (struct t_hashtable *hashtable, const void *key);
int (*hashtable_has_key) (struct t_hashtable *hashtable, const void *key);
void (*hashtable_map) (struct t_hashtable *hashtable,