hashmap.c revision 6091827530d6dd43479d6709fb6e9f745c11e900
/*-*- Mode: C; c-basic-offset: 8 -*-*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "util.h"
#include "hashmap.h"
#include "macro.h"
#define NBUCKETS 127
struct hashmap_entry {
const void *key;
void *value;
};
struct Hashmap {
unsigned n_entries;
};
unsigned string_hash_func(const void *p) {
unsigned hash = 0;
const char *c;
for (c = p; *c; c++)
return hash;
}
int string_compare_func(const void *a, const void *b) {
return strcmp(a, b);
}
unsigned trivial_hash_func(const void *p) {
return PTR_TO_UINT(p);
}
int trivial_compare_func(const void *a, const void *b) {
return a < b ? -1 : (a > b ? 1 : 0);
}
Hashmap *h;
return NULL;
h->n_entries = 0;
return h;
}
assert(h);
assert(e);
/* Remove from iteration list */
if (e->iterate_next)
else
h->iterate_list_tail = e->iterate_previous;
if (e->iterate_previous)
else
h->iterate_list_head = e->iterate_next;
/* Remove from hash table bucket list */
if (e->bucket_next)
if (e->bucket_previous)
else {
}
free(e);
h->n_entries--;
}
void hashmap_free(Hashmap*h) {
if (!h)
return;
while (h->iterate_list_head)
remove_entry(h, h->iterate_list_head);
free(h);
}
struct hashmap_entry *e;
assert(h);
return e;
return NULL;
}
struct hashmap_entry *e;
unsigned hash;
assert(h);
return -EEXIST;
return -ENOMEM;
/* Insert into hash table */
e->bucket_previous = NULL;
/* Insert into iteration list */
e->iterate_previous = h->iterate_list_tail;
e->iterate_next = NULL;
if (h->iterate_list_tail) {
assert(h->iterate_list_head);
h->iterate_list_tail->iterate_next = e;
} else {
assert(!h->iterate_list_head);
h->iterate_list_head = e;
}
h->iterate_list_tail = e;
h->n_entries++;
return 0;
}
unsigned hash;
struct hashmap_entry *e;
if (!h)
return NULL;
return NULL;
return e->value;
}
struct hashmap_entry *e;
unsigned hash;
void *data;
if (!h)
return NULL;
return NULL;
remove_entry(h, e);
return data;
}
struct hashmap_entry *e;
if (!h)
goto at_end;
if (*state == (void*) -1)
goto at_end;
if (!*state && !h->iterate_list_head)
goto at_end;
if (e->iterate_next)
*state = e->iterate_next;
else
*state = (void*) -1;
if (key)
return e->value;
*state = (void *) -1;
if (key)
return NULL;
}
struct hashmap_entry *e;
if (!h)
goto at_beginning;
if (*state == (void*) -1)
goto at_beginning;
if (!*state && !h->iterate_list_tail)
goto at_beginning;
if (e->iterate_previous)
*state = e->iterate_previous;
else
*state = (void*) -1;
if (key)
return e->value;
*state = (void *) -1;
if (key)
return NULL;
}
void* hashmap_first(Hashmap *h) {
if (!h)
return NULL;
if (!h->iterate_list_head)
return NULL;
return h->iterate_list_head->value;
}
void* hashmap_last(Hashmap *h) {
if (!h)
return NULL;
if (!h->iterate_list_tail)
return NULL;
return h->iterate_list_tail->value;
}
void* hashmap_steal_first(Hashmap *h) {
void *data;
if (!h)
return NULL;
if (!h->iterate_list_head)
return NULL;
remove_entry(h, h->iterate_list_head);
return data;
}
unsigned hashmap_size(Hashmap *h) {
if (!h)
return 0;
return h->n_entries;
}
bool hashmap_isempty(Hashmap *h) {
if (!h)
return true;
return h->n_entries == 0;
}