fork download
  1. /*
  2.  * HashTable - ハッシュテーブル。
  3.  *
  4.  * Date: 2014-04-11
  5.  * Author: Leonardone
  6.  * Version: 2.0
  7.  */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. #define DEBUG_FLAG 1
  13.  
  14. #if DEBUG_FLAG
  15. # define DebugDo(d) d
  16. #else
  17. # define DebugDo(d)
  18. #endif
  19.  
  20. /* --- memory --- */
  21.  
  22. #define STATIC_MEMORY 1
  23.  
  24. #if STATIC_MEMORY
  25.  
  26. #define MEMORY_SIZE (4220)
  27. char buf[MEMORY_SIZE + 1];
  28. int bufptr;
  29.  
  30. void *myMalloc(size_t s) {
  31. char *tmp = buf + bufptr;
  32. DebugDo(printf("free: %d, request: %d\n", MEMORY_SIZE - bufptr, s));
  33. bufptr += s;
  34. if (bufptr > MEMORY_SIZE) {
  35. bufptr -= s;
  36. return NULL;
  37. }
  38. return (void*)tmp;
  39. }
  40.  
  41. # define Calloc(s1, s2) myMalloc((s1)*(s2))
  42. # define Malloc(s) myMalloc(s)
  43. # define Realloc(p, s) myMalloc(s)
  44. # define Free(p)
  45. #else
  46. # define Calloc(s1, s2) calloc(s1, s2)
  47. # define Malloc(s) malloc(s)
  48. # define Realloc(p, s) realloc(p, s)
  49. # define Free(p) free(p)
  50. #endif
  51.  
  52. /* --- hashtable.h --- */
  53.  
  54. #define MINIMUM_HASHTABLESIZE (0x0002)
  55. #define MAXIMUM_HASHTABLESIZE (0x7FFF)
  56.  
  57. struct _hashtable;
  58. struct _tabledata;
  59.  
  60. typedef struct _hashtable HashTable, *LPHashTable;
  61. typedef struct _tabledata TableData, *LPTableData;
  62.  
  63. extern LPHashTable newHashTable(const int tablesize, int (*keycmp)(const void *key1, const int key1len, const void *key2, const int key2len), int (*hash)(const void *key, const int keylen, const int tablesize));
  64. extern void releaseHashTable(LPHashTable htable);
  65. extern int addDataIntoHashTable(LPHashTable htable, const void *key, const int keylen, const void *data, const int size);
  66. extern int getDataFromHashTable(const LPHashTable htable, const void *key, const int keylen, void *data, const int size);
  67. extern int removeDataFromHashTable(LPHashTable htable, const void *key, const int keylen);
  68. extern int existKeyInHashTable(LPHashTable htable, const void *key, const int keylen);
  69. extern int setDataIntoHashTable(LPHashTable htable, const void *key, const int keylen, const void *data, const int size);
  70. extern int countDataInHashTable(LPHashTable htable);
  71. extern int getAllKeysInHashTable(const LPHashTable htable, int (*func)(const void *key, const int keylen));
  72. extern int getAllDataInHashTable(const LPHashTable htable, int (*func)(const void *key, const int keylen, const void *data, const int size));
  73.  
  74. struct _hashtable {
  75. int count;
  76. int tablesize;
  77. int (*keycmp)(const void* key1, const int key1len, const void *key2, const int key2len);
  78. int (*hash)(const void *key, const int keylen, const int tablesize);
  79. LPTableData *table;
  80. };
  81.  
  82. struct _tabledata {
  83. void *key;
  84. int keylen;
  85. void *data;
  86. int size;
  87. LPTableData next;
  88. };
  89.  
  90. /* --- hashtable_static.h --- */
  91.  
  92. #define HASH_DEEP (5)
  93.  
  94. static int defaultHash(const void *key, const int keylen, const int tablesize);
  95. static LPTableData *searchPlace(const LPHashTable htable, const void *key, const int keylen);
  96. static void releaseTableData(LPTableData ptbdata, int chain);
  97. static int defaultKeycmp(const void *key1, const int key1len, const void *key2, const int key2len);
  98. static int getHash(const LPHashTable htable, const void *key, const int keylen);
  99.  
  100. /* --- test.c --- */
  101.  
  102. int addIntIntoHashTable(LPHashTable htable, const char *key, const int value) {
  103. int ret = addDataIntoHashTable(htable, key, strlen(key) + 1, &value, sizeof(int));
  104. if (ret == 1) {
  105. DebugDo(printf("add(success): %s, value: %d\n", key, value));
  106. } else if (ret == 2) {
  107. DebugDo(printf("add(failure): %s, value: %d\n", key, value));
  108. } else {
  109. DebugDo(printf("add(fatal error): %s\n", key));
  110. }
  111. return ret;
  112. }
  113.  
  114. int getIntFromHashTable(const LPHashTable htable, const char *key, int *value) {
  115. int ret = getDataFromHashTable(htable, key, strlen(key) + 1, (void*)value, sizeof(int));
  116. if (ret) {
  117. DebugDo(printf("get(success): %s, size: %d\n", key, ret));
  118. } else {
  119. DebugDo(printf("get(failure): %s\n", key));
  120. }
  121. return ret;
  122. }
  123.  
  124. int setIntIntoHashTable(LPHashTable htable, const char *key, const int value) {
  125. int ret = setDataIntoHashTable(htable, key, strlen(key) + 1, &value, sizeof(int));
  126. if (ret == 1) {
  127. DebugDo(printf("set/new(success): %s, value: %d\n", key, value));
  128. } else if (ret == 2) {
  129. DebugDo(printf("set/update(success): %s, value: %d\n", key, value));
  130. } else {
  131. DebugDo(printf("set(fatal error): %s\n", key));
  132. }
  133. return ret;
  134. }
  135.  
  136. int func1(const void *key, const int keylen) {
  137. printf("key: %s\n", (char*)key);
  138. return 0;
  139. }
  140.  
  141. int func2(const void *key, const int keylen, const void *data, const int size) {
  142. printf("key: %s, data: %d\n", (char*)key, *(int*)data);
  143. return 0;
  144. }
  145.  
  146. int main(void) {
  147.  
  148. LPHashTable htable = newHashTable(1024, NULL, NULL);
  149. int v = 0;
  150.  
  151. if (htable == NULL) {
  152. printf("init Hashtable(fatal error)\n");
  153. }
  154.  
  155. addIntIntoHashTable(htable, "foo", 111);
  156. addIntIntoHashTable(htable, "bar", 222);
  157. addIntIntoHashTable(htable, "baz", 333);
  158. addIntIntoHashTable(htable, "fuga", 987);
  159. addIntIntoHashTable(htable, "piyo", 654);
  160.  
  161. if (htable) {
  162. printf("cnt: %d\n", htable->count);
  163. }
  164. printf("cnt: %d\n", countDataInHashTable(htable));
  165.  
  166. addIntIntoHashTable(htable, "hoge", 123);
  167. addIntIntoHashTable(htable, "hoge", 246);
  168. getIntFromHashTable(htable, "hoge", &v);
  169. printf("get: %d\n", v);
  170.  
  171. printf("cnt: %d\n", countDataInHashTable(htable));
  172.  
  173. setIntIntoHashTable(htable, "hoge", 345);
  174. setIntIntoHashTable(htable, "foobar", 999);
  175. getIntFromHashTable(htable, "hoge", &v);
  176. printf("get: %d\n", v);
  177.  
  178. getIntFromHashTable(htable, "baz", &v);
  179. printf("get: %d\n", v);
  180.  
  181. printf("cnt: %d\n", countDataInHashTable(htable));
  182.  
  183. getAllKeysInHashTable(htable, func1);
  184.  
  185. removeDataFromHashTable(htable, "baz", 4);
  186. removeDataFromHashTable(htable, "baz", 4);
  187. removeDataFromHashTable(htable, "test", 5);
  188.  
  189. printf("cnt: %d\n", countDataInHashTable(htable));
  190.  
  191. if (htable) { /* 非公開関数なので内部にエラートラップが無い */
  192. printf("sch: %d\n", (int)searchPlace(htable, "hoge", 5));
  193. printf("sch: %d\n", (int)searchPlace(htable, "abc", 4));
  194. printf("*sch: %d\n", (int)*searchPlace(htable, "hoge", 5));
  195. printf("*sch: %d\n", (int)*searchPlace(htable, "abc", 4));
  196. if (*searchPlace(htable, "hoge", 5)) {
  197. printf("*sch-d: %d\n", *(int*)(*searchPlace(htable, "hoge", 5))->data);
  198. }
  199. if (*searchPlace(htable, "bar", 4)) {
  200. printf("*sch-d: %d\n", *(int*)(*searchPlace(htable, "bar", 4))->data);
  201. }
  202. }
  203.  
  204. printf("ext: %d\n", existKeyInHashTable(htable, "hoge", 5));
  205. printf("ext: %d\n", existKeyInHashTable(htable, "abc", 4));
  206. printf("ext: %d\n", existKeyInHashTable(htable, "foo", 4));
  207. printf("ext: %d\n", existKeyInHashTable(htable, "baz", 4));
  208. printf("ext: %d\n", existKeyInHashTable(htable, "fuga", 5));
  209. printf("ext: %d\n", existKeyInHashTable(htable, "piyo", 5));
  210.  
  211. getAllDataInHashTable(htable, func2);
  212.  
  213. releaseHashTable(htable);
  214.  
  215. return 0;
  216. }
  217.  
  218. /* --- hashtable.c --- */
  219.  
  220. /* +++ extern functions +++ */
  221.  
  222. /**
  223.  * 新しいHashTableを作る。
  224.  * @param tablesize
  225.  * @param keycmp
  226.  * @param hash
  227.  * @return
  228.  */
  229. LPHashTable newHashTable(const int tablesize,
  230. int (*keycmp)(const void *key1, const int key1len, const void *key2, const int key2len),
  231. int (*hash)(const void *key, const int keylen, const int tablesize)) {
  232. /* calloc は 0 で初期化される */
  233. LPHashTable htable;
  234. if (tablesize < MINIMUM_HASHTABLESIZE || tablesize > MAXIMUM_HASHTABLESIZE) {
  235. return NULL; /* 引数エラー */
  236. }
  237. htable = (LPHashTable)Calloc(1, sizeof(HashTable));
  238. if (htable == NULL) {
  239. return NULL; /* メモリ確保失敗 */
  240. }
  241. htable->table = (LPTableData *)Calloc(tablesize, sizeof(LPTableData));
  242. if (htable->table == NULL) {
  243. Free(htable);
  244. return NULL; /* メモリ確保失敗 */
  245. }
  246. htable->tablesize = tablesize;
  247. if (keycmp == NULL) {
  248. htable->keycmp = defaultKeycmp;
  249. } else {
  250. htable->keycmp = keycmp;
  251. }
  252. if (hash == NULL) {
  253. htable->hash = defaultHash;
  254. } else {
  255. htable->hash = hash;
  256. }
  257. DebugDo(printf("init HashTable(%d)\n", tablesize));
  258. return htable;
  259. }
  260.  
  261. /**
  262.  * HashTableをメモリから解放する。
  263.  * @param htable
  264.  */
  265. void releaseHashTable(LPHashTable htable) {
  266. int i;
  267. int tablesize;
  268. LPTableData *ptbdata;
  269. if (htable == NULL) {
  270. return; /* ぬるぽ */
  271. }
  272. tablesize = htable->tablesize;
  273. for (i = 0; i < tablesize; ++i) {
  274. ptbdata = htable->table + i;
  275. if (*ptbdata != NULL) {
  276. releaseTableData(*ptbdata, 1);
  277. }
  278. }
  279. Free(htable->table);
  280. Free(htable);
  281. DebugDo(printf("release HashTable(%d)\n", tablesize));
  282. }
  283.  
  284. /**
  285.  * HashTableにデータを追加する。既にキー名が存在する場合は失敗する。
  286.  * @param htable
  287.  * @param key
  288.  * @param keylen
  289.  * @param data
  290.  * @param size
  291.  * @return
  292.  */
  293. int addDataIntoHashTable(LPHashTable htable, const void *key, const int keylen, const void *data, const int size) {
  294. LPTableData *ptbdata;
  295. if (htable == NULL || key == NULL || data == NULL || size < 1 || keylen < 1) {
  296. return 0; /* 引数エラー */
  297. }
  298. ptbdata = searchPlace(htable, key, keylen);
  299. if (*ptbdata == NULL) {
  300. *ptbdata = (LPTableData)Calloc(1, sizeof(TableData));
  301. if (*ptbdata == NULL) {
  302. return 0; /* メモリ確保失敗 */
  303. }
  304. (*ptbdata)->key = Malloc(keylen);
  305. if ((*ptbdata)->key == NULL) {
  306. Free(*ptbdata);
  307. *ptbdata = NULL;
  308. return 0; /* メモリ確保失敗 */
  309. }
  310. (*ptbdata)->data = Malloc(size);
  311. if ((*ptbdata)->data == NULL) {
  312. Free((*ptbdata)->key);
  313. Free(*ptbdata);
  314. *ptbdata = NULL;
  315. return 0; /* メモリ確保失敗 */
  316. }
  317. memcpy((*ptbdata)->key, key, keylen);
  318. (*ptbdata)->keylen = keylen;
  319. memcpy((*ptbdata)->data, data, size);
  320. (*ptbdata)->size = size;
  321. ++(htable->count);
  322. return 1; /* 成功 */
  323. }
  324. return 2; /* キー名重複 */
  325. }
  326.  
  327. /**
  328.  * HashTableからキー名のデータを取得する。
  329.  * @param htable
  330.  * @param key
  331.  * @param keylen
  332.  * @param data
  333.  * @param size
  334.  * @return
  335.  */
  336. int getDataFromHashTable(const LPHashTable htable, const void *key, const int keylen, void *data, const int size) {
  337. int minsize;
  338. LPTableData tbdata;
  339. if (htable == NULL || key == NULL || data == NULL || size < 1 || keylen < 1) {
  340. return 0; /* 引数エラー */
  341. }
  342. tbdata = *searchPlace(htable, key, keylen);
  343. if (tbdata != NULL) {
  344. minsize = tbdata->size < size ? tbdata->size : size;
  345. memcpy(data, tbdata->data, minsize);
  346. return minsize;
  347. }
  348. return 0;
  349. }
  350.  
  351. /**
  352.  * HashTableにデータを書き込む。既にキー名のデータがある場合は上書きする。
  353.  * @param htable
  354.  * @param key
  355.  * @param keylen
  356.  * @param data
  357.  * @param size
  358.  * @return
  359.  */
  360. int setDataIntoHashTable(LPHashTable htable, const void *key, const int keylen, const void *data, const int size) {
  361. int ret = 1;
  362. void *temp;
  363. LPTableData *ptbdata;
  364. if (htable == NULL || key == NULL || data == NULL || size < 1 || keylen < 1) {
  365. return 0; /* 引数エラー */
  366. }
  367. ptbdata = searchPlace(htable, key, keylen);
  368. if (*ptbdata == NULL) {
  369. *ptbdata = (LPTableData)Calloc(1, sizeof(TableData));
  370. if (*ptbdata == NULL) {
  371. return 0; /* メモリ確保失敗 */
  372. }
  373. (*ptbdata)->key = Malloc(keylen);
  374. if ((*ptbdata)->key == NULL) {
  375. Free(*ptbdata);
  376. *ptbdata = NULL;
  377. return 0; /* メモリ確保失敗 */
  378. }
  379. (*ptbdata)->data = Malloc(size);
  380. if ((*ptbdata)->data == NULL) {
  381. Free((*ptbdata)->key);
  382. Free(*ptbdata);
  383. *ptbdata = NULL;
  384. return 0; /* メモリ確保失敗 */
  385. }
  386. memcpy((*ptbdata)->key, key, keylen);
  387. (*ptbdata)->keylen = keylen;
  388. (*ptbdata)->size = size;
  389. ++(htable->count);
  390. } else {
  391. if ((*ptbdata)->size != size) {
  392. temp = Realloc((*ptbdata)->data, size);
  393. if (temp == NULL) {
  394. return 0; /* メモリ確保失敗 */
  395. }
  396. (*ptbdata)->data = temp;
  397. (*ptbdata)->size = size;
  398. }
  399. ret = 2;
  400. }
  401. memcpy((*ptbdata)->data, data, size);
  402. return ret;
  403. }
  404.  
  405. /**
  406.  * HashTable内の指定キー名のデータを削除する。
  407.  * @param htable HashTable。
  408.  * @param key キー名。
  409.  * @return 削除できたら(1)、失敗したら(0)。
  410.  */
  411. int removeDataFromHashTable(LPHashTable htable, const void *key, const int keylen) {
  412. LPTableData *ptbdata;
  413. LPTableData tbdata;
  414. if (htable == NULL || key == NULL || keylen < 1) {
  415. return 0; /* ぬるぽ */
  416. }
  417. ptbdata = searchPlace(htable, key, keylen);
  418. if (*ptbdata != NULL) {
  419. tbdata = *ptbdata;
  420. *ptbdata = tbdata->next;
  421. releaseTableData(tbdata, 0);
  422. --(htable->count);
  423. DebugDo(printf("remove(success): %d %d\n", *(char*)key, keylen));
  424. return 1;
  425. }
  426. DebugDo(printf("remove(failure): %d %d\n", *(char*)key, keylen));
  427. return 0;
  428. }
  429.  
  430. /**
  431.  * HashTable内にキー名のデータが存在するか書くにする。
  432.  * @param htable HashTable。
  433.  * @param key 探すキー名。
  434.  * @param keylen
  435.  * @return 存在すれば(1)、存在しなければ(0)。
  436.  */
  437. int existKeyInHashTable(LPHashTable htable, const void *key, const int keylen) {
  438. if (htable == NULL || key == NULL || keylen < 1) {
  439. return 0; /* ぬるぽ */
  440. }
  441. return *searchPlace(htable, key, keylen) != NULL;
  442. }
  443.  
  444. /**
  445.  * HashTable内のデータ数を返す。
  446.  * @param htable HashTable。
  447.  * @return データ数。
  448.  */
  449. int countDataInHashTable(LPHashTable htable) {
  450. if (htable == NULL) {
  451. return 0; /* ぬるぽ */
  452. }
  453. return htable->count;
  454. }
  455.  
  456. /**
  457.  * HashTable内のキー名を全て取得する。
  458.  * @param htable
  459.  * @param func
  460.  * @return
  461.  */
  462. int getAllKeysInHashTable(const LPHashTable htable, int (*func)(const void *key, const int keylen)) {
  463. int i;
  464. int ret;
  465. int tablesize;
  466. LPTableData *ptbdata;
  467. LPTableData tbdata;
  468. if (htable == NULL || func == NULL) {
  469. return 0;
  470. }
  471. DebugDo(printf("allkey(start)\n"));
  472. ptbdata = htable->table;
  473. tablesize = htable->tablesize;
  474. for (i = 0; i < tablesize; ++i) {
  475. tbdata = *ptbdata;
  476. while (tbdata != NULL) {
  477. ret = (*func)(tbdata->key, tbdata->keylen);
  478. if (ret) {
  479. DebugDo(printf("allkey(stop)\n"));
  480. return 2;
  481. }
  482. tbdata = tbdata->next;
  483. }
  484. ++ptbdata;
  485. }
  486. DebugDo(printf("allkey(done)\n"));
  487. return 1;
  488. }
  489.  
  490. /**
  491.  * HashTable内のデータを全て取得する。
  492.  * @param htable
  493.  * @param func
  494.  * @return
  495.  */
  496. int getAllDataInHashTable(const LPHashTable htable, int (*func)(const void *key, const int keylen, const void *data, const int size)) {
  497. int i;
  498. int ret;
  499. int tablesize;
  500. LPTableData *ptbdata;
  501. LPTableData tbdata;
  502. if (htable == NULL || func == NULL) {
  503. return 0;
  504. }
  505. DebugDo(printf("alldata(start)\n"));
  506. ptbdata = htable->table;
  507. tablesize = htable->tablesize;
  508. for (i = 0; i < tablesize; ++i) {
  509. tbdata = *ptbdata;
  510. while (tbdata != NULL) {
  511. ret = (*func)(tbdata->key, tbdata->keylen, tbdata->data, tbdata->size);
  512. if (ret) {
  513. DebugDo(printf("alldata(stop)\n"));
  514. return 2;
  515. }
  516. tbdata = tbdata->next;
  517. }
  518. ++ptbdata;
  519. }
  520. DebugDo(printf("alldata(done)\n"));
  521. return 1;
  522. }
  523.  
  524. /* +++ static functions +++ */
  525.  
  526. /**
  527.  * キーの比較。
  528.  * @param key1
  529.  * @param key1len
  530.  * @param key2
  531.  * @param key2len
  532.  * @return
  533.  */
  534. int defaultKeycmp(const void *key1, const int key1len, const void *key2, const int key2len) {
  535. if (key1len != key2len) {
  536. return key1len - key2len;
  537. }
  538. return memcmp(key1, key2, key1len);
  539. }
  540.  
  541. /**
  542.  * ハッシュ関数。キー名からハッシュ値を生成する。
  543.  * @param key キー名。
  544.  * @param keylen
  545.  * @param tablesize
  546.  * @return ハッシュ値。
  547.  */
  548. int defaultHash(const void *key, const int keylen, const int tablesize) {
  549. int i;
  550. char *p = (char*)key;
  551. int v = (int)*p;
  552. int lm = keylen - 1;
  553. for (i = 0; i < HASH_DEEP && i < lm; i++) {
  554. v ^= (int)(*p) * (int)(*(p + 1));
  555. ++p;
  556. }
  557. return v;
  558. }
  559.  
  560. /**
  561.  * ハッシュ値を取得する。
  562.  * @param htable
  563.  * @param key
  564.  * @param keyleln
  565.  */
  566. int getHash(const LPHashTable htable, const void *key, const int keylen) {
  567. int h = (*(htable->hash))(key, keylen, htable->tablesize);
  568. if (h < 0) {
  569. h = ~h;
  570. }
  571. return h % htable->tablesize;
  572. }
  573.  
  574. /**
  575.  * HashTableからキー名のデータを格納する場所(アドレス)を探す。
  576.  * @param htable キー名を探すHashTable。
  577.  * @param key 探すキー名。
  578.  * @param keylen
  579.  * @return 格納されてる場所(アドレス)。
  580.  */
  581. LPTableData *searchPlace(const LPHashTable htable, const void *key, const int keylen) {
  582. int h = getHash(htable, key, keylen);
  583. LPTableData *ptbdata = htable->table + h;
  584. while (*ptbdata != NULL) {
  585. if ((*(htable->keycmp))((*ptbdata)->key, (*ptbdata)->keylen, key, keylen) == 0) {
  586. break;
  587. }
  588. ptbdata = &(*ptbdata)->next;
  589. }
  590. DebugDo(printf("hash: %d %d -> %d\n", *(char*)key, keylen, h));
  591. return ptbdata;
  592. }
  593.  
  594. /**
  595.  * TableDataをメモリから解放する。
  596.  * @param ptbdata 解放するデータ。
  597.  * @param chain nextにあるTableDataも解放する(1)かしない(0)か。
  598.  */
  599. void releaseTableData(LPTableData tbdata, int chain) {
  600. if (tbdata == NULL) {
  601. return;
  602. }
  603. if (chain) {
  604. releaseTableData(tbdata->next, chain);
  605. }
  606. DebugDo(printf("release TableData: %d %d\n", *((char*)(tbdata->key)), tbdata->keylen));
  607. Free(tbdata->key);
  608. Free(tbdata->data);
  609. Free(tbdata);
  610. }
