xl_hash.h

#ifndef __XL_HASH__
#define __XL_HASH__

#include <stdio.h>

typedef void *        XL_VALUE_TYPE;
typedef void *        XL_KEY_TYPE;
typedef unsigned long XL_HASH_KEY_TYPE;

#define XL_HASH_CALC(hash, key)            ((*hash->type->hash)(key))
#define XL_HASH_KEY_COMP(hash, a, b)       ((*hash->type->compare)(a, b) == 0)
#define XL_HASH_FIND_ENTRY(hash, hash_key) (xl_hash_find_chain(hash->entry[hash_key]->next))

/* ハッシュタイプの構造体 */
typedef struct xl_hash_type xl_hash_type;
struct xl_hash_type {
	int (*compare)(XL_KEY_TYPE, XL_KEY_TYPE); /* 比較関数ポインタ */
	int (*hash)(XL_KEY_TYPE);                 /* ハッシュ関数ポインタ */
	unsigned int value_size;                  /* エントリのサイズ */
	unsigned int key_size;                    /* キーのサイズ */
};

/* ハッシュエントリの構造体 */
typedef struct xl_hash_entry xl_hash_entry;
struct xl_hash_entry {
	XL_VALUE_TYPE value;                      /* ハッシュ値 */
	XL_KEY_TYPE   key;                        /* ハッシュキー */
	xl_hash_entry *pre;                       /* 次へのポインタ */
	xl_hash_entry *next;                      /* 前へのポインタ */
};

/* チェーンハッシュの構造体 */
typedef struct xl_hash xl_hash;
struct xl_hash {
	xl_hash_type *type;                       /* ハッシュタイプ */
	XL_HASH_KEY_TYPE size;                    /* ハッシュサイズ */
	xl_hash_entry **entry;                    /* ハッシュのエントリ */
};

xl_hash *xl_hash_init(xl_hash_type *type);
xl_hash *xl_hash_init_with_size(xl_hash_type *type, XL_HASH_KEY_TYPE size);
xl_hash_entry *xl_hash_find(xl_hash *hash, XL_KEY_TYPE key);
int xl_hash_delete(xl_hash *hash, XL_KEY_TYPE key);
xl_hash_entry *xl_hash_new_entry(xl_hash *hash, XL_VALUE_TYPE val, XL_KEY_TYPE key);
int xl_hash_add_first(xl_hash *hash, XL_VALUE_TYPE val, XL_KEY_TYPE key);
int xl_hash_add_last(xl_hash *hash, XL_VALUE_TYPE val, XL_KEY_TYPE key);
void xl_hash_foreach(xl_hash *hash, void (*func)(XL_VALUE_TYPE));
xl_hash *xl_hash_lookup(xl_hash *hash, int (*func)(XL_VALUE_TYPE));
void xl_hash_free(xl_hash *hash);
void xl_hash_clear(xl_hash *hash);

#endif