const struct mapping_t *map,
char* errbuf, ssize_t errlen);
-static HASH *ConfigOptions = NULL;
+static hash_t *ConfigOptions = NULL;
/* for synonym warning reports: synonym found during parsing */
typedef struct syn_t {
err.data = error;
err.dsize = sizeof(error);
- ConfigOptions = hash_create (sizeof(MuttVars) * 2, 0);
+ ConfigOptions = hash_new (sizeof(MuttVars) * 2, 0);
for (i = 0; MuttVars[i].option; i++) {
hash_insert (ConfigOptions, MuttVars[i].option, &MuttVars[i]);
}
int hash_string(const unsigned char *s, int n)
{
- int h = 0;
+ unsigned h = 0;
while (*s) {
h += (h << 7) + *s++;
}
- h = (h * SOMEPRIME) % n;
- h = (h >= 0) ? h : h + n;
- return (h % n);
+ return (h * SOMEPRIME) % n;
}
-HASH *hash_create(int nelem, int allow_dup)
+hash_t *hash_init(hash_t *table, int nelem, int allow_dup)
{
- HASH *table = p_new(HASH, 1);
-
table->dupes = allow_dup;
table->nelem = MIN(nelem, 2);
table->curnelem = 0;
table->table = p_new(struct hash_elem *, table->nelem);
-
return table;
}
-void hash_resize(HASH *ptr, int nelem)
+/* ptr pointer to the hash table to be freed
+ * destroy() function to call to free the ->data member (optional)
+ */
+void hash_wipe(hash_t *h, void (*dtor)(void *))
+{
+ int i;
+
+ for (i = 0; i < h->nelem; i++) {
+ struct hash_elem *elem, *tmp;
+
+ for (elem = h->table[i]; elem;) {
+ tmp = elem;
+ elem = elem->next;
+ if (dtor)
+ dtor(tmp->data);
+ p_delete(&tmp);
+ }
+ }
+ p_delete(&h->table);
+}
+
+void hash_resize(hash_t *ptr, int nelem)
{
- HASH *table;
- struct hash_elem *elem, *tmp;
+ hash_t table;
int i;
/* XXX hack: we know the has was correct, no dupe checks is fater */
- table = hash_create(nelem, 1);
+ hash_init(&table, nelem, 1);
for (i = 0; i < ptr->nelem; i++) {
+ struct hash_elem *elem, *tmp;
for (elem = ptr->table[i]; elem;) {
tmp = elem;
elem = elem->next;
- hash_insert(table, tmp->key, tmp->data);
+ hash_insert(&table, tmp->key, tmp->data);
p_delete(&tmp);
}
}
p_delete(&ptr->table);
- ptr->nelem = table->nelem;
- ptr->table = table->table;
- p_delete(&table);
+ ptr->nelem = table.nelem;
+ ptr->table = table.table;
}
/* table hash table to update
* data data to associate with `key'
* allow_dup if nonzero, duplicate keys are allowed in the table
*/
-int hash_insert(HASH *table, const char *key, void *data)
+int hash_insert(hash_t *table, const char *key, void *data)
{
struct hash_elem *ptr;
int h;
return h;
}
-void *hash_find_hash(const HASH *table, int hash, const char *key)
+void *hash_find(const hash_t *table, const char *key)
{
+ int hash = hash_string((unsigned char*)key, table->nelem);
struct hash_elem *ptr;
for (ptr = table->table[hash]; ptr; ptr = ptr->next) {
return NULL;
}
-void hash_delete_hash(HASH *table, int hash, const char *key, const void *data,
- void (*destroy)(void *))
+void hash_remove(hash_t *table, const char *key, const void *data,
+ void (*destroy)(void *))
{
+ int hash = hash_string((unsigned char*)key, table->nelem);
struct hash_elem *ptr = table->table[hash];
struct hash_elem **last = &table->table[hash];
}
}
-/* ptr pointer to the hash table to be freed
- * destroy() function to call to free the ->data member (optional)
- */
-void hash_destroy(HASH **ptr, void (*destroy)(void *))
-{
- int i;
- HASH *pptr = *ptr;
- struct hash_elem *elem, *tmp;
-
- for (i = 0; i < pptr->nelem; i++) {
- for (elem = pptr->table[i]; elem;) {
- tmp = elem;
- elem = elem->next;
- if (destroy)
- destroy (tmp->data);
- p_delete(&tmp);
- }
- }
- p_delete(&pptr->table);
- p_delete(ptr);
-}
-
-void hash_map(HASH *table,
+void hash_map(hash_t *table,
void (*mapfunc)(const char* key, void* data, unsigned long more),
unsigned long more)
{
int nelem;
int curnelem;
struct hash_elem **table;
-} HASH;
+} hash_t;
-#define hash_find(table, key) \
- hash_find_hash(table, hash_string((unsigned char *)key, table->nelem), key)
+hash_t *hash_init(hash_t *, int nelem, int allow_dup);
+static inline hash_t *hash_new(int nelem, int allow_dup) {
+ return hash_init(p_new(hash_t, 1), nelem, allow_dup);
+}
-#define hash_delete(table,key,data,destroy) \
- hash_delete_hash(table, hash_string((unsigned char *)key, table->nelem), key, data, destroy)
+void hash_wipe(hash_t*, void (*dtor)(void*));
+static inline void hash_delete(hash_t **h, void (*dtor)(void*)) {
+ if (*h) {
+ hash_wipe(*h, dtor);
+ p_delete(h);
+ }
+}
-HASH *hash_create(int nelem, int allow_dup);
int hash_string(const unsigned char *s, int n);
-int hash_insert(HASH *table, const char *key, void *data);
-void hash_resize(HASH *table, int nelem);
-void *hash_find_hash(const HASH *table, int hash, const char *key);
-void hash_delete_hash(HASH *table, int hash, const char *key,
- const void *data, void (*destroy)(void *));
-void hash_destroy(HASH **hash, void (*destroy)(void *));
-
-void hash_map(HASH *table,
+void hash_resize(hash_t *table, int nelem);
+
+int hash_insert(hash_t *table, const char *key, void *data);
+void *hash_find(const hash_t *table, const char *key);
+void hash_remove(hash_t *table, const char *key, const void *data,
+ void (*destroy)(void *));
+
+void hash_map(hash_t *table,
void (*mapfunc)(const char *key, void *data, unsigned long more),
unsigned long more);
/* simulate a close */
if (ctx->id_hash)
- hash_destroy (&ctx->id_hash, NULL);
+ hash_delete (&ctx->id_hash, NULL);
if (ctx->subj_hash)
- hash_destroy (&ctx->subj_hash, NULL);
+ hash_delete (&ctx->subj_hash, NULL);
mutt_clear_threads (ctx);
p_delete(&ctx->v2r);
if (ctx->readonly) {
struct maildir *md; /* list of messages in the mailbox */
struct maildir **last, *p;
int i;
- HASH *fnames; /* hash table for quickly looking up the base filename
+ hash_t *fnames; /* hash table for quickly looking up the base filename
for a maildir message */
if (!option (OPTCHECKNEW))
* of each message we scanned. This is used in the loop over the
* existing messages below to do some correlation.
*/
- fnames = hash_create (1031, 0);
+ fnames = hash_new (1031, 0);
for (p = md; p; p = p->next) {
maildir_canon_filename (buf, p->h->path, sizeof (buf));
}
/* destroy the file name hash */
- hash_destroy (&fnames, NULL);
+ hash_delete (&fnames, NULL);
/* If we didn't just get new mail, update the tables. */
if (occult)
struct maildir *md, *p;
struct maildir **last = NULL;
struct mh_sequences mhs;
- HASH *fnames;
+ hash_t *fnames;
int i;
if (!option (OPTCHECKNEW))
mhs_free_sequences (&mhs);
/* check for modifications and adjust flags */
- fnames = hash_create (1031, 0);
+ fnames = hash_new (1031, 0);
for (p = md; p; p = p->next)
hash_insert (fnames, p->h->path, p);
/* destroy the file name hash */
- hash_destroy (&fnames, NULL);
+ hash_delete (&fnames, NULL);
/* If we didn't just get new mail, update the tables. */
if (occult)
if (MX_IDX(ctx->magic-1) && mxfmts[ctx->magic-1]->mx_fastclose_mailbox)
mxfmts[ctx->magic-1]->mx_fastclose_mailbox(ctx);
if (ctx->subj_hash)
- hash_destroy (&ctx->subj_hash, NULL);
+ hash_delete (&ctx->subj_hash, NULL);
if (ctx->id_hash)
- hash_destroy (&ctx->id_hash, NULL);
+ hash_delete (&ctx->id_hash, NULL);
mutt_clear_threads (ctx);
for (i = 0; i < ctx->msgcount; i++)
header_delete(&ctx->hdrs[i]);
ctx->hdrs[i]->content->hdr_offset);
/* remove message from the hash tables */
if (ctx->subj_hash && ctx->hdrs[i]->env->real_subj)
- hash_delete (ctx->subj_hash, ctx->hdrs[i]->env->real_subj,
+ hash_remove (ctx->subj_hash, ctx->hdrs[i]->env->real_subj,
ctx->hdrs[i], NULL);
if (ctx->id_hash && ctx->hdrs[i]->env->message_id)
- hash_delete (ctx->id_hash, ctx->hdrs[i]->env->message_id,
+ hash_remove (ctx->id_hash, ctx->hdrs[i]->env->message_id,
ctx->hdrs[i], NULL);
header_delete(&ctx->hdrs[i]);
}
HEADER **hdrs;
HEADER *last_tag; /* last tagged msg. used to link threads */
THREAD *tree; /* top of thread tree */
- HASH *id_hash; /* hash table by msg id */
- HASH *subj_hash; /* hash table by subject */
- HASH *thread_hash; /* hash table for threading */
+ hash_t *id_hash; /* hash table by msg id */
+ hash_t *subj_hash; /* hash table by subject */
+ hash_t *thread_hash; /* hash table for threading */
int *v2r; /* mapping from virtual to real msgno */
int hdrmax; /* number of pointers in hdrs */
int msgcount; /* number of messages in the mailbox */
serv = p_new(NNTP_SERVER, 1);
serv->conn = conn;
serv->newsrc = m_strdup(file);
- serv->newsgroups = hash_create(1009, false);
+ serv->newsgroups = hash_new(1009, false);
slurp_newsrc (serv); /* load .newsrc */
nntp_parse_cacheindex (serv); /* load .index */
if (option (OPTNEWSCACHE) && serv->cache && nntp_get_cache_all (serv) >= 0)
nntp_check_newgroups (serv, 1);
else if (nntp_get_active (serv) < 0) {
- hash_destroy (&serv->newsgroups, nntp_delete_data);
+ hash_delete (&serv->newsgroups, nntp_delete_data);
for (list = serv->list; list; list = list->next)
list->data = NULL;
string_list_wipe(&serv->list);
/* CACHE: delete cache and line from .index */
nntp_delete_cache (nntp_data);
- hash_delete (serv->newsgroups, nntp_data->group, NULL,
+ hash_remove (serv->newsgroups, nntp_data->group, NULL,
nntp_delete_data);
while (l && l->data != (void *) nntp_data)
l = l->next;
if (data && data->deleted && !data->rc) {
nntp_delete_cache (data);
- hash_delete (serv->newsgroups, data->group, NULL, nntp_delete_data);
+ hash_remove (serv->newsgroups, data->group, NULL, nntp_delete_data);
tmp->data = NULL;
}
}
time_t mtime;
time_t newgroups_time;
time_t check_time;
- HASH *newsgroups;
+ hash_t *newsgroups;
string_list_t *list; /* list of newsgroups */
string_list_t *tail; /* last entry of list */
CONNECTION *conn;
ctx->tree = NULL;
if (ctx->thread_hash)
- hash_destroy (&ctx->thread_hash, free);
+ hash_delete (&ctx->thread_hash, free);
}
static int compare_threads (const void *a, const void *b)
init = 1;
if (init)
- ctx->thread_hash = hash_create (ctx->msgcount * 2, 1);
+ ctx->thread_hash = hash_new (ctx->msgcount * 2, 1);
/* we want a quick way to see if things are actually attached to the top of the
* thread tree or if they're just dangling, so we attach everything to a top
}
-HASH *mutt_make_id_hash (CONTEXT * ctx)
+hash_t *mutt_make_id_hash (CONTEXT * ctx)
{
int i;
HEADER *hdr;
- HASH *hash;
+ hash_t *hash;
- hash = hash_create (ctx->msgcount * 2, 0);
+ hash = hash_new (ctx->msgcount * 2, 0);
for (i = 0; i < ctx->msgcount; i++) {
hdr = ctx->hdrs[i];
return hash;
}
-HASH *mutt_make_subj_hash (CONTEXT * ctx)
+hash_t *mutt_make_subj_hash (CONTEXT * ctx)
{
int i;
HEADER *hdr;
- HASH *hash;
+ hash_t *hash;
- hash = hash_create (ctx->msgcount * 2, 1);
+ hash = hash_new (ctx->msgcount * 2, 1);
for (i = 0; i < ctx->msgcount; i++) {
hdr = ctx->hdrs[i];
int mutt_messages_in_thread (CONTEXT *, HEADER *, int);
-HASH *mutt_make_id_hash (CONTEXT *);
-HASH *mutt_make_subj_hash (CONTEXT *);
+hash_t *mutt_make_id_hash (CONTEXT *);
+hash_t *mutt_make_subj_hash (CONTEXT *);
int mutt_link_threads (HEADER *, HEADER *, CONTEXT *);
void mutt_break_thread (HEADER *);