Add hashtable in core and plugin API
parent
ff97274bca
commit
cb18bdb10b
|
@ -2541,6 +2541,305 @@ weechat.list_free(list)
|
|||
weechat.list_free(list)
|
||||
----------------------------------------
|
||||
|
||||
[[hashtables]]
|
||||
Hashtables
|
||||
~~~~~~~~~~
|
||||
|
||||
Hashtable functions.
|
||||
|
||||
weechat_hashtable_new
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Create a new hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
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),
|
||||
int (*callback_keycmp)(struct t_hashtable *hashtable,
|
||||
const void *key1,
|
||||
const void *key2));
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'size': size of internal array to store hashed keys, a high value uses more
|
||||
memory, but has better performance (this is *not* a limit for number of items
|
||||
in hashtable)
|
||||
* 'type_keys': type for keys in hashtable:
|
||||
** 'WEECHAT_HASHTABLE_INTEGER'
|
||||
** 'WEECHAT_HASHTABLE_STRING'
|
||||
** 'WEECHAT_HASHTABLE_POINTER'
|
||||
** 'WEECHAT_HASHTABLE_BUFFER'
|
||||
** 'WEECHAT_HASHTABLE_TIME'
|
||||
* 'type_values': type for values in hashtable:
|
||||
** 'WEECHAT_HASHTABLE_INTEGER'
|
||||
** 'WEECHAT_HASHTABLE_STRING'
|
||||
** 'WEECHAT_HASHTABLE_POINTER'
|
||||
** '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)
|
||||
* '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)
|
||||
|
||||
Return value:
|
||||
|
||||
* pointer to new hashtable, NULL if an error occured
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
struct t_hashtable *hashtable = weechat_hashtable_new (8,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL,
|
||||
NULL);
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_set_with_size
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Add or update item in a hashtable with size for key and value.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int weechat_hashtable_set_with_size (struct t_hashtable *hashtable,
|
||||
void *key, int key_size,
|
||||
void *value, int value_size);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'key': key pointer
|
||||
* 'key_size': size of key (in bytes), used only if type of keys in hashtable
|
||||
is "buffer"
|
||||
* 'value': value pointer
|
||||
* 'value_size': size of value (in bytes), used only if type of values in
|
||||
hashtable is "buffer"
|
||||
|
||||
Return value:
|
||||
|
||||
* 1 if ok, 0 if error
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_set_with_size (hashtable, "my_key", 0,
|
||||
my_buffer, sizeof (my_buffer_struct));
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_set
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Add or update item in a hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int weechat_hashtable_set (struct t_hashtable *hashtable,
|
||||
void *key, void *value);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'key': key pointer
|
||||
* 'value': value pointer
|
||||
|
||||
Return value:
|
||||
|
||||
* 1 if ok, 0 if error
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_set (hashtable, "my_key", "my_value");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_get
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Get value associated with a key in a hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void *weechat_hashtable_get (struct t_hashtable *hashtable, void *key);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'key': key pointer
|
||||
|
||||
Return value:
|
||||
|
||||
* value for key, NULL if key is not found
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void *value = weechat_hashtable_get (hashtable, "my_key");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_map
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Call a function on all hashtable entries.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void hashtable_map (struct t_hashlist *hashlist,
|
||||
int (*callback_map)(void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key,
|
||||
const void *value),
|
||||
void *callback_map_data);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'callback_map': function called for each entry in hashtable
|
||||
* 'callback_map_data': pointer given to map callback when it is called
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void
|
||||
map_cb (void *data, struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
/* display key and value (they are both strings here) */
|
||||
weechat_printf (NULL, "key: '%s', value: '%s'",
|
||||
(const char *)key,
|
||||
(const char *)value);
|
||||
}
|
||||
/* ... */
|
||||
weechat_hashtable_map (hashtable, &map_cb, NULL);
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_get_integer
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Return integer value of a hashtable property.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int weechat_hashtable_get_integer (struct t_hashtable *hashtable,
|
||||
void *property);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'property': property name:
|
||||
** 'size': size of internal array "htable" in hashtable
|
||||
** 'items_count': number of items in hashtable
|
||||
|
||||
Return value:
|
||||
|
||||
* integer value of property
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int items_count = weechat_hashtable_get_integer (hashtable, "items_count");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_remove
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Remove an item in a hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void weechat_hashtable_remove (struct t_hashtable *hashtable, const void *key);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'key': key pointer
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_remove (hashtable, "my_key");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_remove_all
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Remove all items in a hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void weechat_hashtable_remove_all (struct t_hashtable *hashtable);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_remove_all (hashtable);
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_free
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Free a hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void weechat_hashtable_free (struct t_hashtable *hashtable);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_free (hashtable);
|
||||
----------------------------------------
|
||||
|
||||
[[configuration_files]]
|
||||
Configuration files
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -2567,6 +2567,308 @@ weechat.list_free(list)
|
|||
weechat.list_free(list)
|
||||
----------------------------------------
|
||||
|
||||
[[hashtables]]
|
||||
Hashtables
|
||||
~~~~~~~~~~
|
||||
|
||||
Hashtable functions.
|
||||
|
||||
weechat_hashtable_new
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Crée une nouvelle hashtable.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
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),
|
||||
int (*callback_keycmp)(struct t_hashtable *hashtable,
|
||||
const void *key1,
|
||||
const void *key2));
|
||||
----------------------------------------
|
||||
|
||||
Paramètres :
|
||||
|
||||
* 'size' : taille du tableau interne pour stocker les clés sous forme de "hash",
|
||||
une grande valeur utilise plus de mémoire mais présente une meilleure
|
||||
performance (cela n'est *pas* une limite sur le nombre d'entrées de la
|
||||
hashtable)
|
||||
* 'type_keys' : type pour les clés dans la hashtable :
|
||||
** 'WEECHAT_HASHTABLE_INTEGER'
|
||||
** 'WEECHAT_HASHTABLE_STRING'
|
||||
** 'WEECHAT_HASHTABLE_POINTER'
|
||||
** 'WEECHAT_HASHTABLE_BUFFER'
|
||||
** 'WEECHAT_HASHTABLE_TIME'
|
||||
* 'type_values' : type pour les valeurs dans la hashtable :
|
||||
** 'WEECHAT_HASHTABLE_INTEGER'
|
||||
** 'WEECHAT_HASHTABLE_STRING'
|
||||
** 'WEECHAT_HASHTABLE_POINTER'
|
||||
** '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)
|
||||
* '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)
|
||||
|
||||
Valeur de retour :
|
||||
|
||||
* pointeur vers la nouvelle hashtable, NULL en cas d'erreur
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
struct t_hashtable *hashtable = weechat_hashtable_new (8,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL,
|
||||
NULL);
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_set_with_size
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Ajoute ou met à jour une entrée dans une hashtable avec une taille pour la clé
|
||||
et la valeur.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int weechat_hashtable_set_with_size (struct t_hashtable *hashtable,
|
||||
void *key, int key_size,
|
||||
void *value, int value_size);
|
||||
----------------------------------------
|
||||
|
||||
Paramètres :
|
||||
|
||||
* 'hashtable' : pointeur vers la hashtable
|
||||
* 'key' : pointeur vers la clé
|
||||
* 'key_size' : taille de la clé (en octets), utilisée seulement si le type de
|
||||
clés dans la hashtable est "buffer"
|
||||
* 'value' : pointeur vers la valeur
|
||||
* 'value_size' : taille de la valeur (en octets), utilisée seulement si le type
|
||||
de valeurs dans la hashtable est "buffer"
|
||||
|
||||
Valeur de retour :
|
||||
|
||||
* 1 si ok, 0 en cas d'erreur
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_set_with_size (hashtable, "ma_cle", 0,
|
||||
my_buffer, sizeof (my_buffer_struct));
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_set
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Ajoute ou met à jour une entrée dans la hashtable.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int weechat_hashtable_set (struct t_hashtable *hashtable,
|
||||
void *key, void *value);
|
||||
----------------------------------------
|
||||
|
||||
Paramètres :
|
||||
|
||||
* 'hashtable' : pointeur vers la hashtable
|
||||
* 'key' : pointeur vers la clé
|
||||
* 'value' : pointeur vers la valeur
|
||||
|
||||
Valeur de retour :
|
||||
|
||||
* 1 si ok, 0 en cas d'erreur
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_set (hashtable, "ma_cle", "ma_valeur");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_get
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Retourne la valeur associée à une clé dans une hashtable.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void *weechat_hashtable_get (struct t_hashtable *hashtable, void *key);
|
||||
----------------------------------------
|
||||
|
||||
Paramètres :
|
||||
|
||||
* 'hashtable' : pointeur vers la hashtable
|
||||
* 'key' : pointeur vers la clé
|
||||
|
||||
Valeur en retour :
|
||||
|
||||
* valeur pour la clé, NULL si la clé n'est pas trouvée
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void *value = weechat_hashtable_get (hashtable, "ma_cle");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_map
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Appelle une fonction pour chaque entrée d'une hashtable.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void hashtable_map (struct t_hashlist *hashlist,
|
||||
int (*callback_map)(void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key,
|
||||
const void *value),
|
||||
void *callback_map_data);
|
||||
----------------------------------------
|
||||
|
||||
Paramètres :
|
||||
|
||||
* 'hashtable' : pointeur vers la hashtable
|
||||
* 'callback_map' : fonction appelée pour chaque entrée de la hashtable
|
||||
* 'callback_map_data' : pointeur donné au "callback" lorsqu'il est appelé
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void
|
||||
map_cb (void *data, struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
/* afficher la clé et la valeur (elles sont des chaînes ici) */
|
||||
weechat_printf (NULL, "clé: '%s', valeur: '%s'",
|
||||
(const char *)key,
|
||||
(const char *)value);
|
||||
}
|
||||
/* ... */
|
||||
weechat_hashtable_map (hashtable, &map_cb, NULL);
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_get_integer
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Retourne une valeur entière pour une propriété d'une hashtable.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int weechat_hashtable_get_integer (struct t_hashtable *hashtable,
|
||||
void *property);
|
||||
----------------------------------------
|
||||
|
||||
Paramètres :
|
||||
|
||||
* 'hashtable' : pointeur vers la hashtable
|
||||
* 'property' : nom de propriété :
|
||||
** 'size' : taille du tableau interne "htable" dans la hashtable
|
||||
** 'items_count' : nombre d'éléments dans la hashtable
|
||||
|
||||
Valeur en retour :
|
||||
|
||||
* valeur entière de l'option
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int items_count = weechat_hashtable_get_integer (hashtable, "items_count");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_remove
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Supprime un élément d'une hashtable.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void weechat_hashtable_remove (struct t_hashtable *hashtable, const void *key);
|
||||
----------------------------------------
|
||||
|
||||
Paramètres :
|
||||
|
||||
* 'hashtable' : pointeur vers la hashtable
|
||||
* 'key' : pointeur vers la clé
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_remove (hashtable, "ma_cle");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_remove_all
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Supprime tous les éléments d'une hashtable.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void weechat_hashtable_remove_all (struct t_hashtable *hashtable);
|
||||
----------------------------------------
|
||||
|
||||
Paramètres :
|
||||
|
||||
* 'hashtable' : pointeur vers la hashtable
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_remove_all (hashtable);
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_free
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Supprime une hashtable.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void weechat_hashtable_free (struct t_hashtable *hashtable);
|
||||
----------------------------------------
|
||||
|
||||
Paramètres :
|
||||
|
||||
* 'hashtable' : pointeur vers la hashtable
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_free (hashtable);
|
||||
----------------------------------------
|
||||
|
||||
[[configuration_files]]
|
||||
Fichiers de configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -2579,6 +2579,305 @@ weechat.list_free(list)
|
|||
weechat.list_free(list)
|
||||
----------------------------------------
|
||||
|
||||
[[hashtables]]
|
||||
Hashtables
|
||||
~~~~~~~~~~
|
||||
|
||||
Hashtable functions.
|
||||
|
||||
weechat_hashtable_new
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Create a new hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
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),
|
||||
int (*callback_keycmp)(struct t_hashtable *hashtable,
|
||||
const void *key1,
|
||||
const void *key2));
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'size': size of internal array to store hashed keys, a high value uses more
|
||||
memory, but has better performance (this is *not* a limit for number of items
|
||||
in hashtable)
|
||||
* 'type_keys': type for keys in hashtable:
|
||||
** 'WEECHAT_HASHTABLE_INTEGER'
|
||||
** 'WEECHAT_HASHTABLE_STRING'
|
||||
** 'WEECHAT_HASHTABLE_POINTER'
|
||||
** 'WEECHAT_HASHTABLE_BUFFER'
|
||||
** 'WEECHAT_HASHTABLE_TIME'
|
||||
* 'type_values': type for values in hashtable:
|
||||
** 'WEECHAT_HASHTABLE_INTEGER'
|
||||
** 'WEECHAT_HASHTABLE_STRING'
|
||||
** 'WEECHAT_HASHTABLE_POINTER'
|
||||
** '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)
|
||||
* '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)
|
||||
|
||||
Return value:
|
||||
|
||||
* pointer to new hashtable, NULL if an error occured
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
struct t_hashtable *hashtable = weechat_hashtable_new (8,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL,
|
||||
NULL);
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_set_with_size
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Add or update item in a hashtable with size for key and value.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int weechat_hashtable_set_with_size (struct t_hashtable *hashtable,
|
||||
void *key, int key_size,
|
||||
void *value, int value_size);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'key': key pointer
|
||||
* 'key_size': size of key (in bytes), used only if type of keys in hashtable
|
||||
is "buffer"
|
||||
* 'value': value pointer
|
||||
* 'value_size': size of value (in bytes), used only if type of values in
|
||||
hashtable is "buffer"
|
||||
|
||||
Return value:
|
||||
|
||||
* 1 if ok, 0 if error
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_set_with_size (hashtable, "my_key", 0,
|
||||
my_buffer, sizeof (my_buffer_struct));
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_set
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Add or update item in a hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int weechat_hashtable_set (struct t_hashtable *hashtable,
|
||||
void *key, void *value);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'key': key pointer
|
||||
* 'value': value pointer
|
||||
|
||||
Return value:
|
||||
|
||||
* 1 if ok, 0 if error
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_set (hashtable, "my_key", "my_value");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_get
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Get value associated with a key in a hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void *weechat_hashtable_get (struct t_hashtable *hashtable, void *key);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'key': key pointer
|
||||
|
||||
Return value:
|
||||
|
||||
* value for key, NULL if key is not found
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void *value = weechat_hashtable_get (hashtable, "my_key");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_map
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Call a function on all hashtable entries.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void hashtable_map (struct t_hashlist *hashlist,
|
||||
int (*callback_map)(void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key,
|
||||
const void *value),
|
||||
void *callback_map_data);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'callback_map': function called for each entry in hashtable
|
||||
* 'callback_map_data': pointer given to map callback when it is called
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void
|
||||
map_cb (void *data, struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
/* display key and value (they are both strings here) */
|
||||
weechat_printf (NULL, "key: '%s', value: '%s'",
|
||||
(const char *)key,
|
||||
(const char *)value);
|
||||
}
|
||||
/* ... */
|
||||
weechat_hashtable_map (hashtable, &map_cb, NULL);
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_get_integer
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Return integer value of a hashtable property.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int weechat_hashtable_get_integer (struct t_hashtable *hashtable,
|
||||
void *property);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'property': property name:
|
||||
** 'size': size of internal array "htable" in hashtable
|
||||
** 'items_count': number of items in hashtable
|
||||
|
||||
Return value:
|
||||
|
||||
* integer value of property
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
int items_count = weechat_hashtable_get_integer (hashtable, "items_count");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_remove
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Remove an item in a hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void weechat_hashtable_remove (struct t_hashtable *hashtable, const void *key);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
* 'key': key pointer
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_remove (hashtable, "my_key");
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_remove_all
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Remove all items in a hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void weechat_hashtable_remove_all (struct t_hashtable *hashtable);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_remove_all (hashtable);
|
||||
----------------------------------------
|
||||
|
||||
weechat_hashtable_free
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Free a hashtable.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
void weechat_hashtable_free (struct t_hashtable *hashtable);
|
||||
----------------------------------------
|
||||
|
||||
Arguments:
|
||||
|
||||
* 'hashtable': hashtable pointer
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----------------------------------------
|
||||
weechat_hashtable_free (hashtable);
|
||||
----------------------------------------
|
||||
|
||||
[[configuration_files]]
|
||||
File di configurazione
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -26,6 +26,7 @@ wee-command.c wee-command.h
|
|||
wee-config.c wee-config.h
|
||||
wee-config-file.c wee-config-file.h
|
||||
wee-debug.c wee-debug.h
|
||||
wee-hashtable.c wee-hashtable.h
|
||||
wee-hook.c wee-hook.h
|
||||
wee-infolist.c wee-infolist.h
|
||||
wee-input.c wee-input.h
|
||||
|
|
|
@ -33,6 +33,8 @@ lib_weechat_core_a_SOURCES = weechat.c \
|
|||
wee-config-file.h \
|
||||
wee-debug.c \
|
||||
wee-debug.h \
|
||||
wee-hashtable.c \
|
||||
wee-hashtable.h \
|
||||
wee-hook.c \
|
||||
wee-hook.h \
|
||||
wee-infolist.c \
|
||||
|
|
|
@ -0,0 +1,549 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* wee-hashtable.c: implementation of hashtable
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "weechat.h"
|
||||
#include "wee-hashtable.h"
|
||||
#include "wee-log.h"
|
||||
#include "wee-string.h"
|
||||
#include "../plugins/weechat-plugin.h"
|
||||
|
||||
|
||||
char *hashtable_type_names[HASHTABLE_NUM_TYPES] =
|
||||
{ "integer", "string", "pointer", "buffer", "time" };
|
||||
|
||||
|
||||
/*
|
||||
* hashtable_get_type: get integer for type (string)
|
||||
*/
|
||||
|
||||
int
|
||||
hashtable_get_type (const char *type)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!type)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < HASHTABLE_NUM_TYPES; i++)
|
||||
{
|
||||
if (string_strcasecmp (hashtable_type_names[i], type) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
/* type not found */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_hash_key_string_cb: default callback to hash a string key
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
hashtable_hash_key_string_cb (struct t_hashtable *hashtable, const void *key)
|
||||
{
|
||||
const char *ptr_key;
|
||||
unsigned long hash;
|
||||
|
||||
/* 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]);
|
||||
}
|
||||
return hash % hashtable->size;
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_keycmp_string_cb: default callback for string comparison on keys
|
||||
*/
|
||||
|
||||
int
|
||||
hashtable_keycmp_string_cb (struct t_hashtable *hashtable,
|
||||
const void *key1, const void *key2)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) hashtable;
|
||||
|
||||
return strcmp ((const char *)key1, (const char *)key2);
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_new: create a new hash table
|
||||
*/
|
||||
|
||||
struct t_hashtable *
|
||||
hashtable_new (int size,
|
||||
const char *type_keys, const char *type_values,
|
||||
t_hashtable_hash_key *callback_hash_key,
|
||||
t_hashtable_keycmp *callback_keycmp)
|
||||
{
|
||||
struct t_hashtable *new_hashtable;
|
||||
int i, type_keys_int, type_values_int;
|
||||
|
||||
type_keys_int = hashtable_get_type (type_keys);
|
||||
if (type_keys_int < 0)
|
||||
return NULL;
|
||||
type_values_int = hashtable_get_type (type_values);
|
||||
if (type_values_int < 0)
|
||||
return NULL;
|
||||
|
||||
if ((type_keys_int != HASHTABLE_STRING) && (!callback_hash_key || !callback_keycmp))
|
||||
return NULL;
|
||||
|
||||
new_hashtable = malloc (sizeof (*new_hashtable));
|
||||
if (new_hashtable)
|
||||
{
|
||||
new_hashtable->size = size;
|
||||
new_hashtable->type_keys = type_keys_int;
|
||||
new_hashtable->type_values = type_values_int;
|
||||
new_hashtable->htable = malloc (size * sizeof (*(new_hashtable->htable)));
|
||||
if (!new_hashtable->htable)
|
||||
{
|
||||
free (new_hashtable);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
new_hashtable->htable[i] = NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return new_hashtable;
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_alloc_type: alloc space for a key or value
|
||||
*/
|
||||
|
||||
void
|
||||
hashtable_alloc_type (enum t_hashtable_type type, void *value, int size_value,
|
||||
void **pointer, int *size)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case HASHTABLE_INTEGER:
|
||||
*pointer = malloc (sizeof (int));
|
||||
if (*pointer)
|
||||
*((int *)(*pointer)) = *((int *)value);
|
||||
*size = (*pointer) ? sizeof (int) : 0;
|
||||
break;
|
||||
case HASHTABLE_STRING:
|
||||
*pointer = strdup ((const char *)value);
|
||||
*size = (*pointer) ? strlen (*pointer) + 1 : 0;
|
||||
break;
|
||||
case HASHTABLE_POINTER:
|
||||
*pointer = value;
|
||||
*size = sizeof (void *);
|
||||
break;
|
||||
case HASHTABLE_BUFFER:
|
||||
*pointer = malloc (size_value);
|
||||
if (*pointer)
|
||||
memcpy (*pointer, value, size_value);
|
||||
*size = (*pointer) ? size_value : 0;
|
||||
break;
|
||||
case HASHTABLE_TIME:
|
||||
*pointer = malloc (sizeof (time_t));
|
||||
if (*pointer)
|
||||
*((time_t *)(*pointer)) = *((time_t *)value);
|
||||
*size = (*pointer) ? sizeof (time_t) : 0;
|
||||
break;
|
||||
case HASHTABLE_NUM_TYPES:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_free_type: free space used by a key or value
|
||||
*/
|
||||
|
||||
void
|
||||
hashtable_free_type (enum t_hashtable_type type, void *value)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case HASHTABLE_INTEGER:
|
||||
case HASHTABLE_STRING:
|
||||
case HASHTABLE_BUFFER:
|
||||
case HASHTABLE_TIME:
|
||||
free (value);
|
||||
break;
|
||||
case HASHTABLE_POINTER:
|
||||
break;
|
||||
case HASHTABLE_NUM_TYPES:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_set_with_size: set value for item in hash table
|
||||
* argument size is used only for type "buffer"
|
||||
* return 1 if ok, 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
hashtable_set_with_size (struct t_hashtable *hashtable,
|
||||
void *key, int key_size,
|
||||
void *value, int value_size)
|
||||
{
|
||||
unsigned int hash;
|
||||
struct t_hashtable_item *ptr_item, *pos_item, *new_item;
|
||||
|
||||
if (!hashtable
|
||||
|| ((hashtable->type_keys == HASHTABLE_BUFFER) && (key_size <= 0))
|
||||
|| ((hashtable->type_values == HASHTABLE_BUFFER) && (value_size <= 0)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* search position for item in hash table */
|
||||
hash = hashtable->callback_hash_key (hashtable, key);
|
||||
pos_item = NULL;
|
||||
for (ptr_item = hashtable->htable[hash];
|
||||
ptr_item
|
||||
&& ((int)(hashtable->callback_keycmp) (hashtable, key, ptr_item->key) > 0);
|
||||
ptr_item = ptr_item->next_item)
|
||||
{
|
||||
pos_item = ptr_item;
|
||||
}
|
||||
|
||||
/* replace value if item is already in hash table */
|
||||
if (ptr_item && (hashtable->callback_keycmp (hashtable, key, ptr_item->key) == 0))
|
||||
{
|
||||
ptr_item->value = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* create new item */
|
||||
new_item = malloc (sizeof (*new_item));
|
||||
if (!new_item)
|
||||
return 0;
|
||||
|
||||
/* set key and value */
|
||||
hashtable_alloc_type (hashtable->type_keys,
|
||||
key, key_size,
|
||||
&new_item->key, &new_item->key_size);
|
||||
hashtable_alloc_type (hashtable->type_values,
|
||||
value, value_size,
|
||||
&new_item->value, &new_item->value_size);
|
||||
|
||||
/* add item */
|
||||
if (pos_item)
|
||||
{
|
||||
/* insert item after position found */
|
||||
new_item->prev_item = pos_item;
|
||||
new_item->next_item = pos_item->next_item;
|
||||
if (pos_item->next_item)
|
||||
(pos_item->next_item)->prev_item = new_item;
|
||||
pos_item->next_item = new_item;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* insert item at beginning of list */
|
||||
new_item->prev_item = NULL;
|
||||
new_item->next_item = hashtable->htable[hash];
|
||||
if (hashtable->htable[hash])
|
||||
(hashtable->htable[hash])->prev_item = new_item;
|
||||
hashtable->htable[hash] = new_item;
|
||||
}
|
||||
|
||||
hashtable->items_count++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_set: set value for item in hash table
|
||||
* return 1 if ok, 0 if error
|
||||
* Note: this function can be called *only* if key AND value are
|
||||
* *not* of type "buffer"
|
||||
*/
|
||||
|
||||
int
|
||||
hashtable_set (struct t_hashtable *hashtable, void *key, void *value)
|
||||
{
|
||||
return hashtable_set_with_size (hashtable, key, 0, value, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_get_item: search an item in hashtable
|
||||
* if hash is non NULL pointer, then it is set with
|
||||
* hash value of key (even if key is not found)
|
||||
*/
|
||||
|
||||
struct t_hashtable_item *
|
||||
hashtable_get_item (struct t_hashtable *hashtable, const void *key,
|
||||
unsigned int *hash)
|
||||
{
|
||||
unsigned int key_hash;
|
||||
struct t_hashtable_item *ptr_item;
|
||||
|
||||
if (!hashtable)
|
||||
return NULL;
|
||||
|
||||
key_hash = hashtable->callback_hash_key (hashtable, key);
|
||||
if (hash)
|
||||
*hash = key_hash;
|
||||
for (ptr_item = hashtable->htable[key_hash];
|
||||
ptr_item && hashtable->callback_keycmp (hashtable, key, ptr_item->key) > 0;
|
||||
ptr_item = ptr_item->next_item)
|
||||
{
|
||||
}
|
||||
|
||||
if (ptr_item
|
||||
&& (hashtable->callback_keycmp (hashtable, key, ptr_item->key) == 0))
|
||||
{
|
||||
return ptr_item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_get: get value for a key in hash table
|
||||
* return pointer to "value" for key,
|
||||
* or NULL if key is not found in hash table
|
||||
*/
|
||||
|
||||
void *
|
||||
hashtable_get (struct t_hashtable *hashtable, const void *key)
|
||||
{
|
||||
struct t_hashtable_item *ptr_item;
|
||||
|
||||
ptr_item = hashtable_get_item (hashtable, key, NULL);
|
||||
|
||||
return (ptr_item) ? ptr_item->value : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_map: call a function on all hashtable entries
|
||||
*/
|
||||
|
||||
void
|
||||
hashtable_map (struct t_hashtable *hashtable,
|
||||
t_hashtable_map *callback_map,
|
||||
void *callback_map_data)
|
||||
{
|
||||
int i;
|
||||
struct t_hashtable_item *ptr_item;
|
||||
|
||||
if (!hashtable)
|
||||
return;
|
||||
|
||||
for (i = 0; i < hashtable->size; i++)
|
||||
{
|
||||
for (ptr_item = hashtable->htable[i]; ptr_item;
|
||||
ptr_item = ptr_item->next_item)
|
||||
{
|
||||
(void) (callback_map) (callback_map_data,
|
||||
hashtable,
|
||||
ptr_item->key,
|
||||
ptr_item->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_get_integer: get a hashtable property as integer
|
||||
*/
|
||||
|
||||
int
|
||||
hashtable_get_integer (struct t_hashtable *hashtable, const char *property)
|
||||
{
|
||||
if (hashtable && property)
|
||||
{
|
||||
if (string_strcasecmp (property, "size") == 0)
|
||||
return hashtable->size;
|
||||
else if (string_strcasecmp (property, "items_count") == 0)
|
||||
return hashtable->items_count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_remove_item: remove an item from hashmap
|
||||
*/
|
||||
|
||||
void
|
||||
hashtable_remove_item (struct t_hashtable *hashtable,
|
||||
struct t_hashtable_item *item,
|
||||
unsigned int hash)
|
||||
{
|
||||
if (!hashtable || !item)
|
||||
return;
|
||||
|
||||
/* free key and value */
|
||||
hashtable_free_type (hashtable->type_keys, item->key);
|
||||
hashtable_free_type (hashtable->type_values, item->value);
|
||||
|
||||
/* remove item from list */
|
||||
if (item->prev_item)
|
||||
(item->prev_item)->next_item = item->next_item;
|
||||
if (item->next_item)
|
||||
(item->next_item)->prev_item = item->prev_item;
|
||||
if (hashtable->htable[hash] == item)
|
||||
hashtable->htable[hash] = item->next_item;
|
||||
|
||||
hashtable->items_count--;
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_remove: remove an item from hashmap (search it with key)
|
||||
*/
|
||||
|
||||
void
|
||||
hashtable_remove (struct t_hashtable *hashtable, const void *key)
|
||||
{
|
||||
struct t_hashtable_item *ptr_item;
|
||||
unsigned int hash;
|
||||
|
||||
ptr_item = hashtable_get_item (hashtable, key, &hash);
|
||||
if (ptr_item)
|
||||
hashtable_remove_item (hashtable, ptr_item, hash);
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_remove_all: remove all items from hashmap
|
||||
*/
|
||||
|
||||
void
|
||||
hashtable_remove_all (struct t_hashtable *hashtable)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!hashtable)
|
||||
return;
|
||||
|
||||
for (i = 0; i < hashtable->size; i++)
|
||||
{
|
||||
while (hashtable->htable[i])
|
||||
{
|
||||
hashtable_remove_item (hashtable, hashtable->htable[i], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_free: free hashtable (remove all items and free hashtable)
|
||||
*/
|
||||
|
||||
void
|
||||
hashtable_free (struct t_hashtable *hashtable)
|
||||
{
|
||||
hashtable_remove_all (hashtable);
|
||||
free (hashtable->htable);
|
||||
free (hashtable);
|
||||
}
|
||||
|
||||
/*
|
||||
* hashtable_print_log: print hashtable in log (usually for crash dump)
|
||||
*/
|
||||
|
||||
void
|
||||
hashtable_print_log (struct t_hashtable *hashtable, const char *name)
|
||||
{
|
||||
struct t_hashtable_item *ptr_item;
|
||||
int i;
|
||||
|
||||
log_printf ("");
|
||||
log_printf ("[hashtable %s (addr:0x%lx)]", name, hashtable);
|
||||
log_printf (" size . . . . . . . . . : %d", hashtable->size);
|
||||
log_printf (" htable . . . . . . . . : 0x%lx", hashtable->htable);
|
||||
log_printf (" items_count. . . . . . : %d", hashtable->items_count);
|
||||
log_printf (" type_keys. . . . . . . : %d", hashtable->type_keys);
|
||||
log_printf (" type_values. . . . . . : %d", hashtable->type_values);
|
||||
log_printf (" callback_hash_key. . . : 0x%lx", hashtable->callback_hash_key);
|
||||
log_printf (" callback_keycmp. . . . : 0x%lx", hashtable->callback_keycmp);
|
||||
|
||||
for (i = 0; i < hashtable->size; i++)
|
||||
{
|
||||
log_printf (" htable[%06d] . . . . : 0x%lx", i, hashtable->htable[i]);
|
||||
for (ptr_item = hashtable->htable[i]; ptr_item;
|
||||
ptr_item = ptr_item->next_item)
|
||||
{
|
||||
log_printf (" [item 0x%lx]", hashtable->htable);
|
||||
switch (hashtable->type_keys)
|
||||
{
|
||||
case HASHTABLE_INTEGER:
|
||||
log_printf (" key (integer). . . : %d", *((int *)ptr_item->key));
|
||||
break;
|
||||
case HASHTABLE_STRING:
|
||||
log_printf (" key (string) . . . : '%s'", (char *)ptr_item->key);
|
||||
break;
|
||||
case HASHTABLE_POINTER:
|
||||
log_printf (" key (pointer). . . : 0x%lx", ptr_item->key);
|
||||
break;
|
||||
case HASHTABLE_BUFFER:
|
||||
log_printf (" key (buffer) . . . : 0x%lx", ptr_item->key);
|
||||
break;
|
||||
case HASHTABLE_TIME:
|
||||
log_printf (" key (time) . . . . : %ld", *((time_t *)ptr_item->key));
|
||||
break;
|
||||
case HASHTABLE_NUM_TYPES:
|
||||
break;
|
||||
}
|
||||
log_printf (" key_size . . . . . : %d", ptr_item->key_size);
|
||||
switch (hashtable->type_values)
|
||||
{
|
||||
case HASHTABLE_INTEGER:
|
||||
log_printf (" value (integer). . : %d", *((int *)ptr_item->value));
|
||||
break;
|
||||
case HASHTABLE_STRING:
|
||||
log_printf (" value (string) . . : '%s'", (char *)ptr_item->value);
|
||||
break;
|
||||
case HASHTABLE_POINTER:
|
||||
log_printf (" value (pointer). . : 0x%lx", ptr_item->value);
|
||||
break;
|
||||
case HASHTABLE_BUFFER:
|
||||
log_printf (" value (buffer) . . : 0x%lx", ptr_item->value);
|
||||
break;
|
||||
case HASHTABLE_TIME:
|
||||
log_printf (" value (time) . . . : %d", *((time_t *)ptr_item->value));
|
||||
break;
|
||||
case HASHTABLE_NUM_TYPES:
|
||||
break;
|
||||
}
|
||||
log_printf (" value_size . . . . : %d", ptr_item->value_size);
|
||||
log_printf (" prev_item. . . . . : 0x%lx", ptr_item->prev_item);
|
||||
log_printf (" next_item. . . . . : 0x%lx", ptr_item->next_item);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Sebastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __WEECHAT_HASHTABLE_H
|
||||
#define __WEECHAT_HASHTABLE_H 1
|
||||
|
||||
struct t_hashtable;
|
||||
|
||||
typedef unsigned int (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_map)(void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key, const void *value);
|
||||
|
||||
/*
|
||||
* 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).
|
||||
* Keys with same hashed key are grouped in a linked list pointed by htable.
|
||||
* htable is not sorted, linked list is sorted.
|
||||
*
|
||||
* Example of a hashtable with size 8 and 6 items added inside, items are:
|
||||
* "weechat", "fast", "light", "extensible", "chat", "client"
|
||||
* Keys "fast" and "light" have same hashed value, so they are together in
|
||||
* linked list.
|
||||
*
|
||||
* Result is:
|
||||
* +-----+
|
||||
* | 0 |
|
||||
* +-----+
|
||||
* | 1 |
|
||||
* +-----+
|
||||
* | 2 | --> "extensible"
|
||||
* +-----+
|
||||
* | 3 | --> "fast" --> "light"
|
||||
* +-----+
|
||||
* | 4 | --> "weechat"
|
||||
* +-----+
|
||||
* | 5 | --> "chat"
|
||||
* +-----+
|
||||
* | 6 | --> "client"
|
||||
* +-----+
|
||||
* | 7 |
|
||||
* +-----+
|
||||
*/
|
||||
|
||||
enum t_hashtable_type
|
||||
{
|
||||
HASHTABLE_INTEGER = 0,
|
||||
HASHTABLE_STRING,
|
||||
HASHTABLE_POINTER,
|
||||
HASHTABLE_BUFFER,
|
||||
HASHTABLE_TIME,
|
||||
/* number of hashtable types */
|
||||
HASHTABLE_NUM_TYPES,
|
||||
};
|
||||
|
||||
struct t_hashtable_item
|
||||
{
|
||||
void *key; /* item key */
|
||||
int key_size; /* size of key (in bytes) */
|
||||
void *value; /* pointer to value */
|
||||
int value_size; /* size of value (in bytes) */
|
||||
struct t_hashtable_item *prev_item; /* link to previous item */
|
||||
struct t_hashtable_item *next_item; /* link to next item */
|
||||
};
|
||||
|
||||
struct t_hashtable
|
||||
{
|
||||
int size; /* hashtable size */
|
||||
struct t_hashtable_item **htable; /* table to map hashes with linked */
|
||||
/* lists */
|
||||
int items_count; /* number of items in hashtable */
|
||||
|
||||
/* type for keys and values */
|
||||
enum t_hashtable_type type_keys; /* type for keys: int/str/pointer */
|
||||
enum t_hashtable_type type_values; /* type for values: int/str/pointer */
|
||||
|
||||
/* callbacks */
|
||||
t_hashtable_hash_key *callback_hash_key; /* hash key to integer value */
|
||||
t_hashtable_keycmp *callback_keycmp; /* compare two keys */
|
||||
};
|
||||
|
||||
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,
|
||||
void *key, int key_size,
|
||||
void *value, int value_size);
|
||||
extern int hashtable_set (struct t_hashtable *hashtable, void *key,
|
||||
void *value);
|
||||
extern void *hashtable_get (struct t_hashtable *hashtable, const void *key);
|
||||
extern void hashtable_map (struct t_hashtable *hashtable,
|
||||
t_hashtable_map *callback_map,
|
||||
void *callback_map_data);
|
||||
extern int hashtable_get_integer (struct t_hashtable *hashtable,
|
||||
const char *property);
|
||||
extern void hashtable_remove (struct t_hashtable *hashtable, const void *key);
|
||||
extern void hashtable_remove_all (struct t_hashtable *hashtable);
|
||||
extern void hashtable_free (struct t_hashtable *hashtable);
|
||||
extern void hashtable_print_log (struct t_hashtable *hashtable,
|
||||
const char *name);
|
||||
|
||||
#endif /* __WEECHAT_HASHTABLE_H */
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "../core/weechat.h"
|
||||
#include "../core/wee-config.h"
|
||||
#include "../core/wee-hashtable.h"
|
||||
#include "../core/wee-hook.h"
|
||||
#include "../core/wee-infolist.h"
|
||||
#include "../core/wee-list.h"
|
||||
|
@ -520,6 +521,16 @@ plugin_load (const char *filename)
|
|||
new_plugin->list_remove_all = &weelist_remove_all;
|
||||
new_plugin->list_free = &weelist_free;
|
||||
|
||||
new_plugin->hashtable_new = &hashtable_new;
|
||||
new_plugin->hashtable_set_with_size = &hashtable_set_with_size;
|
||||
new_plugin->hashtable_set = &hashtable_set;
|
||||
new_plugin->hashtable_get = &hashtable_get;
|
||||
new_plugin->hashtable_map = &hashtable_map;
|
||||
new_plugin->hashtable_get_integer = &hashtable_get_integer;
|
||||
new_plugin->hashtable_remove = &hashtable_remove;
|
||||
new_plugin->hashtable_remove_all = &hashtable_remove_all;
|
||||
new_plugin->hashtable_free = &hashtable_free;
|
||||
|
||||
new_plugin->config_new = &config_file_new;
|
||||
new_plugin->config_new_section = &config_file_new_section;
|
||||
new_plugin->config_search_section = &config_file_search_section;
|
||||
|
|
|
@ -35,6 +35,7 @@ struct t_gui_bar_item;
|
|||
struct t_gui_completion;
|
||||
struct t_infolist;
|
||||
struct t_weelist;
|
||||
struct t_hashtable;
|
||||
struct timeval;
|
||||
|
||||
/*
|
||||
|
@ -93,6 +94,13 @@ struct timeval;
|
|||
#define WEECHAT_LIST_POS_BEGINNING "beginning"
|
||||
#define WEECHAT_LIST_POS_END "end"
|
||||
|
||||
/* type for keys and values in hashtable */
|
||||
#define WEECHAT_HASHTABLE_INTEGER "integer"
|
||||
#define WEECHAT_HASHTABLE_STRING "string"
|
||||
#define WEECHAT_HASHTABLE_POINTER "pointer"
|
||||
#define WEECHAT_HASHTABLE_BUFFER "buffer"
|
||||
#define WEECHAT_HASHTABLE_TIME "time"
|
||||
|
||||
/* buffer hotlist */
|
||||
#define WEECHAT_HOTLIST_LOW "0"
|
||||
#define WEECHAT_HOTLIST_MESSAGE "1"
|
||||
|
@ -241,6 +249,33 @@ struct t_weechat_plugin
|
|||
void (*list_remove_all) (struct t_weelist *weelist);
|
||||
void (*list_free) (struct t_weelist *weelist);
|
||||
|
||||
/* hash tables */
|
||||
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),
|
||||
int (*callback_keycmp)(struct t_hashtable *hashtable,
|
||||
const void *key1,
|
||||
const void *key2));
|
||||
int (*hashtable_set_with_size) (struct t_hashtable *hashtable,
|
||||
void *key, int key_size,
|
||||
void *value, int value_size);
|
||||
int (*hashtable_set) (struct t_hashtable *hashtable, void *key,
|
||||
void *value);
|
||||
void *(*hashtable_get) (struct t_hashtable *hashtable, const void *key);
|
||||
void (*hashtable_map) (struct t_hashtable *hashtable,
|
||||
void (*callback_map) (void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key,
|
||||
const void *value),
|
||||
void *callback_map_data);
|
||||
int (*hashtable_get_integer) (struct t_hashtable *hashtable,
|
||||
const char *property);
|
||||
void (*hashtable_remove) (struct t_hashtable *hashtable, const void *key);
|
||||
void (*hashtable_remove_all) (struct t_hashtable *hashtable);
|
||||
void (*hashtable_free) (struct t_hashtable *hashtable);
|
||||
|
||||
/* config files */
|
||||
struct t_config_file *(*config_new) (struct t_weechat_plugin *plugin,
|
||||
const char *name,
|
||||
|
@ -829,6 +864,31 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
|
|||
#define weechat_list_free(__list) \
|
||||
weechat_plugin->list_free(__list)
|
||||
|
||||
/* hash tables */
|
||||
#define weechat_hashtable_new(__size, __type_keys, __type_values, \
|
||||
__hash_key_cb, __keycmp_cb) \
|
||||
weechat_plugin->hashtable_new(__size, __type_keys, __type_values, \
|
||||
__hash_key_cb, __keycmp_cb)
|
||||
#define weechat_hashtable_set_with_size(__hashtable, __key, __key_size, \
|
||||
__value, __value_size) \
|
||||
weechat_plugin->hashtable_set_with_size(__hashtable, __key, \
|
||||
__key_size, __value, \
|
||||
__value_size)
|
||||
#define weechat_hashtable_set(__hashtable, __key, __value) \
|
||||
weechat_plugin->hashtable_set(__hashtable, __key, __value)
|
||||
#define weechat_hashtable_get(__hashtable, __key) \
|
||||
weechat_plugin->hashtable_get(__hashtable, __key)
|
||||
#define weechat_hashtable_map(__hashtable, __cb_map, __cb_map_data) \
|
||||
weechat_plugin->hashtable_map(__hashtable, __cb_map, __cb_map_data)
|
||||
#define weechat_hashtable_get_integer(__hashtable, __property) \
|
||||
weechat_plugin->hashtable_get_integer(__hashtable, __property)
|
||||
#define weechat_hashtable_remove(__hashtable, __key) \
|
||||
weechat_plugin->hashtable_remove(__hashtable, __key)
|
||||
#define weechat_hashtable_remove_all(__hashtable) \
|
||||
weechat_plugin->hashtable_remove_all(__hashtable)
|
||||
#define weechat_hashtable_free(__hashtable) \
|
||||
weechat_plugin->hashtable_free(__hashtable)
|
||||
|
||||
/* config files */
|
||||
#define weechat_config_new(__name, __callback_reload, \
|
||||
__callback_reload_data) \
|
||||
|
|
Loading…
Reference in New Issue