#ifndef WORDHASH_H
#define WORDHASH_H
#include "word.h"
/* Hash entry. */
typedef struct hashnode_t {
/*@dependent@*/ struct hashnode_t *iter_next; /* Next item added to hash. For fast traversal */
struct hashnode_t *next; /* Next item in linked list of items with same hash */
word_t *key; /* word key */
void *data; /* Associated data. To be used by caller. */
} hashnode_t;
typedef struct wh_alloc_node {
hashnode_t *buf;
/*@refs@*/ size_t avail;
/*@refs@*/ size_t used;
/*@null@*/ struct wh_alloc_node *next;
} wh_alloc_node;
typedef struct wh_alloc_str {
char *buf;
/*@refs@*/ size_t avail;
/*@refs@*/ size_t used;
/*@null@*/ struct wh_alloc_str *next;
} wh_alloc_str;
typedef /*@null@*/ hashnode_t *hashnode_pt;
typedef enum wh_e { WH_NORMAL,
WH_PROPS,
WH_CNTS } wh_t;
typedef struct wordhash_s {
/*@null@*/ /*@dependent@*/ wh_t type; /* normal, ordered, props, or cnts */
/*@null@*/ /*@dependent@*/ bool freeable;
/*@null@*/ /*@dependent@*/ uint index; /* access index */
/*@null@*/ /*@dependent@*/ uint count; /* count of words */
/*@null@*/ /*@dependent@*/ uint size; /* size of array */
hashnode_pt *bin;
/*@null@*/ /*@owned@*/ wh_alloc_node *nodes; /* list of node buffers */
/*@null@*/ wh_alloc_str *strings; /* list of string buffers */
/*@null@*/ /*@dependent@*/ hashnode_t *iter_ptr;
/*@null@*/ /*@dependent@*/ hashnode_t *iter_head;
/*@null@*/ /*@dependent@*/ hashnode_t *iter_tail;
/*@null@*/ /*@dependent@*/ hashnode_t *props; /* array of nodes */
/*@null@*/ /*@dependent@*/ wordcnts_t *cnts; /* array of counts */
} wordhash_t;
/*@only@*/ wordhash_t *wordhash_new(void);
/*@only@*/ wordhash_t *wordhash_init(wh_t type, uint count);
void wordhash_free(/*@only@*/ wordhash_t *);
size_t wordhash_count(wordhash_t * h);
void wordhash_sort(wordhash_t * h);
void wordhash_add(wordhash_t *dst, wordhash_t *src, void (*initializer)(void *));
void wordhash_set_counts(wordhash_t *wh, int good, int bad);
void *wordhash_search (const wordhash_t *wh, const word_t *t, uint hash);
/* Given h, s, n, search for key s.
* If found, return pointer to associated buffer.
* Else, insert key and return pointer to allocated buffer of size n. */
/*@observer@*/ void *wordhash_insert(wordhash_t *, word_t *, size_t, void (*)(void *));
/* Starts an iteration over the hash entries */
/*@null@*/ /*@exposed@*/ void *wordhash_first(wordhash_t *);
/* returns next entry or NULL if at end */
/*@null@*/ /*@exposed@*/ void *wordhash_next(wordhash_t *);
wordhash_t *convert_propslist_to_countlist(wordhash_t *wh);
wordhash_t *convert_wordhash_to_propslist(wordhash_t *wh, wordhash_t *db);
/* for bogotune */
void *wordhash_search_memory (const word_t *t);
#endif