/*
 * ハッシュテーブルコンテナライブラリ
 */

#ifndef MINATO_HASH_H
#define MINATO_HASH_H

#include "saphire_extra.h"

#define HASH_KEYSIZE_PER_ONE_IT 5

/* ハッシュオブジェクト */
typedef struct _hash_it {
   char* mKey;
   
   void* mItem;
   struct _hash_it* mCollisionIt;

   struct _hash_it* mNextIt;
} hash_it;

typedef struct {
   hash_it** mTable;
   int mTableSize;

   hash_it* mEntryIt;

   int mCounter;                // 全走査用
} hash_obj;

///////////////////////////////////////////////////////////////////////
// 関数宣言
///////////////////////////////////////////////////////////////////////

// 初期化
#ifdef MDEBUG

hash_obj* hash_new_debug(int size, const char* fname, int line, const char* func_name);
#define HASH_NEW(size) hash_new_debug(size, __FILE__, __LINE__, __FUNCTION__)

#else

hash_obj* hash_new(int size);
#define HASH_NEW(size) hash_new(size)

#endif


void hash_delete(hash_obj* self);               // 解放

void hash_put(hash_obj* self, char* key, void* item);       // 代入
void hash_erase(hash_obj* self, char* key);                 // 削除
void hash_clear(hash_obj* self);                            // クリア
void hash_replace(hash_obj* self, char* key, void* item);   // 置き換え

void hash_show(hash_obj* self, char* fname);                // デバッグ用ハッシュテーブル表示

void* hash_item(hash_obj* self, char* key);                 // 引数のキーのアイテムを返す
void* hash_item_addr(hash_obj* self, char* key);            // 引数のキーのアイテムのアドレスを返す
char* hash_key(hash_obj* self, void* item);                 // 引数のアイテムのキーを返す
int hash_count(hash_obj* self);                             // アイテムの数を返す


// 全走査用
hash_it* hash_loop_begin(hash_obj* self);
void* hash_loop_item(hash_it* it);
char* hash_loop_key(hash_it* it);
hash_it* hash_loop_next(hash_it* it);

/*
 * 全走査(例)
 *
 * hash_it* i = hash_loop_begin(hash);
 * while(!it) {
 *     void* obj = hash_loop_item(it);
 *
 *     objの処理
 *
 *     it = hash_loop_next(it);
 * }
 *
 */

#endif
