We are going to store some tuples into our table, that will map each name to a number. The cost to access a given number from the name should be very small, even with many entries in our table. This is the initial data:
struct _Phone_Entry {
const char *name;
const char *number;
};
typedef struct _Phone_Entry Phone_Entry;
static Phone_Entry _start_entries[] = {
{ "Wolfgang Amadeus Mozart", "+01 23 456-78910" },
{ "Ludwig van Beethoven", "+12 34 567-89101" },
{ "Richard Georg Strauss", "+23 45 678-91012" },
{ "Heitor Villa-Lobos", "+34 56 789-10123" },
{ NULL, NULL }
};
Before starting to play with the hash, let's write a callback that will be used to free the elements from it. Since we are just storing strduped strings, we just need to free them:
static void
_phone_entry_free_cb(void *data)
{
free(data);
}
We also need a callback to iterate over the elements of the list later, so we are defining it now:
_phone_book_foreach_cb(
const Eina_Hash *phone_book,
const void *key,
void *data, void *fdata)
{
const char *name = key;
const char *number = data;
printf("%s: %s\n", name, number);
}
struct _Eina_Hash Eina_Hash
Type for a generic hash table.
Definition eina_hash.h:288
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition eina_types.h:299
unsigned char Eina_Bool
Type to mimic a boolean.
Definition eina_types.h:287
Now let's create our Eina_Hash using eina_hash_string_superfast_new :
Eina_Hash * eina_hash_string_superfast_new(Eina_Free_Cb data_free_cb)
Create a new hash table for use with strings.
Definition eina_hash.c:772
int eina_init(void)
Initialize the Eina library.
Definition eina_main.c:244
Now we add the keys and data to the hash using eina_hash_add . This means that the key is copied inside the table, together with the pointer to the data (phone numbers).
for (i = 0; _start_entries[i].name != NULL; i++)
{
strdup(_start_entries[i].number));
}
Eina_Bool eina_hash_add(Eina_Hash *hash, const void *key, const void *data)
Add an entry to the given hash table.
Definition eina_hash.c:913
Some basic manipulations with the hash, like finding a value given a key, deleting an entry, modifying an entry are exemplified in the following lines. Notice that the eina_hash_modify function returns the old value stored in that entry, and it needs to be freed, while the eina_hash_del function already calls our free callback:
if (phone)
{
printf("Printing entry.\n");
printf("Name: %s\n", entry_name);
printf("Number: %s\n\n", phone);
}
printf("Hash entry successfully deleted? %d\n\n", r);
strdup("+23 45 111-11111"));
free(phone);
void * eina_hash_modify(Eina_Hash *hash, const void *key, const void *data)
Modify the entry pointer at the specified key and return the old entry.
Definition eina_hash.c:1157
Eina_Bool eina_hash_del(Eina_Hash *hash, const void *key, const void *data)
Remove the entry identified by a key or a data from the given hash table.
Definition eina_hash.c:1014
void * eina_hash_find(const Eina_Hash *hash, const void *key)
Retrieve a specific entry in the given hash table.
Definition eina_hash.c:1053
The eina_hash_set function can be used to set a key-value entry to the table if it doesn't exist, or to modify an existent entry. It returns the old entry if it was already set, and NULL otherwise. But since it will return NULL on error too, we need to check if an error has occurred:
strdup("+55 01 234-56789"));
if (!phone)
{
if (!err)
{
printf("No previous phone found for Raul Seixas. ");
printf("Creating new entry.\n");
}
else
printf("Error when setting phone for Raul Seixas\n");
}
else
{
printf("Old phone for Raul Seixas was %s\n", phone);
free(phone);
}
printf("\n");
Eina_Error eina_error_get(void)
Return the last set error.
Definition eina_error.c:250
int Eina_Error
Error type.
Definition eina_error.h:85
void eina_error_set(Eina_Error err)
Set the last error.
Definition eina_error.c:256
void * eina_hash_set(Eina_Hash *hash, const void *key, const void *data)
Modify the entry pointer at the specified key and return the old entry or add the entry if not found.
Definition eina_hash.c:1103
There are different ways of iterate over the entries of a hash. Here we show two of them: using eina_hash_foreach and Eina_Iterator .
printf("List of phones:\n");
printf("\n");
printf("List of phones:\n");
{
const char *name = t->
key;
const char *number = t->
data;
printf("%s: %s\n", name, number);
}
void eina_hash_foreach(const Eina_Hash *hash, Eina_Hash_Foreach func, const void *fdata)
Call a function on every member stored in the hash table.
Definition eina_hash.c:1207
Eina_Iterator * eina_hash_iterator_tuple_new(const Eina_Hash *hash)
Returned a new iterator associated to hash keys and data.
Definition eina_hash.c:1293
Eina_Bool eina_iterator_next(Eina_Iterator *iterator, void **data)
Return the value of the current element and go to the next one.
Definition eina_iterator.c:116
void eina_iterator_free(Eina_Iterator *iterator)
Free an iterator.
Definition eina_iterator.c:96
Definition eina_hash.h:293
void * data
The data associated to the key.
Definition eina_hash.h:295
const void * key
The key.
Definition eina_hash.h:294
It's also possible to change the key for a specific entry, without having to remove the entry from the table and adding it again:
Eina_Bool eina_hash_move(Eina_Hash *hash, const void *old_key, const void *new_key)
Change the key associated with a data without triggering the free callback.
Definition eina_hash.c:1175
We can remove all the elements from the table without free the table itself:
printf("There are %d items in the hash.\n\n",
int eina_hash_population(const Eina_Hash *hash)
Returns the number of entries in the given hash table.
Definition eina_hash.c:840
void eina_hash_free_buckets(Eina_Hash *hash)
Free the given hash table buckets resources.
Definition eina_hash.c:868
Or free the the entire table with its content:
void eina_hash_free(Eina_Hash *hash)
Free the given hash table resources.
Definition eina_hash.c:850
The full code for this example can be seen here: Hash table in action