Success #stdin #stdout 0s 2256KB
stdin
Standard input is empty
stdout
free: 4220, request: 20
free: 4200, request: 4096
init HashTable(1024)
hash: 102 4 -> 125
free: 104, request: 20
free: 84, request: 4
free: 80, request: 4
add(success): foo, value: 111
hash: 98 4 -> 626
free: 76, request: 20
free: 56, request: 4
free: 52, request: 4
add(success): bar, value: 222
hash: 98 4 -> 890
free: 48, request: 20
free: 28, request: 4
free: 24, request: 4
add(success): baz, value: 333
hash: 102 5 -> 748
free: 20, request: 20
free: 0, request: 5
add(fatal error): fuga
hash: 112 5 -> 86
free: 0, request: 20
add(fatal error): piyo
cnt: 3
cnt: 3
hash: 104 5 -> 378
free: 0, request: 20
add(fatal error): hoge
hash: 104 5 -> 378
free: 0, request: 20
add(fatal error): hoge
hash: 104 5 -> 378
get(failure): hoge
get: 0
cnt: 3
hash: 104 5 -> 378
free: 0, request: 20
set(fatal error): hoge
hash: 102 7 -> 19
free: 0, request: 20
set(fatal error): foobar
hash: 104 5 -> 378
get(failure): hoge
get: 0
hash: 98 4 -> 890
get(success): baz, size: 4
get: 333
cnt: 3
allkey(start)
key: foo
key: bar
key: baz
allkey(done)
hash: 98 4 -> 890
release TableData: 98 4
remove(success): 98 4
hash: 98 4 -> 890
remove(failure): 98 4
hash: 116 5 -> 243
remove(failure): 116 5
cnt: 2
hash: 104 5 -> 378
sch: 134522748
hash: 97 4 -> 165
sch: 134521896
hash: 104 5 -> 378
*sch: 0
hash: 97 4 -> 165
*sch: 0
hash: 104 5 -> 378
hash: 98 4 -> 626
hash: 98 4 -> 626
*sch-d: 222
hash: 104 5 -> 378
ext: 0
hash: 97 4 -> 165
ext: 0
hash: 102 4 -> 125
ext: 1
hash: 98 4 -> 890
ext: 0
hash: 102 5 -> 748
ext: 0
hash: 112 5 -> 86
ext: 0
alldata(start)
key: foo, data: 111
key: bar, data: 222
alldata(done)
release TableData: 102 4
release TableData: 98 4
release HashTable(1024)