From b3a958feb03694e2f0df71482875684e45353964 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Mon, 4 Oct 2021 16:32:23 +0100 Subject: [PATCH] Update uthash to v2.3.0 Also delete files and folders that are only useful in the original repository. Updating uthash to this version allows compiling with CHERI LLVM where the current version of uthash (1.9.8) triggers a warning that our build infrastructure includes in -Werror by default: ``` ../../libglvnd/src/util/winsys_dispatch.c:154:9: error: cast from provenance-free integer type to pointer type will give pointer that can not be dereferenced [-Werror,-Wcheri-capability-misuse] ../../libglvnd/include/lkdhash.h:86:5: note: expanded from macro 'LKDHASH_TEARDOWN' LKDHASH_TEARDOWN_2(_lh, _param, cur ## _ht, \ ^ ../../libglvnd/include/lkdhash.h:55:9: note: expanded from macro 'LKDHASH_TEARDOWN_2' HASH_DEL(_LH(_lockedhash), _cur); \ ^ ../../libglvnd/src/util/uthash/src/uthash.h:271:5: note: expanded from macro 'HASH_DEL' HASH_DELETE(hh,head,delptr) ^ ../../libglvnd/src/util/uthash/src/uthash.h:239:14: note: expanded from macro 'HASH_DELETE' ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ ^ ``` Signed-off-by: Alex Richardson --- src/util/uthash/LICENSE | 2 +- src/util/uthash/README.md | 4 +- src/util/uthash/doc/ChangeLog.html | 1504 -------- src/util/uthash/doc/ChangeLog.txt | 230 -- src/util/uthash/doc/banner.png | Bin 20477 -> 0 bytes src/util/uthash/doc/banner.svg | 451 --- .../uthash/doc/google315d692c9c632ed0.html | 1 - src/util/uthash/doc/index.html | 124 - src/util/uthash/doc/license.html | 55 - src/util/uthash/doc/rss.png | Bin 689 -> 0 bytes src/util/uthash/doc/styles.css | 141 - src/util/uthash/doc/todo.txt | 4 - src/util/uthash/doc/userguide.html | 3034 ----------------- src/util/uthash/doc/userguide.txt | 1793 ---------- src/util/uthash/doc/utarray.html | 1265 ------- src/util/uthash/doc/utarray.txt | 374 -- src/util/uthash/doc/uthash-mini.png | Bin 3611 -> 0 bytes src/util/uthash/doc/uthash-mini.svg | 288 -- src/util/uthash/doc/uthash.png | Bin 21518 -> 0 bytes src/util/uthash/doc/utlist.html | 1189 ------- src/util/uthash/doc/utlist.txt | 264 -- src/util/uthash/doc/utstring.html | 1074 ------ src/util/uthash/doc/utstring.txt | 229 -- src/util/uthash/include | 1 + src/util/uthash/src/utarray.h | 120 +- src/util/uthash/src/uthash.h | 1298 ++++--- src/util/uthash/src/utlist.h | 782 +++-- src/util/uthash/src/utringbuffer.h | 108 + src/util/uthash/src/utstack.h | 88 + src/util/uthash/src/utstring.h | 139 +- src/util/uthash/tests/README | 116 - src/util/uthash/tests/all_funcs | 14 - src/util/uthash/tests/bloom_perf.c | 64 - src/util/uthash/tests/bloom_perf.sh | 17 - src/util/uthash/tests/do_tests | 21 - src/util/uthash/tests/do_tests.cygwin | 22 - src/util/uthash/tests/do_tests.mingw | 20 - src/util/uthash/tests/do_tests_win32.cmd | 16 - src/util/uthash/tests/emit_keys.c | 44 - src/util/uthash/tests/example.c | 135 - src/util/uthash/tests/hashscan.c | 589 ---- src/util/uthash/tests/keystat.c | 219 -- src/util/uthash/tests/keystats | 40 - src/util/uthash/tests/lru_cache/cache.c | 221 -- src/util/uthash/tests/lru_cache/cache.h | 31 - src/util/uthash/tests/lru_cache/main.c | 191 -- src/util/uthash/tests/mexpand | 21 - src/util/uthash/tests/simkeys.pl | 28 - src/util/uthash/tests/sleep_test.c | 29 - src/util/uthash/tests/tdiff.cpp | 34 - src/util/uthash/tests/test1.ans | 10 - src/util/uthash/tests/test1.c | 27 - src/util/uthash/tests/test10.ans | 4 - src/util/uthash/tests/test10.c | 45 - src/util/uthash/tests/test11.ans | 51 - src/util/uthash/tests/test11.c | 50 - src/util/uthash/tests/test11.dat | 51 - src/util/uthash/tests/test12.ans | 20 - src/util/uthash/tests/test12.c | 34 - src/util/uthash/tests/test13.ans | 5 - src/util/uthash/tests/test13.c | 42 - src/util/uthash/tests/test14.ans | 1 - src/util/uthash/tests/test14.c | 46 - src/util/uthash/tests/test14.dat | 1219 ------- src/util/uthash/tests/test15.ans | 1 - src/util/uthash/tests/test15.c | 34 - src/util/uthash/tests/test16.ans | 1 - src/util/uthash/tests/test16.c | 46 - src/util/uthash/tests/test17.ans | 134 - src/util/uthash/tests/test17.c | 55 - src/util/uthash/tests/test18.ans | 20 - src/util/uthash/tests/test18.c | 33 - src/util/uthash/tests/test19.ans | 1012 ------ src/util/uthash/tests/test19.c | 52 - src/util/uthash/tests/test2.ans | 5 - src/util/uthash/tests/test2.c | 31 - src/util/uthash/tests/test20.ans | 1 - src/util/uthash/tests/test20.c | 28 - src/util/uthash/tests/test21.ans | 1 - src/util/uthash/tests/test21.c | 38 - src/util/uthash/tests/test22.ans | 1 - src/util/uthash/tests/test22.c | 59 - src/util/uthash/tests/test23.ans | 6 - src/util/uthash/tests/test23.c | 44 - src/util/uthash/tests/test24.ans | 1 - src/util/uthash/tests/test24.c | 25 - src/util/uthash/tests/test25.ans | 28 - src/util/uthash/tests/test25.c | 112 - src/util/uthash/tests/test26.ans | 53 - src/util/uthash/tests/test26.c | 52 - src/util/uthash/tests/test27.ans | 28 - src/util/uthash/tests/test27.c | 112 - src/util/uthash/tests/test28.ans | 34 - src/util/uthash/tests/test28.c | 132 - src/util/uthash/tests/test29.ans | 103 - src/util/uthash/tests/test29.c | 48 - src/util/uthash/tests/test3.ans | 5 - src/util/uthash/tests/test3.c | 38 - src/util/uthash/tests/test30.ans | 51 - src/util/uthash/tests/test30.c | 43 - src/util/uthash/tests/test31.ans | 51 - src/util/uthash/tests/test31.c | 43 - src/util/uthash/tests/test32.ans | 51 - src/util/uthash/tests/test32.c | 41 - src/util/uthash/tests/test33.ans | 51 - src/util/uthash/tests/test33.c | 43 - src/util/uthash/tests/test34.ans | 51 - src/util/uthash/tests/test34.c | 41 - src/util/uthash/tests/test35.ans | 30 - src/util/uthash/tests/test35.c | 37 - src/util/uthash/tests/test36.ans | 15 - src/util/uthash/tests/test36.c | 46 - src/util/uthash/tests/test37.ans | 20 - src/util/uthash/tests/test37.c | 51 - src/util/uthash/tests/test38.ans | 1 - src/util/uthash/tests/test38.c | 28 - src/util/uthash/tests/test39.ans | 7 - src/util/uthash/tests/test39.c | 31 - src/util/uthash/tests/test4.ans | 10 - src/util/uthash/tests/test4.c | 29 - src/util/uthash/tests/test40.ans | 1 - src/util/uthash/tests/test40.c | 34 - src/util/uthash/tests/test41.ans | 6 - src/util/uthash/tests/test41.c | 58 - src/util/uthash/tests/test42.ans | 14 - src/util/uthash/tests/test42.c | 65 - src/util/uthash/tests/test43.ans | 88 - src/util/uthash/tests/test43.c | 76 - src/util/uthash/tests/test44.ans | 9 - src/util/uthash/tests/test44.c | 44 - src/util/uthash/tests/test45.ans | 3 - src/util/uthash/tests/test45.c | 24 - src/util/uthash/tests/test46.ans | 11 - src/util/uthash/tests/test46.c | 49 - src/util/uthash/tests/test47.ans | 8 - src/util/uthash/tests/test47.c | 28 - src/util/uthash/tests/test48.ans | 10 - src/util/uthash/tests/test48.c | 20 - src/util/uthash/tests/test49.ans | 2 - src/util/uthash/tests/test49.c | 20 - src/util/uthash/tests/test5.ans | 5 - src/util/uthash/tests/test5.c | 33 - src/util/uthash/tests/test50.ans | 2 - src/util/uthash/tests/test50.c | 19 - src/util/uthash/tests/test51.ans | 2 - src/util/uthash/tests/test51.c | 28 - src/util/uthash/tests/test52.ans | 2 - src/util/uthash/tests/test52.c | 39 - src/util/uthash/tests/test53.ans | 1 - src/util/uthash/tests/test53.c | 13 - src/util/uthash/tests/test54.ans | 2 - src/util/uthash/tests/test54.c | 23 - src/util/uthash/tests/test55.ans | 2 - src/util/uthash/tests/test55.c | 18 - src/util/uthash/tests/test56.ans | 65 - src/util/uthash/tests/test56.c | 86 - src/util/uthash/tests/test57.ans | 1 - src/util/uthash/tests/test57.c | 28 - src/util/uthash/tests/test58.ans | 18 - src/util/uthash/tests/test58.c | 55 - src/util/uthash/tests/test59.ans | 1 - src/util/uthash/tests/test59.c | 51 - src/util/uthash/tests/test6.ans | 1 - src/util/uthash/tests/test6.c | 52 - src/util/uthash/tests/test60.ans | 1 - src/util/uthash/tests/test60.c | 45 - src/util/uthash/tests/test61.ans | 16 - src/util/uthash/tests/test61.c | 42 - src/util/uthash/tests/test62.ans | 20 - src/util/uthash/tests/test62.c | 61 - src/util/uthash/tests/test63.ans | 7 - src/util/uthash/tests/test63.c | 47 - src/util/uthash/tests/test64.ans | 7 - src/util/uthash/tests/test64.c | 47 - src/util/uthash/tests/test65.ans | 4 - src/util/uthash/tests/test65.c | 72 - src/util/uthash/tests/test65.dat | 51 - src/util/uthash/tests/test66.ans | 20 - src/util/uthash/tests/test66.c | 37 - src/util/uthash/tests/test67.ans | 20 - src/util/uthash/tests/test67.c | 27 - src/util/uthash/tests/test68.ans | 10 - src/util/uthash/tests/test68.c | 57 - src/util/uthash/tests/test69.ans | 11 - src/util/uthash/tests/test69.c | 59 - src/util/uthash/tests/test7.ans | 0 src/util/uthash/tests/test7.c | 38 - src/util/uthash/tests/test70.ans | 10 - src/util/uthash/tests/test70.c | 57 - src/util/uthash/tests/test71.ans | 11 - src/util/uthash/tests/test71.c | 59 - src/util/uthash/tests/test72.ans | 10 - src/util/uthash/tests/test72.c | 57 - src/util/uthash/tests/test73.ans | 11 - src/util/uthash/tests/test73.c | 59 - src/util/uthash/tests/test74.ans | 6 - src/util/uthash/tests/test74.c | 41 - src/util/uthash/tests/test75.ans | 6 - src/util/uthash/tests/test75.c | 41 - src/util/uthash/tests/test76.ans | 6 - src/util/uthash/tests/test76.c | 58 - src/util/uthash/tests/test77.ans | 13 - src/util/uthash/tests/test77.c | 71 - src/util/uthash/tests/test78.ans | 28 - src/util/uthash/tests/test78.c | 112 - src/util/uthash/tests/test79.ans | 8 - src/util/uthash/tests/test79.c | 57 - src/util/uthash/tests/test8.ans | 15 - src/util/uthash/tests/test8.c | 34 - src/util/uthash/tests/test80.ans | 6 - src/util/uthash/tests/test80.c | 20 - src/util/uthash/tests/test81.ans | 6 - src/util/uthash/tests/test81.c | 20 - src/util/uthash/tests/test82.ans | 9 - src/util/uthash/tests/test82.c | 31 - src/util/uthash/tests/test9.ans | 500 --- src/util/uthash/tests/test9.c | 31 - src/util/uthash/tests/threads/README | 2 - src/util/uthash/tests/threads/do_tests | 22 - src/util/uthash/tests/threads/test1.c | 111 - src/util/uthash/tests/threads/test2.c | 70 - 221 files changed, 1655 insertions(+), 22942 deletions(-) delete mode 100644 src/util/uthash/doc/ChangeLog.html delete mode 100644 src/util/uthash/doc/ChangeLog.txt delete mode 100644 src/util/uthash/doc/banner.png delete mode 100644 src/util/uthash/doc/banner.svg delete mode 100644 src/util/uthash/doc/google315d692c9c632ed0.html delete mode 100644 src/util/uthash/doc/index.html delete mode 100644 src/util/uthash/doc/license.html delete mode 100644 src/util/uthash/doc/rss.png delete mode 100644 src/util/uthash/doc/styles.css delete mode 100644 src/util/uthash/doc/todo.txt delete mode 100644 src/util/uthash/doc/userguide.html delete mode 100644 src/util/uthash/doc/userguide.txt delete mode 100644 src/util/uthash/doc/utarray.html delete mode 100644 src/util/uthash/doc/utarray.txt delete mode 100644 src/util/uthash/doc/uthash-mini.png delete mode 100644 src/util/uthash/doc/uthash-mini.svg delete mode 100644 src/util/uthash/doc/uthash.png delete mode 100644 src/util/uthash/doc/utlist.html delete mode 100644 src/util/uthash/doc/utlist.txt delete mode 100644 src/util/uthash/doc/utstring.html delete mode 100644 src/util/uthash/doc/utstring.txt create mode 120000 src/util/uthash/include create mode 100644 src/util/uthash/src/utringbuffer.h create mode 100644 src/util/uthash/src/utstack.h delete mode 100644 src/util/uthash/tests/README delete mode 100755 src/util/uthash/tests/all_funcs delete mode 100644 src/util/uthash/tests/bloom_perf.c delete mode 100755 src/util/uthash/tests/bloom_perf.sh delete mode 100755 src/util/uthash/tests/do_tests delete mode 100755 src/util/uthash/tests/do_tests.cygwin delete mode 100644 src/util/uthash/tests/do_tests.mingw delete mode 100644 src/util/uthash/tests/do_tests_win32.cmd delete mode 100644 src/util/uthash/tests/emit_keys.c delete mode 100644 src/util/uthash/tests/example.c delete mode 100644 src/util/uthash/tests/hashscan.c delete mode 100644 src/util/uthash/tests/keystat.c delete mode 100755 src/util/uthash/tests/keystats delete mode 100644 src/util/uthash/tests/lru_cache/cache.c delete mode 100644 src/util/uthash/tests/lru_cache/cache.h delete mode 100644 src/util/uthash/tests/lru_cache/main.c delete mode 100755 src/util/uthash/tests/mexpand delete mode 100755 src/util/uthash/tests/simkeys.pl delete mode 100644 src/util/uthash/tests/sleep_test.c delete mode 100644 src/util/uthash/tests/tdiff.cpp delete mode 100644 src/util/uthash/tests/test1.ans delete mode 100644 src/util/uthash/tests/test1.c delete mode 100644 src/util/uthash/tests/test10.ans delete mode 100644 src/util/uthash/tests/test10.c delete mode 100644 src/util/uthash/tests/test11.ans delete mode 100644 src/util/uthash/tests/test11.c delete mode 100644 src/util/uthash/tests/test11.dat delete mode 100644 src/util/uthash/tests/test12.ans delete mode 100644 src/util/uthash/tests/test12.c delete mode 100644 src/util/uthash/tests/test13.ans delete mode 100644 src/util/uthash/tests/test13.c delete mode 100644 src/util/uthash/tests/test14.ans delete mode 100644 src/util/uthash/tests/test14.c delete mode 100644 src/util/uthash/tests/test14.dat delete mode 100644 src/util/uthash/tests/test15.ans delete mode 100644 src/util/uthash/tests/test15.c delete mode 100644 src/util/uthash/tests/test16.ans delete mode 100644 src/util/uthash/tests/test16.c delete mode 100644 src/util/uthash/tests/test17.ans delete mode 100644 src/util/uthash/tests/test17.c delete mode 100644 src/util/uthash/tests/test18.ans delete mode 100644 src/util/uthash/tests/test18.c delete mode 100644 src/util/uthash/tests/test19.ans delete mode 100644 src/util/uthash/tests/test19.c delete mode 100644 src/util/uthash/tests/test2.ans delete mode 100644 src/util/uthash/tests/test2.c delete mode 100644 src/util/uthash/tests/test20.ans delete mode 100644 src/util/uthash/tests/test20.c delete mode 100644 src/util/uthash/tests/test21.ans delete mode 100644 src/util/uthash/tests/test21.c delete mode 100644 src/util/uthash/tests/test22.ans delete mode 100644 src/util/uthash/tests/test22.c delete mode 100644 src/util/uthash/tests/test23.ans delete mode 100644 src/util/uthash/tests/test23.c delete mode 100644 src/util/uthash/tests/test24.ans delete mode 100644 src/util/uthash/tests/test24.c delete mode 100644 src/util/uthash/tests/test25.ans delete mode 100644 src/util/uthash/tests/test25.c delete mode 100644 src/util/uthash/tests/test26.ans delete mode 100644 src/util/uthash/tests/test26.c delete mode 100644 src/util/uthash/tests/test27.ans delete mode 100644 src/util/uthash/tests/test27.c delete mode 100644 src/util/uthash/tests/test28.ans delete mode 100644 src/util/uthash/tests/test28.c delete mode 100644 src/util/uthash/tests/test29.ans delete mode 100644 src/util/uthash/tests/test29.c delete mode 100644 src/util/uthash/tests/test3.ans delete mode 100644 src/util/uthash/tests/test3.c delete mode 100644 src/util/uthash/tests/test30.ans delete mode 100644 src/util/uthash/tests/test30.c delete mode 100644 src/util/uthash/tests/test31.ans delete mode 100644 src/util/uthash/tests/test31.c delete mode 100644 src/util/uthash/tests/test32.ans delete mode 100644 src/util/uthash/tests/test32.c delete mode 100644 src/util/uthash/tests/test33.ans delete mode 100644 src/util/uthash/tests/test33.c delete mode 100644 src/util/uthash/tests/test34.ans delete mode 100644 src/util/uthash/tests/test34.c delete mode 100644 src/util/uthash/tests/test35.ans delete mode 100644 src/util/uthash/tests/test35.c delete mode 100644 src/util/uthash/tests/test36.ans delete mode 100644 src/util/uthash/tests/test36.c delete mode 100644 src/util/uthash/tests/test37.ans delete mode 100644 src/util/uthash/tests/test37.c delete mode 100644 src/util/uthash/tests/test38.ans delete mode 100644 src/util/uthash/tests/test38.c delete mode 100644 src/util/uthash/tests/test39.ans delete mode 100644 src/util/uthash/tests/test39.c delete mode 100644 src/util/uthash/tests/test4.ans delete mode 100644 src/util/uthash/tests/test4.c delete mode 100644 src/util/uthash/tests/test40.ans delete mode 100644 src/util/uthash/tests/test40.c delete mode 100644 src/util/uthash/tests/test41.ans delete mode 100644 src/util/uthash/tests/test41.c delete mode 100644 src/util/uthash/tests/test42.ans delete mode 100644 src/util/uthash/tests/test42.c delete mode 100644 src/util/uthash/tests/test43.ans delete mode 100644 src/util/uthash/tests/test43.c delete mode 100644 src/util/uthash/tests/test44.ans delete mode 100644 src/util/uthash/tests/test44.c delete mode 100644 src/util/uthash/tests/test45.ans delete mode 100644 src/util/uthash/tests/test45.c delete mode 100644 src/util/uthash/tests/test46.ans delete mode 100644 src/util/uthash/tests/test46.c delete mode 100644 src/util/uthash/tests/test47.ans delete mode 100644 src/util/uthash/tests/test47.c delete mode 100644 src/util/uthash/tests/test48.ans delete mode 100644 src/util/uthash/tests/test48.c delete mode 100644 src/util/uthash/tests/test49.ans delete mode 100644 src/util/uthash/tests/test49.c delete mode 100644 src/util/uthash/tests/test5.ans delete mode 100644 src/util/uthash/tests/test5.c delete mode 100644 src/util/uthash/tests/test50.ans delete mode 100644 src/util/uthash/tests/test50.c delete mode 100644 src/util/uthash/tests/test51.ans delete mode 100644 src/util/uthash/tests/test51.c delete mode 100644 src/util/uthash/tests/test52.ans delete mode 100644 src/util/uthash/tests/test52.c delete mode 100644 src/util/uthash/tests/test53.ans delete mode 100644 src/util/uthash/tests/test53.c delete mode 100644 src/util/uthash/tests/test54.ans delete mode 100644 src/util/uthash/tests/test54.c delete mode 100644 src/util/uthash/tests/test55.ans delete mode 100644 src/util/uthash/tests/test55.c delete mode 100644 src/util/uthash/tests/test56.ans delete mode 100644 src/util/uthash/tests/test56.c delete mode 100644 src/util/uthash/tests/test57.ans delete mode 100644 src/util/uthash/tests/test57.c delete mode 100644 src/util/uthash/tests/test58.ans delete mode 100644 src/util/uthash/tests/test58.c delete mode 100644 src/util/uthash/tests/test59.ans delete mode 100644 src/util/uthash/tests/test59.c delete mode 100644 src/util/uthash/tests/test6.ans delete mode 100644 src/util/uthash/tests/test6.c delete mode 100644 src/util/uthash/tests/test60.ans delete mode 100644 src/util/uthash/tests/test60.c delete mode 100644 src/util/uthash/tests/test61.ans delete mode 100644 src/util/uthash/tests/test61.c delete mode 100644 src/util/uthash/tests/test62.ans delete mode 100644 src/util/uthash/tests/test62.c delete mode 100644 src/util/uthash/tests/test63.ans delete mode 100644 src/util/uthash/tests/test63.c delete mode 100644 src/util/uthash/tests/test64.ans delete mode 100644 src/util/uthash/tests/test64.c delete mode 100644 src/util/uthash/tests/test65.ans delete mode 100644 src/util/uthash/tests/test65.c delete mode 100644 src/util/uthash/tests/test65.dat delete mode 100644 src/util/uthash/tests/test66.ans delete mode 100644 src/util/uthash/tests/test66.c delete mode 100644 src/util/uthash/tests/test67.ans delete mode 100644 src/util/uthash/tests/test67.c delete mode 100644 src/util/uthash/tests/test68.ans delete mode 100644 src/util/uthash/tests/test68.c delete mode 100644 src/util/uthash/tests/test69.ans delete mode 100644 src/util/uthash/tests/test69.c delete mode 100644 src/util/uthash/tests/test7.ans delete mode 100644 src/util/uthash/tests/test7.c delete mode 100644 src/util/uthash/tests/test70.ans delete mode 100644 src/util/uthash/tests/test70.c delete mode 100644 src/util/uthash/tests/test71.ans delete mode 100644 src/util/uthash/tests/test71.c delete mode 100644 src/util/uthash/tests/test72.ans delete mode 100644 src/util/uthash/tests/test72.c delete mode 100644 src/util/uthash/tests/test73.ans delete mode 100644 src/util/uthash/tests/test73.c delete mode 100644 src/util/uthash/tests/test74.ans delete mode 100644 src/util/uthash/tests/test74.c delete mode 100644 src/util/uthash/tests/test75.ans delete mode 100644 src/util/uthash/tests/test75.c delete mode 100644 src/util/uthash/tests/test76.ans delete mode 100644 src/util/uthash/tests/test76.c delete mode 100644 src/util/uthash/tests/test77.ans delete mode 100644 src/util/uthash/tests/test77.c delete mode 100644 src/util/uthash/tests/test78.ans delete mode 100644 src/util/uthash/tests/test78.c delete mode 100644 src/util/uthash/tests/test79.ans delete mode 100644 src/util/uthash/tests/test79.c delete mode 100644 src/util/uthash/tests/test8.ans delete mode 100644 src/util/uthash/tests/test8.c delete mode 100644 src/util/uthash/tests/test80.ans delete mode 100644 src/util/uthash/tests/test80.c delete mode 100644 src/util/uthash/tests/test81.ans delete mode 100644 src/util/uthash/tests/test81.c delete mode 100644 src/util/uthash/tests/test82.ans delete mode 100644 src/util/uthash/tests/test82.c delete mode 100644 src/util/uthash/tests/test9.ans delete mode 100644 src/util/uthash/tests/test9.c delete mode 100644 src/util/uthash/tests/threads/README delete mode 100755 src/util/uthash/tests/threads/do_tests delete mode 100644 src/util/uthash/tests/threads/test1.c delete mode 100644 src/util/uthash/tests/threads/test2.c diff --git a/src/util/uthash/LICENSE b/src/util/uthash/LICENSE index ad8e16a..e75a243 100644 --- a/src/util/uthash/LICENSE +++ b/src/util/uthash/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2005-2013, Troy D. Hanson http://troydhanson.github.com/uthash/ +Copyright (c) 2005-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/util/uthash/README.md b/src/util/uthash/README.md index 3adebca..a85c10d 100644 --- a/src/util/uthash/README.md +++ b/src/util/uthash/README.md @@ -1,6 +1,8 @@ +[![Build status](https://api.travis-ci.org/troydhanson/uthash.svg?branch=master)](https://travis-ci.org/troydhanson/uthash) + Documentation for uthash is available at: -http://troydhanson.github.com/uthash/ +https://troydhanson.github.com/uthash/ diff --git a/src/util/uthash/doc/ChangeLog.html b/src/util/uthash/doc/ChangeLog.html deleted file mode 100644 index b59128d..0000000 --- a/src/util/uthash/doc/ChangeLog.html +++ /dev/null @@ -1,1504 +0,0 @@ - - - - - -uthash ChangeLog - - - - - -
-
-
-

Click to return to the uthash home page.

-
-
-
-

Version 1.9.8.p2

-
-
    -
  • -

    -added LRU cache example in tests/lru_cache (thanks, Oliver Lorenz!) -

    -
  • -
  • -

    -fix LL_DELETE2 for VS2008 (thanks, Greg Davydouski!) -

    -
  • -
-
-
-
-

Version 1.9.8.p1

-
-
    -
  • -

    -fix missing argument in HASH_REPLACE_STR (thanks, Alex!) -

    -
  • -
  • -

    -bump version number in source files to match docs (thanks, John Crow!) -

    -
  • -
  • -

    -add HASH_OVERHEAD macro to get overhead size for hash table -

    -
  • -
-
-
-
-

Version 1.9.8 (2013-03-10)

-
-
    -
  • -

    -HASH_REPLACE now in uthash (thanks, Nick Vatamaniuc!) -

    -
  • -
  • -

    -fixed clang warnings (thanks wynnw!) -

    -
  • -
  • -

    -fixed utarray_insert when inserting past array end (thanks Rob Willett!) -

    -
  • -
  • -

    -you can now find uthash on GitHub -

    -
  • -
  • -

    -there’s a uthash Google Group -

    -
  • -
  • -

    -uthash has been downloaded 29,000+ times since 2006 on SourceForge -

    -
  • -
-
-
-
-

Version 1.9.7 (2012-10-09)

-
-
    -
  • -

    -utstring now supports substring search using utstring_find (thanks, Joe Wei!) -

    -
  • -
  • -

    -utlist now supports element prepend and replace (thanks, Zoltán Lajos Kis!) -

    -
  • -
  • -

    -utlist element prev/next fields can now have any names (thanks, Pawel S. Veselov!) -

    -
  • -
  • -

    -uthash cast quiets a clang warning (thanks, Roman Divacky and Baptiste Daroussin!) -

    -
  • -
  • -

    -uthash userguide example shows how to check key uniqueness (thanks, Richard Cook!) -

    -
  • -
  • -

    -uthash HASH_MUR compiles under MSVC++ 10 in C mode (thanks, Arun Kirthi Cherian!) -

    -
  • -
  • -

    -utstring_printf now supports format checking (thanks, Donald Carr!) -

    -
  • -
-
-
-
-

Version 1.9.6 (2012-04-28)

-
-
    -
  • -

    -add utarray_prev (thanks, Ben Hiett!) -

    -
  • -
  • -

    -add parens/casts for greater compatibility (thanks, Atis, Debasis Ganguly, and Steve McClellan!) -

    -
  • -
  • -

    -added ifndef to uthash_malloc and related hooks (thanks, Holger Machens!) -

    -
  • -
  • -

    -edit examples so they do not leak memory (thanks, 任晶磊!) -

    -
  • -
-
-
-
-

Version 1.9.5 (2011-11-16)

-
-
    -
  • -

    -added utarray_renew -

    -
  • -
  • -

    -fixed memory leak in uthash_clear when using Bloom filter (thanks, Jan Hättig!) -

    -
  • -
  • -

    -utarray now copies the UT_icd on array creation rather than storing a pointer -

    -
  • -
  • -

    -add parentheses to HASH_ADD to fix preprocessing of certain arguments (thanks, Aaron Rosen!) -

    -
  • -
  • -

    -more parenthesizations for greater macro argument flexibility -

    -
  • -
-
-
-
-

Version 1.9.4 (2011-06-05)

-
-
    -
  • -

    -uthash now supports MurmurHash v3 -

    -
  • -
  • -

    -utlist now includes concatenation macros (LL_CONCAT and DL_CONCAT) -

    -
  • -
  • -

    -utarray now supports binary search (utarray_find) -

    -
  • -
  • -

    -utstring now supports a new-or-clear-existing macro (utstring_renew) -

    -
  • -
  • -

    -documented technique for a multi-level hash table -

    -
  • -
  • -

    -clarified scope requirements for UT_icd in the utarray documentation -

    -
  • -
  • -

    -fixed termination when utstring_clear is followed by utstring_body -

    -
  • -
  • -

    -fixed utarray_inserta macro when used with complex arguments -

    -
  • -
  • -

    -on Visual Studio define missing type uint8_t -

    -
  • -
  • -

    -Debian/Ubuntu include uthash in the package uthash-dev. -

    -
  • -
  • -

    -uthash has been downloaded 16,211 times. -

    -
  • -
-

Thanks to Yu Feng, Richard Cook, Dino Ciuffetti, Chris Groer, and Arun Cherian -for feedback and fixes in this release!

-
-
-
-

Version 1.9.3 (2010-10-31)

-
-
    -
  • -

    -fix an ifdef for compatibility with Intel compiler (thanks, degski!) -

    -
  • -
  • -

    -fix HASH_ITER macro to satisfy C++ casting rules (thanks, Erik Bai!) -

    -
  • -
-
-
-
-

Version 1.9.2 (2010-10-04)

-
-
    -
  • -

    -new HASH_ITER macro for more convenient deletion-safe iteration -

    -
  • -
  • -

    -hashscan can now run on FreeBSD 8.1 and later (thanks, Markus Gebert!) -

    -
  • -
  • -

    -More parens to evaluate complex macro arguments properly (thanks, ngg!) -

    -
  • -
  • -

    -Add sz parameter to the uthash_free hook for platforms that do their own memory management. Hopefully this minor API change doesn’t cause too much breakage for people. (thanks, Niall Douglas!) -

    -
  • -
  • -

    -uthash has been downloaded 12,294 times -

    -
  • -
-
-
-
-

Version 1.9.1 (2010-05-15)

-
-
    -
  • -

    -Fix a redefinition warning when using uthash.h and utstring.h together -

    -
  • -
  • -

    -Fix a bug in utstring_init -

    -
  • -
  • -

    -Added HASH_FIND_PTR and HASH_ADD_PTR (thanks, Niall Douglas!) -

    -
  • -
-
-
-
-

Version 1.9 (2010-03-31)

-
-
    -
  • -

    -uthash now supports Visual Studio 2008 and 2010 in C or C++ code! -

    -
  • -
  • -

    -new headers utarray.h and utstring.h - are now included. These implement dynamic arrays and strings using macros -

    -
  • -
  • -

    -utlist.h now has deletion-safe iterators and search macros -

    -
  • -
  • -

    -the test suite now runs under Visual Studio (thanks again degski!) -

    -
  • -
  • -

    -special thanks for suggesting utarray and utlist features to Charalampos P.! -

    -
  • -
  • -

    -uthash has been downloaded 9,616 times -

    -
  • -
-
-
-
-

Version 1.8 (2009-09-08)

-
-
    -
  • -

    -Added the hashscan utility that can report on the size and quality of - hash tables in a running process (Linux-only) -

    -
  • -
  • -

    -Added Bloom filter support. This has the potential to speed up certain - types of programs that look up non-existant keys in sufficient numbers. -

    -
  • -
  • -

    -Restored the MurmurHash, which can once again be used, if an additional - symbol is defined. This is a "safety" by which the user declares they - understand that -fno-strict-aliasing flag must be used if they are - using MurmurHash under gcc with optimization. -

    -
  • -
  • -

    -Unified the bucket/table malloc hooks; now there is only one malloc hook -

    -
  • -
  • -

    -Re-organized the manual into a main section and advanced topics section -

    -
  • -
  • -

    -Fixed a bug in utlist.h where sorting a singly-linked list threw a - compile-time error. -

    -
  • -
  • -

    -Fixed a bug in utlist.h where a doubly-linked list that is sorted - did not maintain the special head->prev pointer back to the list tail. -

    -
  • -
-
-
-
-

Version 1.7 (2009-06-11)

-
-
    -
  • -

    -The MurmurHash has been removed, and Jenkin’s hash is once again the default. - While MurmurHash performed well, it’s unsafe with regard to the strict - aliasing rule. This results in incorrect code when compiled with optimization. - It’s not possible to enable -fno-strict-aliasing from within a header file. -

    -
  • -
  • -

    -The linked list macros in utlist.h now comply with the strict-aliasing - rule so they generate correct code under high optimization levels (O2 or O3). - The use of the __typeof__ extension, which was originally a GNU extension, - may reduce portability to other compilers that do not support this extension. - This extension is used in the singly-linked list macros and the sort macros. -

    -
  • -
-
-
-
-

Version 1.6 (2009-05-08)

-
-

Special thanks to Alfred Heisner for contributing several enhancements:

-
    -
  • -

    -Support for two new hash functions: -

    -
      -
    • -

      -the Paul Hsieh hash function (HASH_SFH) -

      -
    • -
    • -

      -Austin Appleby’s MurmurHash function (HASH_MUR) -

      -
    • -
    -
  • -
  • -

    -Because of its excellent performance, MurmurHash is now the default hash function. -

    -
  • -
  • -

    -keystats now has much better elapsed time accuracy under Cygwin and MinGW -

    -
  • -
  • -

    -fixed casting in HASH_FNV, HASH_SAX and HASH_OAT for non-char keys -

    -
  • -
-

This release also includes:

-
    -
  • -

    -a new HASH_CLEAR operation clears a hash table in one step. -

    -
  • -
  • -

    -a new HASH_SELECT operation inserts those elements from one hash that - satisfy a given condition into another hash. The selected items have - dual presence in both hash tables. For example a game could select the - visible polygons from a hash of all polygons. -

    -
  • -
  • -

    -fixed a compile-time error which occurred if the final argument to - HASH_ADD_KEYPTR was a pointer to an array member like &a[i] -

    -
  • -
  • -

    -added another test script tests/all_funcs which executes the test suite - using every supported hash function -

    -
  • -
-

And lastly,

-
    -
  • -

    -a new, separate header called utlist.h is included which - provides linked list macros for C structures, similar in style to the - uthash macros -

    -
  • -
-
-
-
-

Version 1.5 (2009-02-19)

-
-
    -
  • -

    -now thread-safe for concurrent readers -

    -
  • -
  • -

    -use scratch variables on stack rather than in table (thanks, Petter Arvidsson!). - This change made HASH_FIND about 13% faster and enabled reader concurrency. -

    -
  • -
  • -

    -made BSD license terms even more permissive -

    -
  • -
  • -

    -added PDF version of User Guide -

    -
  • -
  • -

    -added update news -(RSS) - -

    -
  • -
-
-
-
-

Version 1.4 (2008-09-23)

-
-
    -
  • -

    -Add HASH_COUNT for counting items in the hash -

    -
  • -
  • -

    -Compatibility with C++. Satisfy additional casting requirements. - Also in the tests/ directory, running make cplusplus now compiles - all the test programs with the C++ compiler. -

    -
  • -
  • -

    -Eliminate elmt pointer from the UT_hash_handle. Calculate elmt - from hash handle address by subtracting hho (hash handle offset). -

    -
  • -
  • -

    -Contributed by L.S.Chin: - Cast void* to char* before pointer arithmetic to suppress compiler - warnings. We assume compilers abide to C standards which impose - requirement that sizeof(void*) == sizeof(char*). -

    -
  • -
  • -

    -Return meaningful exit status from do_tests per Tiago Cunha, - so that package manager-based install can verify tests are successful -

    -
  • -
-
-
-
-

Version 1.3 (2008-07-27)

-
-
    -
  • -

    -use integer-only math-- no floating point! Support FPU-less CPU’s. -

    -
  • -
  • -

    -eliminate hash_q metric, which measured the fraction of items with - non-ideal chain positions. We only need to know if this fraction - is below 0.5. This is now determined using fast bitwise tests. -

    -
  • -
  • -

    -when an item is added to the hash, calculate the key’s hash value - upfront and store it, instead of recomputing it as needed. This hashv - is stored in the hash handle. Potentially major speed benefit for - bucket expansion algorithm. Deleting is marginally improved too. -

    -
  • -
  • -

    -fixed a minor bug in the calculation of the max ideal chain length; - line 446 in v1.2 erroneously calculated a/b*2 instead of a/(b*2). - The effect of this bug was that bucket expansion could occur more - readily because the per-bucket max chain length multiplier factor - (which delays bucket expansion when certain buckets are overused) - was set to a lower, expansion-favoring value than intended. -

    -
  • -
  • -

    -improved source commenting and improved variable names in structures -

    -
  • -
  • -

    -remove HASH_JSW. Lengthy random number array made code less readable -

    -
  • -
  • -

    -add HASH_SRT(hh,hash,cmp) as a generalized HASH_SORT(hash,cmp). - It was an omission in uthash 1.2 that there was no sort macro for - hash handles with names other than hh. -

    -
  • -
  • -

    -Corrected HASH_FSCK so it works with any name for the hash handle. -

    -
  • -
  • -

    -behave properly in pathological HASH_DEL(a,a) case where the same - variable references the head and the deletee (advancing the head - then loses the correct reference to the deletee); fix by using - scratch area in the hash table to store deletee hash handle. -

    -
  • -
  • -

    -made tests runnable on MinGW -

    -
  • -
  • -

    -3000+ downloads since uthash-1.0 -

    -
  • -
-
-
-
-

Version 1.2 (2006-11-22)

-
-
    -
  • -

    -new HASH_SORT macro -

    -
  • -
  • -

    -Cygwin support -

    -
  • -
  • -

    -User Guide now features a clickable Table of Contents. - (The technique for generating the TOC on the browser was contributed - back to the AsciiDoc project and incorporated into AsciiDoc v8.1.0). -

    -
  • -
-
-
-
-

Version 1.1 (2006-06-28)

-
-
    -
  • -

    -uthash-1.1 released -

    -
  • -
  • -

    -supports several built-in user-selectable hash functions -

    -
  • -
  • -

    -new keystats utility quantifies performance of hash functions -

    -
  • -
-
-
-
-

Version 1.0 (2006-06-02)

-
-
    -
  • -

    -Initial release -

    -
  • -
-
-
-
-

- - - diff --git a/src/util/uthash/doc/ChangeLog.txt b/src/util/uthash/doc/ChangeLog.txt deleted file mode 100644 index 0807da8..0000000 --- a/src/util/uthash/doc/ChangeLog.txt +++ /dev/null @@ -1,230 +0,0 @@ -uthash ChangeLog -================ - -Click to return to the link:index.html[uthash home page]. - -Version 1.9.8.p2 ----------------- -* added LRU cache example in `tests/lru_cache` (thanks, Oliver Lorenz!) -* fix LL_DELETE2 for VS2008 (thanks, Greg Davydouski!) - -Version 1.9.8.p1 ----------------- -* fix missing argument in `HASH_REPLACE_STR` (thanks, Alex!) -* bump version number in source files to match docs (thanks, John Crow!) -* add `HASH_OVERHEAD` macro to get overhead size for hash table - -Version 1.9.8 (2013-03-10) --------------------------- -* `HASH_REPLACE` now in uthash (thanks, Nick Vatamaniuc!) -* fixed clang warnings (thanks wynnw!) -* fixed `utarray_insert` when inserting past array end (thanks Rob Willett!) -* you can now find http://troydhanson.github.com/uthash/[uthash on GitHub] -* there's a https://groups.google.com/d/forum/uthash[uthash Google Group] -* uthash has been downloaded 29,000+ times since 2006 on SourceForge - -Version 1.9.7 (2012-10-09) --------------------------- -* utstring now supports substring search using `utstring_find` (thanks, Joe Wei!) -* utlist now supports element 'prepend' and 'replace' (thanks, Zoltán Lajos Kis!) -* utlist element prev/next fields can now have any names (thanks, Pawel S. Veselov!) -* uthash cast quiets a clang warning (thanks, Roman Divacky and Baptiste Daroussin!) -* uthash userguide example shows how to check key uniqueness (thanks, Richard Cook!) -* uthash HASH_MUR compiles under MSVC++ 10 in C mode (thanks, Arun Kirthi Cherian!) -* `utstring_printf` now supports format checking (thanks, Donald Carr!) - -Version 1.9.6 (2012-04-28) --------------------------- -* add utarray_prev (thanks, Ben Hiett!) -* add parens/casts for greater compatibility (thanks, Atis, Debasis Ganguly, and Steve McClellan!) -* added ifndef to uthash_malloc and related hooks (thanks, Holger Machens!) -* edit examples so they do not leak memory (thanks, 任晶磊!) - -Version 1.9.5 (2011-11-16) --------------------------- -* added `utarray_renew` -* fixed memory leak in `uthash_clear` when using Bloom filter (thanks, Jan Hättig!) -* utarray now copies the UT_icd on array creation rather than storing a pointer -* add parentheses to `HASH_ADD` to fix preprocessing of certain arguments (thanks, Aaron Rosen!) -* more parenthesizations for greater macro argument flexibility - -Version 1.9.4 (2011-06-05) --------------------------- -* uthash now supports MurmurHash v3 -* utlist now includes concatenation macros (`LL_CONCAT` and `DL_CONCAT`) -* utarray now supports binary search (`utarray_find`) -* utstring now supports a new-or-clear-existing macro (`utstring_renew`) -* documented technique for a multi-level hash table -* clarified scope requirements for `UT_icd` in the utarray documentation -* fixed termination when `utstring_clear` is followed by `utstring_body` -* fixed utarray_inserta macro when used with complex arguments -* on Visual Studio define missing type `uint8_t` -* Debian/Ubuntu include uthash in the package `uthash-dev`. -* uthash has been downloaded 16,211 times. - -Thanks to Yu Feng, Richard Cook, Dino Ciuffetti, Chris Groer, and Arun Cherian -for feedback and fixes in this release! - -Version 1.9.3 (2010-10-31) --------------------------- -* fix an `ifdef` for compatibility with Intel compiler (thanks, degski!) -* fix `HASH_ITER` macro to satisfy C++ casting rules (thanks, Erik Bai!) - -Version 1.9.2 (2010-10-04) --------------------------- -* new `HASH_ITER` macro for more convenient deletion-safe iteration -* `hashscan` can now run on FreeBSD 8.1 and later (thanks, Markus Gebert!) -* More parens to evaluate complex macro arguments properly (thanks, ngg!) -* Add sz parameter to the `uthash_free` hook for platforms that do their own memory management. Hopefully this minor API change doesn't cause too much breakage for people. (thanks, Niall Douglas!) -* uthash has been downloaded 12,294 times - -Version 1.9.1 (2010-05-15) --------------------------- -* Fix a redefinition warning when using `uthash.h` and `utstring.h` together -* Fix a bug in `utstring_init` -* Added `HASH_FIND_PTR` and `HASH_ADD_PTR` (thanks, Niall Douglas!) - -Version 1.9 (2010-03-31) --------------------------- -* uthash now supports Visual Studio 2008 and 2010 in C or C++ code! -* new headers link:utarray.html[utarray.h] and link:utstring.html[utstring.h] - are now included. These implement dynamic arrays and strings using macros -* link:utlist.html[utlist.h] now has deletion-safe iterators and search macros -* the test suite now runs under Visual Studio (thanks again degski!) -* special thanks for suggesting utarray and utlist features to Charalampos P.! -* uthash has been downloaded 9,616 times - -Version 1.8 (2009-09-08) --------------------------- -* Added the `hashscan` utility that can report on the size and quality of - hash tables in a running process (Linux-only) -* Added Bloom filter support. This has the potential to speed up certain - types of programs that look up non-existant keys in sufficient numbers. -* Restored the MurmurHash, which can once again be used, if an additional - symbol is defined. This is a "safety" by which the user declares they - understand that `-fno-strict-aliasing` flag must be used if they are - using MurmurHash under gcc with optimization. -* Unified the bucket/table malloc hooks; now there is only one malloc hook -* Re-organized the manual into a main section and advanced topics section -* Fixed a bug in `utlist.h` where sorting a singly-linked list threw a - compile-time error. -* Fixed a bug in `utlist.h` where a doubly-linked list that is sorted - did not maintain the special `head->prev` pointer back to the list tail. - -Version 1.7 (2009-06-11) --------------------------- -* The MurmurHash has been removed, and Jenkin's hash is once again the default. - While MurmurHash performed well, it's unsafe with regard to the strict - aliasing rule. This results in incorrect code when compiled with optimization. - It's not possible to enable `-fno-strict-aliasing` from within a header file. -* The linked list macros in `utlist.h` now comply with the strict-aliasing - rule so they generate correct code under high optimization levels (O2 or O3). - The use of the `__typeof__` extension, which was originally a GNU extension, - may reduce portability to other compilers that do not support this extension. - This extension is used in the singly-linked list macros and the sort macros. - -Version 1.6 (2009-05-08) --------------------------- -Special thanks to Alfred Heisner for contributing several enhancements: - -* Support for two new hash functions: - - the Paul Hsieh hash function (`HASH_SFH`) - - Austin Appleby's MurmurHash function (`HASH_MUR`) -* Because of its excellent performance, MurmurHash is now the default hash function. -* `keystats` now has much better elapsed time accuracy under Cygwin and MinGW -* fixed casting in `HASH_FNV`, `HASH_SAX` and `HASH_OAT` for non-char keys - -This release also includes: - -* a new `HASH_CLEAR` operation clears a hash table in one step. -* a new `HASH_SELECT` operation inserts those elements from one hash that - satisfy a given condition into another hash. The selected items have - dual presence in both hash tables. For example a game could select the - visible polygons from a hash of all polygons. -* fixed a compile-time error which occurred if the final argument to - `HASH_ADD_KEYPTR` was a pointer to an array member like `&a[i]` -* added another test script `tests/all_funcs` which executes the test suite - using every supported hash function - -And lastly, - -* a new, separate header called link:utlist.html[utlist.h] is included which - provides 'linked list macros' for C structures, similar in style to the - uthash macros - -Version 1.5 (2009-02-19) --------------------------- -* now thread-safe for concurrent readers -* use scratch variables on stack rather than in table (thanks, Petter Arvidsson!). - This change made HASH_FIND about 13% faster and enabled reader concurrency. -* made link:license.html[BSD license] terms even more permissive -* added link:userguide.pdf[PDF version] of User Guide -* added http://troydhanson.wordpress.com/feed/[update news] image:rss.png[(RSS)] - -Version 1.4 (2008-09-23) --------------------------- -* Add `HASH_COUNT` for counting items in the hash -* Compatibility with C\+\+. Satisfy additional casting requirements. - Also in the `tests/` directory, running `make cplusplus` now compiles - all the test programs with the C++ compiler. -* Eliminate `elmt` pointer from the UT_hash_handle. Calculate elmt - from hash handle address by subtracting `hho` (hash handle offset). -* Contributed by L.S.Chin: - Cast `void*` to char* before pointer arithmetic to suppress compiler - warnings. We assume compilers abide to C standards which impose - requirement that `sizeof(void*) == sizeof(char*)`. -* Return meaningful exit status from do_tests per Tiago Cunha, - so that package manager-based install can verify tests are successful - - -Version 1.3 (2008-07-27) ------------------------- -* use integer-only math-- no floating point! Support FPU-less CPU's. -* eliminate `hash_q` metric, which measured the fraction of items with - non-ideal chain positions. We only need to know if this fraction - is below 0.5. This is now determined using fast bitwise tests. -* when an item is added to the hash, calculate the key's hash value - upfront and store it, instead of recomputing it as needed. This hashv - is stored in the hash handle. Potentially major speed benefit for - bucket expansion algorithm. Deleting is marginally improved too. -* fixed a minor bug in the calculation of the max ideal chain length; - line 446 in v1.2 erroneously calculated a/b*2 instead of a/(b*2). - The effect of this bug was that bucket expansion could occur more - readily because the per-bucket 'max chain length multiplier factor' - (which delays bucket expansion when certain buckets are overused) - was set to a lower, expansion-favoring value than intended. -* improved source commenting and improved variable names in structures -* remove `HASH_JSW`. Lengthy random number array made code less readable -* add `HASH_SRT(hh,hash,cmp)` as a generalized `HASH_SORT(hash,cmp)`. - It was an omission in uthash 1.2 that there was no sort macro for - hash handles with names other than hh. -* Corrected `HASH_FSCK` so it works with any name for the hash handle. -* behave properly in pathological `HASH_DEL(a,a)` case where the same - variable references the head and the deletee (advancing the head - then loses the correct reference to the deletee); fix by using - scratch area in the hash table to store deletee hash handle. -* made tests runnable on MinGW -* 3000+ downloads since uthash-1.0 - - -Version 1.2 (2006-11-22) ------------------------- -* new `HASH_SORT` macro -* Cygwin support -* User Guide now features a clickable Table of Contents. - (The technique for generating the TOC on the browser was contributed - back to the AsciiDoc project and incorporated into AsciiDoc v8.1.0). - - -Version 1.1 (2006-06-28) ------------------------- -* uthash-1.1 released -* supports several built-in user-selectable hash functions -* new keystats utility quantifies performance of hash functions - - -Version 1.0 (2006-06-02) ------------------------- -* Initial release - -// vim: set syntax=asciidoc: diff --git a/src/util/uthash/doc/banner.png b/src/util/uthash/doc/banner.png deleted file mode 100644 index de4f310b9fec8cfda8f394e26cc7850968e1c673..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20477 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - ut hash - - - - - - - - - - - - - - - - - - - - - - - a hash tablefor C structures - - - diff --git a/src/util/uthash/doc/google315d692c9c632ed0.html b/src/util/uthash/doc/google315d692c9c632ed0.html deleted file mode 100644 index c79038e..0000000 --- a/src/util/uthash/doc/google315d692c9c632ed0.html +++ /dev/null @@ -1 +0,0 @@ -google-site-verification: google315d692c9c632ed0.html \ No newline at end of file diff --git a/src/util/uthash/doc/index.html b/src/util/uthash/doc/index.html deleted file mode 100644 index fca79bf..0000000 --- a/src/util/uthash/doc/index.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - uthash: a hash table for C structures - - - - - -
- GitHub page > - uthash home - - - -
- -
-
- - - -
- Any C structure can be stored in a hash table using uthash. Just add a - UT_hash_handle to the structure and choose one or more fields - in your structure to act as the key. Then use these macros to store, - retrieve or delete items from the hash table. - -
-Example 1. Adding an item to a hash. -
-
-#include "uthash.h"
-
-struct my_struct {
-    int id;            /* we'll use this field as the key */
-    char name[10];             
-    UT_hash_handle hh; /* makes this structure hashable */
-};
-
-struct my_struct *users = NULL;
-
-void add_user(struct my_struct *s) {
-    HASH_ADD_INT( users, id, s );    
-}
-
-
-
-
- -
-Example 2. Looking up an item in a hash. -
-
-struct my_struct *find_user(int user_id) {
-    struct my_struct *s;
-
-    HASH_FIND_INT( users, &user_id, s );  
-    return s;
-}
-
-
-
-
- -
-Example 3. Deleting an item from a hash. -
- -
-void delete_user(struct my_struct *user) {
-    HASH_DEL( users, user);  
-}
-
-
-
-
- - For more information and examples, please see the User Guide. - -
-
- -
- - - - - - diff --git a/src/util/uthash/doc/license.html b/src/util/uthash/doc/license.html deleted file mode 100644 index c8b63c8..0000000 --- a/src/util/uthash/doc/license.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - uthash: a hash table for C structures - - - - - -
- uthash home > - BSD license -
- -
-
-
-
-Copyright (c) 2005-2013, Troy D. Hanson  http://troydhanson.github.com/uthash/
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-
- -
- - - - - - diff --git a/src/util/uthash/doc/rss.png b/src/util/uthash/doc/rss.png deleted file mode 100644 index b3c949d2244f2c0c81d65e74719af2a1b56d06a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 689 zcmV;i0#5yjP)(tky!*UETcH-TCU7SrqEjJM#?B`_A)!p7(kFf9-P@=@15kkTkGK zgFusyy#KECqZzRdBLb=P?$(kUP;>kYTDeG&{|a+iOiRbI6nbQ)j#7bOf>iF=C+|_py<&Fo1F5cC*iEM?zZGC{ejNg4LWYp=S$L6Qaby6y zp$+F`250{%tU{Lg$5*ROH}y!1UKJS4*xqd7P(Y3JQF?lrnf?yerr%&6yGXLG1ur*B z{$&R1@Oj)yl@%rY5rh?j(j10Yz_DBs`AKFU_QnB;)(aqQmGi&ieOS|21^NP9UMpa< zU&p!f6RZ6Owp^X!EXA=0SbN&h?CrQK%Q3(=YBqqHD^9ZUM0Hxt-6-KT;>lf@j?Z+v zHm(}`>85I&E<7e}oz?6UwjAogowzGO8kSN7+2`b^$Az9L{K5*ko87EV45LT-`_##3 z>d3AGh@>=mbg34|6}+-gT9N+6Dr@44VEl44O&{&|w=qpbzC#iWMKa?5)>tI+KLQK@ Xq0QFqn(9Yl00000NkvXXu0mjfZ8t - - - - -uthash User Guide - - - - - -
-
-
-

To download uthash, follow this link back to the -GitHub project page.

-
-
-
-

A hash in C

-
-

This document is written for C programmers. Since you’re reading this, chances -are that you know a hash is used for looking up items using a key. In scripting -languages, hashes or "dictionaries" are used all the time. In C, hashes don’t -exist in the language itself. This software provides a hash table for C -structures.

-
-

What can it do?

-

This software supports these operations on items in a hash table:

-
    -
  1. -

    -add/replace -

    -
  2. -
  3. -

    -find -

    -
  4. -
  5. -

    -delete -

    -
  6. -
  7. -

    -count -

    -
  8. -
  9. -

    -iterate -

    -
  10. -
  11. -

    -sort -

    -
  12. -
  13. -

    -select -

    -
  14. -
-
-
-

Is it fast?

-

Add, find and delete are normally constant-time operations. This is influenced -by your key domain and the hash function.

-

This hash aims to be minimalistic and efficient. It’s around 900 lines of C. -It inlines automatically because it’s implemented as macros. It’s fast as long -as the hash function is suited to your keys. You can use the default hash -function, or easily compare performance and choose from among several other -built-in hash functions.

-
-
-

Is it a library?

-

No, it’s just a single header file: uthash.h. All you need to do is copy -the header file into your project, and:

-
-
-
#include "uthash.h"
-
-

Since uthash is a header file only, there is no library code to link against.

-
-
-

C/C++ and platforms

-

This software can be used in C and C++ programs. It has been tested on:

-
    -
  • -

    -Linux -

    -
  • -
  • -

    -Mac OS X -

    -
  • -
  • -

    -Windows using Visual Studio 2008 and 2010 -

    -
  • -
  • -

    -Solaris -

    -
  • -
  • -

    -OpenBSD -

    -
  • -
  • -

    -FreeBSD -

    -
  • -
-

Windows users: as of 2013 it’s been a while since I had the environment to test -uthash under Visual Studio. If someone wants to run the unit tests under the latest -Visual Studio and confirm that its still clean, that’d be appreciated.

-
-

Test suite

-

To run the test suite, enter the tests directory. Then,

-
    -
  • -

    -on Unix platforms, run make -

    -
  • -
  • -

    -on Windows, run the "do_tests_win32.cmd" batch file. (You may edit the - batch file if your Visual Studio is installed in a non-standard location). -

    -
  • -
-
-
-
-

BSD licensed

-

This software is made available under the -revised BSD license. -It is free and open source.

-
-
-

Download uthash

-

Follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file.

-
-
-

Getting help

-

I encourage people to use the public Google Group to ask questions: uthash@googlegroups.com

- -

If you are experienced with uthash and like to answer questions, please join the -group and chime in when someone asks a question. That would be a great help!

-
-

Contacting the author

-

You can email me at tdh@tkhanson.net or message @troydhanson on Twitter. I -can’t always answer my email, and when I do, it’s sometimes weeks later. Sorry!

-
-
-
-

Contributing

-

If you add a new feature or fix something in uthash or in the extras, please -make a pull request on Github. For anything other than a trivial change, include -a unit test and documentation if you possibly can. (And don’t be discouraged if -it takes weeks or even months for me to merge it. Sorry, my life is busy!) Thanks!

-
-
-

Extras included

-

Three "extras" come with uthash. These provide lists, dynamic arrays and -strings:

-
    -
  • -

    -utlist.h provides linked list macros for C structures. -

    -
  • -
  • -

    -utarray.h implements dynamic arrays using macros. -

    -
  • -
  • -

    -utstring.h implements a basic dynamic string. -

    -
  • -
-

There’s also a small LRU cache API, based on uthash, in tests/lru_cache.

-
-

Other software

-

Other open-source software by the author is listed at http://tkhanson.net.

-
-
-
-

News

-

The author has a blog for software updates - -(RSS) -. You can also follow @troydhanson on Twitter for updates.

-
-
-

Who’s using it?

-

Uthash was downloaded around 30,000 times between 2006-2013 then transitioned to -GitHub. It’s been incorporated into commercial software, academic research, and -into other open-source software. It has also been added to the native package -repositories for a number of Unix-y distros.

-

When uthash was written, there were fewer options for doing generic hash tables -in C than exist today. There are faster hash tables, more memory-efficient hash -tables, with very different API’s today. But, like driving a minivan, uthash is -convenient, and gets the job done without drawing a lot of attention to itself.

-
-
-
-
-

Your structure

-
-

In uthash, a hash table is comprised of structures. Each structure represents a -key-value association. One or more of the structure fields constitute the key. -The structure pointer itself is the value.

-
-
Defining a structure that can be hashed
-
-
#include "uthash.h"
-
-struct my_struct {
-    int id;                    /* key */
-    char name[10];
-    UT_hash_handle hh;         /* makes this structure hashable */
-};
-
-

Note that, in uthash, your structure will never be moved or copied into another -location when you add it into a hash table. This means that you can keep other -data structures that safely point to your structure-- regardless of whether you -add or delete it from a hash table during your program’s lifetime.

-
-

The key

-

There are no restrictions on the data type or name of the key field. The key -can also comprise multiple contiguous fields, having any names and data types.

-
-
-
Any data type… really?
-

Yes, your key and structure can have any data type. Unlike function calls with -fixed prototypes, uthash consists of macros-- whose arguments are untyped-- and -thus able to work with any type of structure or key.

-
-
-

Unique keys

-

As with any hash, every item must have a unique key. Your application must -enforce key uniqueness. Before you add an item to the hash table, you must -first know (if in doubt, check!) that the key is not already in use. You -can check whether a key already exists in the hash table using HASH_FIND.

-
-
-
-

The hash handle

-

The UT_hash_handle field must be present in your structure. It is used for -the internal bookkeeping that makes the hash work. It does not require -initialization. It can be named anything, but you can simplify matters by -naming it hh. This allows you to use the easier "convenience" macros to add, -find and delete items.

-
-
-

A word about memory

-
-

Overhead

-

The hash handle consumes about 32 bytes per item on a 32-bit system, or 56 bytes -per item on a 64-bit system. The other overhead costs-- the buckets and the -table-- are negligible in comparison. You can use HASH_OVERHEAD to get the -overhead size, in bytes, for a hash table. See Macro Reference.

-
-
-

How clean up occurs

-

Some have asked how uthash cleans up its internal memory. The answer is simple: -when you delete the final item from a hash table, uthash releases all the -internal memory associated with that hash table, and sets its pointer to NULL.

-
-
-
-
-
-

Hash operations

-
-

This section introduces the uthash macros by example. For a more succinct -listing, see Macro Reference.

-
-
-
Convenience vs. general macros:
-

The uthash macros fall into two categories. The convenience macros can be used -with integer, pointer or string keys (and require that you chose the conventional -name hh for the UT_hash_handle field). The convenience macros take fewer -arguments than the general macros, making their usage a bit simpler for these -common types of keys.

-

The general macros can be used for any types of keys, or for multi-field keys, -or when the UT_hash_handle has been named something other than hh. These -macros take more arguments and offer greater flexibility in return. But if the -convenience macros suit your needs, use them-- your code will be more readable.

-
-
-

Declare the hash

-

Your hash must be declared as a NULL-initialized pointer to your structure.

-
-
-
struct my_struct *users = NULL;    /* important! initialize to NULL */
-
-
-
-

Add item

-

Allocate and initialize your structure as you see fit. The only aspect -of this that matters to uthash is that your key must be initialized to -a unique value. Then call HASH_ADD. (Here we use the convenience macro -HASH_ADD_INT, which offers simplified usage for keys of type int).

-
-
Add an item to a hash
-
-
void add_user(int user_id, char *name) {
-    struct my_struct *s;
-
-    s = malloc(sizeof(struct my_struct));
-    s->id = user_id;
-    strcpy(s->name, name);
-    HASH_ADD_INT( users, id, s );  /* id: name of key field */
-}
-
-

The first parameter to HASH_ADD_INT is the hash table, and the -second parameter is the name of the key field. Here, this is id. The -last parameter is a pointer to the structure being added.

-
-
-
Wait.. the field name is a parameter?
-

If you find it strange that id, which is the name of a field in the -structure, can be passed as a parameter, welcome to the world of macros. Don’t -worry- the C preprocessor expands this to valid C code.

-
-
-

Key must not be modified while in-use

-

Once a structure has been added to the hash, do not change the value of its key. -Instead, delete the item from the hash, change the key, and then re-add it.

-
-
-

Checking uniquness

-

In the example above, we didn’t check to see if user_id was already a key -of some existing item in the hash. If there’s any chance that duplicate keys -could be generated by your program, you must explicitly check the uniqueness -before adding the key to the hash. If the key is already in the hash, you can -simply modify the existing structure in the hash rather than adding the item. -It is an error to add two items with the same key to the hash table.

-

Let’s rewrite the add_user function to check whether the id is in the hash. -Only if the id is not present in the hash, do we create the item and add it. -Otherwise we just modify the structure that already exists.

-
-
-
void add_user(int user_id, char *name) {
-    struct my_struct *s;
-
-
-
-
    HASH_FIND_INT(users, &user_id, s);  /* id already in the hash? */
-    if (s==NULL) {
-      s = (struct my_struct*)malloc(sizeof(struct my_struct));
-      s->id = user_id;
-      HASH_ADD_INT( users, id, s );  /* id: name of key field */
-    }
-    strcpy(s->name, name);
-}
-
-

Why doesn’t uthash check key uniqueness for you? It saves the cost of a hash -lookup for those programs which don’t need it- for example, programs whose keys -are generated by an incrementing, non-repeating counter.

-

However, if replacement is a common operation, it is possible to use the -HASH_REPLACE macro. This macro, before adding the item, will try to find an -item with the same key and delete it first. It also returns a pointer to the -replaced item, so the user has a chance to de-allocate its memory.

-
-
-

Passing the hash pointer into functions

-

In the example above users is a global variable, but what if the caller wanted -to pass the hash pointer into the add_user function? At first glance it would -appear that you could simply pass users as an argument, but that won’t work -right.

-
-
-
/* bad */
-void add_user(struct my_struct *users, int user_id, char *name) {
-  ...
-  HASH_ADD_INT( users, id, s );
-}
-
-

You really need to pass a pointer to the hash pointer:

-
-
-
/* good */
-void add_user(struct my_struct **users, int user_id, char *name) { ...
-  ...
-  HASH_ADD_INT( *users, id, s );
-}
-
-

Note that we dereferenced the pointer in the HASH_ADD also.

-

The reason it’s necessary to deal with a pointer to the hash pointer is simple: -the hash macros modify it (in other words, they modify the pointer itself not -just what it points to).

-
-
-
-

Replace item

-

HASH_REPLACE macros are equivalent to HASH_ADD macros except they attempt -to find and delete the item first. If it find and deletes and item, it will -also return that items pointer as an output parameter.

-
-
-

Find item

-

To look up a structure in a hash, you need its key. Then call HASH_FIND. -(Here we use the convenience macro HASH_FIND_INT for keys of type int).

-
-
Find a structure using its key
-
-
struct my_struct *find_user(int user_id) {
-    struct my_struct *s;
-
-    HASH_FIND_INT( users, &user_id, s );  /* s: output pointer */
-    return s;
-}
-
-

Here, the hash table is users, and &user_id points to the key (an integer -in this case). Last, s is the output variable of HASH_FIND_INT. The -final result is that s points to the structure with the given key, or -is NULL if the key wasn’t found in the hash.

-
- - - -
-
Note
-
The middle argument is a pointer to the key. You can’t pass a literal key -value to HASH_FIND. Instead assign the literal value to a variable, and pass -a pointer to the variable.
-
-
-
-

Delete item

-

To delete a structure from a hash, you must have a pointer to it. (If you only -have the key, first do a HASH_FIND to get the structure pointer).

-
-
Delete an item from a hash
-
-
void delete_user(struct my_struct *user) {
-    HASH_DEL( users, user);  /* user: pointer to deletee */
-    free(user);              /* optional; it's up to you! */
-}
-
-

Here again, users is the hash table, and user is a pointer to the -structure we want to remove from the hash.

-
-

uthash never frees your structure

-

Deleting a structure just removes it from the hash table-- it doesn’t free -it. The choice of when to free your structure is entirely up to you; uthash -will never free your structure. For example when using HASH_REPLACE macros, -a replaced output argument is returned back, in order to make it possible for -the user to de-allocate it.

-
-
-

Delete can change the pointer

-

The hash table pointer (which initially points to the first item added to the -hash) can change in response to HASH_DEL (i.e. if you delete the first item -in the hash table).

-
-
-

Iterative deletion

-

The HASH_ITER macro is a deletion-safe iteration construct which expands -to a simple for loop.

-
-
Delete all items from a hash
-
-
void delete_all() {
-  struct my_struct *current_user, *tmp;
-
-  HASH_ITER(hh, users, current_user, tmp) {
-    HASH_DEL(users,current_user);  /* delete; users advances to next */
-    free(current_user);            /* optional- if you want to free  */
-  }
-}
-
-
-
-

All-at-once deletion

-

If you only want to delete all the items, but not free them or do any -per-element clean up, you can do this more efficiently in a single operation:

-
-
-
HASH_CLEAR(hh,users);
-
-

Afterward, the list head (here, users) will be set to NULL.

-
-
-
-

Count items

-

The number of items in the hash table can be obtained using HASH_COUNT:

-
-
Count of items in the hash table
-
-
unsigned int num_users;
-num_users = HASH_COUNT(users);
-printf("there are %u users\n", num_users);
-
-

Incidentally, this works even the list (users, here) is NULL, in -which case the count is 0.

-
-
-

Iterating and sorting

-

You can loop over the items in the hash by starting from the beginning and -following the hh.next pointer.

-
-
Iterating over all the items in a hash
-
-
void print_users() {
-    struct my_struct *s;
-
-    for(s=users; s != NULL; s=s->hh.next) {
-        printf("user id %d: name %s\n", s->id, s->name);
-    }
-}
-
-

There is also an hh.prev pointer you could use to iterate backwards through -the hash, starting from any known item.

-
-

Deletion-safe iteration

-

In the example above, it would not be safe to delete and free s in the body -of the for loop, (because s is derefenced each time the loop iterates). -This is easy to rewrite correctly (by copying the s->hh.next pointer to a -temporary variable before freeing s), but it comes up often enough that a -deletion-safe iteration macro, HASH_ITER, is included. It expands to a -for-loop header. Here is how it could be used to rewrite the last example:

-
-
-
struct my_struct *s, *tmp;
-
-
-
-
HASH_ITER(hh, users, s, tmp) {
-    printf("user id %d: name %s\n", s->id, s->name);
-    /* ... it is safe to delete and free s here */
-}
-
-
-
-
A hash is also a doubly-linked list.
-

Iterating backward and forward through the items in the hash is possible -because of the hh.prev and hh.next fields. All the items in the hash can -be reached by repeatedly following these pointers, thus the hash is also a -doubly-linked list.

-
-

If you’re using uthash in a C++ program, you need an extra cast on the for -iterator, e.g., s=(struct my_struct*)s->hh.next.

-
-
-

Sorting

-

The items in the hash are visited in "insertion order" when you follow the -hh.next pointer. You can sort the items into a new order using HASH_SORT.

-
-
-
HASH_SORT( users, name_sort );
-
-

The second argument is a pointer to a comparison function. It must accept two -pointer arguments (the items to compare), and must return an int which is -less than zero, zero, or greater than zero, if the first item sorts before, -equal to, or after the second item, respectively. (This is the same convention -used by strcmp or qsort in the standard C library).

-
-
-
int sort_function(void *a, void *b) {
-  /* compare a to b (cast a and b appropriately)
-   * return (int) -1 if (a < b)
-   * return (int)  0 if (a == b)
-   * return (int)  1 if (a > b)
-   */
-}
-
-

Below, name_sort and id_sort are two examples of sort functions.

-
-
Sorting the items in the hash
-
-
int name_sort(struct my_struct *a, struct my_struct *b) {
-    return strcmp(a->name,b->name);
-}
-
-int id_sort(struct my_struct *a, struct my_struct *b) {
-    return (a->id - b->id);
-}
-
-void sort_by_name() {
-    HASH_SORT(users, name_sort);
-}
-
-void sort_by_id() {
-    HASH_SORT(users, id_sort);
-}
-
-

When the items in the hash are sorted, the first item may change position. In -the example above, users may point to a different structure after calling -HASH_SORT.

-
-
-
-

A complete example

-

We’ll repeat all the code and embellish it with a main() function to form a -working example.

-

If this code was placed in a file called example.c in the same directory as -uthash.h, it could be compiled and run like this:

-
-
-
cc -o example example.c
-./example
-
-

Follow the prompts to try the program.

-
-
A complete program
-
-
#include <stdio.h>   /* gets */
-#include <stdlib.h>  /* atoi, malloc */
-#include <string.h>  /* strcpy */
-#include "uthash.h"
-
-struct my_struct {
-    int id;                    /* key */
-    char name[10];
-    UT_hash_handle hh;         /* makes this structure hashable */
-};
-
-struct my_struct *users = NULL;
-
-void add_user(int user_id, char *name) {
-    struct my_struct *s;
-
-    HASH_FIND_INT(users, &user_id, s);  /* id already in the hash? */
-    if (s==NULL) {
-      s = (struct my_struct*)malloc(sizeof(struct my_struct));
-      s->id = user_id;
-      HASH_ADD_INT( users, id, s );  /* id: name of key field */
-    }
-    strcpy(s->name, name);
-}
-
-struct my_struct *find_user(int user_id) {
-    struct my_struct *s;
-
-    HASH_FIND_INT( users, &user_id, s );  /* s: output pointer */
-    return s;
-}
-
-void delete_user(struct my_struct *user) {
-    HASH_DEL( users, user);  /* user: pointer to deletee */
-    free(user);
-}
-
-void delete_all() {
-  struct my_struct *current_user, *tmp;
-
-  HASH_ITER(hh, users, current_user, tmp) {
-    HASH_DEL(users,current_user);  /* delete it (users advances to next) */
-    free(current_user);            /* free it */
-  }
-}
-
-void print_users() {
-    struct my_struct *s;
-
-    for(s=users; s != NULL; s=(struct my_struct*)(s->hh.next)) {
-        printf("user id %d: name %s\n", s->id, s->name);
-    }
-}
-
-int name_sort(struct my_struct *a, struct my_struct *b) {
-    return strcmp(a->name,b->name);
-}
-
-int id_sort(struct my_struct *a, struct my_struct *b) {
-    return (a->id - b->id);
-}
-
-void sort_by_name() {
-    HASH_SORT(users, name_sort);
-}
-
-void sort_by_id() {
-    HASH_SORT(users, id_sort);
-}
-
-int main(int argc, char *argv[]) {
-    char in[10];
-    int id=1, running=1;
-    struct my_struct *s;
-    unsigned num_users;
-
-    while (running) {
-        printf(" 1. add user\n");
-        printf(" 2. add/rename user by id\n");
-        printf(" 3. find user\n");
-        printf(" 4. delete user\n");
-        printf(" 5. delete all users\n");
-        printf(" 6. sort items by name\n");
-        printf(" 7. sort items by id\n");
-        printf(" 8. print users\n");
-        printf(" 9. count users\n");
-        printf("10. quit\n");
-        gets(in);
-        switch(atoi(in)) {
-            case 1:
-                printf("name?\n");
-                add_user(id++, gets(in));
-                break;
-            case 2:
-                printf("id?\n");
-                gets(in); id = atoi(in);
-                printf("name?\n");
-                add_user(id, gets(in));
-                break;
-            case 3:
-                printf("id?\n");
-                s = find_user(atoi(gets(in)));
-                printf("user: %s\n", s ? s->name : "unknown");
-                break;
-            case 4:
-                printf("id?\n");
-                s = find_user(atoi(gets(in)));
-                if (s) delete_user(s);
-                else printf("id unknown\n");
-                break;
-            case 5:
-                delete_all();
-                break;
-            case 6:
-                sort_by_name();
-                break;
-            case 7:
-                sort_by_id();
-                break;
-            case 8:
-                print_users();
-                break;
-            case 9:
-                num_users=HASH_COUNT(users);
-                printf("there are %u users\n", num_users);
-                break;
-            case 10:
-                running=0;
-                break;
-        }
-    }
-
-    delete_all();  /* free any structures */
-    return 0;
-}
-
-

This program is included in the distribution in tests/example.c. You can run -make example in that directory to compile it easily.

-
-
-
-
-

Standard key types

-
-

This section goes into specifics of how to work with different kinds of keys. -You can use nearly any type of key-- integers, strings, pointers, structures, etc.

-
- - - -
-
Note
-
-
A note about float
-

You can use floating point keys. This comes with the same caveats as with any -program that tests floating point equality. In other words, even the tiniest -difference in two floating point numbers makes them distinct keys.

-
-
-
-

Integer keys

-

The preceding examples demonstrated use of integer keys. To recap, use the -convenience macros HASH_ADD_INT and HASH_FIND_INT for structures with -integer keys. (The other operations such as HASH_DELETE and HASH_SORT are -the same for all types of keys).

-
-
-

String keys

-

If your structure has a string key, the operations to use depend on whether your -structure points to the key (char *) or the string resides within the -structure (char a[10]). This distinction is important. As we’ll see below, -you need to use HASH_ADD_KEYPTR when your structure points to a key (that is, -the key itself is outside of the structure); in contrast, use HASH_ADD_STR -for a string key that is contained within your structure.

-
- - - -
-
Note
-
-
char[ ] vs. char*
-

The string is within the structure in the first example below-- name is a -char[10] field. In the second example, the key is outside of the -structure-- name is a char *. So the first example uses HASH_ADD_STR but -the second example uses HASH_ADD_KEYPTR. For information on this macro, see -the Macro reference.

-
-
-
-

String within structure

-
-
A string-keyed hash (string within structure)
-
-
#include <string.h>  /* strcpy */
-#include <stdlib.h>  /* malloc */
-#include <stdio.h>   /* printf */
-#include "uthash.h"
-
-struct my_struct {
-    char name[10];             /* key (string is WITHIN the structure) */
-    int id;
-    UT_hash_handle hh;         /* makes this structure hashable */
-};
-
-
-int main(int argc, char *argv[]) {
-    const char **n, *names[] = { "joe", "bob", "betty", NULL };
-    struct my_struct *s, *tmp, *users = NULL;
-    int i=0;
-
-    for (n = names; *n != NULL; n++) {
-        s = (struct my_struct*)malloc(sizeof(struct my_struct));
-        strncpy(s->name, *n,10);
-        s->id = i++;
-        HASH_ADD_STR( users, name, s );
-    }
-
-    HASH_FIND_STR( users, "betty", s);
-    if (s) printf("betty's id is %d\n", s->id);
-
-    /* free the hash table contents */
-    HASH_ITER(hh, users, s, tmp) {
-      HASH_DEL(users, s);
-      free(s);
-    }
-    return 0;
-}
-
-

This example is included in the distribution in tests/test15.c. It prints:

-
-
-
betty's id is 2
-
-
-
-

String pointer in structure

-

Now, here is the same example but using a char * key instead of char [ ]:

-
-
A string-keyed hash (structure points to string)
-
-
#include <string.h>  /* strcpy */
-#include <stdlib.h>  /* malloc */
-#include <stdio.h>   /* printf */
-#include "uthash.h"
-
-struct my_struct {
-    const char *name;          /* key */
-    int id;
-    UT_hash_handle hh;         /* makes this structure hashable */
-};
-
-
-int main(int argc, char *argv[]) {
-    const char **n, *names[] = { "joe", "bob", "betty", NULL };
-    struct my_struct *s, *tmp, *users = NULL;
-    int i=0;
-
-    for (n = names; *n != NULL; n++) {
-        s = (struct my_struct*)malloc(sizeof(struct my_struct));
-        s->name = *n;
-        s->id = i++;
-        HASH_ADD_KEYPTR( hh, users, s->name, strlen(s->name), s );
-    }
-
-    HASH_FIND_STR( users, "betty", s);
-    if (s) printf("betty's id is %d\n", s->id);
-
-    /* free the hash table contents */
-    HASH_ITER(hh, users, s, tmp) {
-      HASH_DEL(users, s);
-      free(s);
-    }
-    return 0;
-}
-
-

This example is included in tests/test40.c.

-
-
-
-

Pointer keys

-

Your key can be a pointer. To be very clear, this means the pointer itself -can be the key (in contrast, if the thing pointed to is the key, this is a -different use case handled by HASH_ADD_KEYPTR).

-

Here is a simple example where a structure has a pointer member, called key.

-
-
A pointer key
-
-
#include <stdio.h>
-#include <stdlib.h>
-#include "uthash.h"
-
-typedef struct {
-  void *key;
-  int i;
-  UT_hash_handle hh;
-} el_t;
-
-el_t *hash = NULL;
-char *someaddr = NULL;
-
-int main() {
-  el_t *d;
-  el_t *e = (el_t*)malloc(sizeof(el_t));
-  if (!e) return -1;
-  e->key = (void*)someaddr;
-  e->i = 1;
-  HASH_ADD_PTR(hash,key,e);
-  HASH_FIND_PTR(hash, &someaddr, d);
-  if (d) printf("found\n");
-
-  /* release memory */
-  HASH_DEL(hash,e);
-  free(e);
-  return 0;
-}
-
-

This example is included in tests/test57.c. Note that the end of the program -deletes the element out of the hash, (and since no more elements remain in the -hash), uthash releases its internal memory.

-
-
-

Structure keys

-

Your key field can have any data type. To uthash, it is just a sequence of -bytes. Therefore, even a nested structure can be used as a key. We’ll use the -general macros HASH_ADD and HASH_FIND to demonstrate.

-
- - - -
-
Note
-
Structures contain padding (wasted internal space used to fulfill -alignment requirements for the members of the structure). These padding bytes -must be zeroed before adding an item to the hash or looking up an item. -Therefore always zero the whole structure before setting the members of -interest. The example below does this-- see the two calls to memset.
-
-
-
A key which is a structure
-
-
#include <stdlib.h>
-#include <stdio.h>
-#include "uthash.h"
-
-typedef struct {
-  char a;
-  int b;
-} record_key_t;
-
-typedef struct {
-    record_key_t key;
-    /* ... other data ... */
-    UT_hash_handle hh;
-} record_t;
-
-int main(int argc, char *argv[]) {
-    record_t l, *p, *r, *tmp, *records = NULL;
-
-    r = (record_t*)malloc( sizeof(record_t) );
-    memset(r, 0, sizeof(record_t));
-    r->key.a = 'a';
-    r->key.b = 1;
-    HASH_ADD(hh, records, key, sizeof(record_key_t), r);
-
-    memset(&l, 0, sizeof(record_t));
-    l.key.a = 'a';
-    l.key.b = 1;
-    HASH_FIND(hh, records, &l.key, sizeof(record_key_t), p);
-
-    if (p) printf("found %c %d\n", p->key.a, p->key.b);
-
-    HASH_ITER(hh, records, p, tmp) {
-      HASH_DEL(records, p);
-      free(p);
-    }
-    return 0;
-}
-
-

This usage is nearly the same as use of a compound key explained below.

-

Note that the general macros require the name of the UT_hash_handle to be -passed as the first argument (here, this is hh). The general macros are -documented in Macro Reference.

-
-
-
-
-

Advanced Topics

-
-
-

Compound keys

-

Your key can even comprise multiple contiguous fields.

-
-
A multi-field key
-
-
#include <stdlib.h>    /* malloc       */
-#include <stddef.h>    /* offsetof     */
-#include <stdio.h>     /* printf       */
-#include <string.h>    /* memset       */
-#include "uthash.h"
-
-#define UTF32 1
-
-typedef struct {
-  UT_hash_handle hh;
-  int len;
-  char encoding;      /* these two fields */
-  int text[];         /* comprise the key */
-} msg_t;
-
-typedef struct {
-    char encoding;
-    int text[];
-} lookup_key_t;
-
-int main(int argc, char *argv[]) {
-    unsigned keylen;
-    msg_t *msg, *tmp, *msgs = NULL;
-    lookup_key_t *lookup_key;
-
-    int beijing[] = {0x5317, 0x4eac};   /* UTF-32LE for 北京 */
-
-    /* allocate and initialize our structure */
-    msg = (msg_t*)malloc( sizeof(msg_t) + sizeof(beijing) );
-    memset(msg, 0, sizeof(msg_t)+sizeof(beijing)); /* zero fill */
-    msg->len = sizeof(beijing);
-    msg->encoding = UTF32;
-    memcpy(msg->text, beijing, sizeof(beijing));
-
-    /* calculate the key length including padding, using formula */
-    keylen =   offsetof(msg_t, text)       /* offset of last key field */
-             + sizeof(beijing)             /* size of last key field */
-             - offsetof(msg_t, encoding);  /* offset of first key field */
-
-    /* add our structure to the hash table */
-    HASH_ADD( hh, msgs, encoding, keylen, msg);
-
-    /* look it up to prove that it worked :-) */
-    msg=NULL;
-
-    lookup_key = (lookup_key_t*)malloc(sizeof(*lookup_key) + sizeof(beijing));
-    memset(lookup_key, 0, sizeof(*lookup_key) + sizeof(beijing));
-    lookup_key->encoding = UTF32;
-    memcpy(lookup_key->text, beijing, sizeof(beijing));
-    HASH_FIND( hh, msgs, &lookup_key->encoding, keylen, msg );
-    if (msg) printf("found \n");
-    free(lookup_key);
-
-    HASH_ITER(hh, msgs, msg, tmp) {
-      HASH_DEL(msgs, msg);
-      free(msg);
-    }
-    return 0;
-}
-
-

This example is included in the distribution in tests/test22.c.

-

If you use multi-field keys, recognize that the compiler pads adjacent fields -(by inserting unused space between them) in order to fulfill the alignment -requirement of each field. For example a structure containing a char followed -by an int will normally have 3 "wasted" bytes of padding after the char, in -order to make the int field start on a multiple-of-4 address (4 is the length -of the int).

-
-
-
Calculating the length of a multi-field key:
-

To determine the key length when using a multi-field key, you must include any -intervening structure padding the compiler adds for alignment purposes.

-

An easy way to calculate the key length is to use the offsetof macro from -<stddef.h>. The formula is:

-
-
-
key length =   offsetof(last_key_field)
-             + sizeof(last_key_field)
-             - offsetof(first_key_field)
-
-

In the example above, the keylen variable is set using this formula.

-
-

When dealing with a multi-field key, you must zero-fill your structure before -HASH_ADD'ing it to a hash table, or using its fields in a HASH_FIND key.

-

In the previous example, memset is used to initialize the structure by -zero-filling it. This zeroes out any padding between the key fields. If we -didn’t zero-fill the structure, this padding would contain random values. The -random values would lead to HASH_FIND failures; as two "identical" keys will -appear to mismatch if there are any differences within their padding.

-
-
-

Multi-level hash tables

-

A multi-level hash table arises when each element of a hash table contains its -own secondary hash table. There can be any number of levels. In a scripting -language you might see:

-
-
-
$items{bob}{age}=37
-
-

The C program below builds this example in uthash: the hash table is called -items. It contains one element (bob) whose own hash table contains one -element (age) with value 37. No special functions are necessary to build -a multi-level hash table.

-

While this example represents both levels (bob and age) using the same -structure, it would also be fine to use two different structure definitions. -It would also be fine if there were three or more levels instead of two.

-
-
Multi-level hash table
-
-
#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "uthash.h"
-
-/* hash of hashes */
-typedef struct item {
-  char name[10];
-  struct item *sub;
-  int val;
-  UT_hash_handle hh;
-} item_t;
-
-item_t *items=NULL;
-
-int main(int argc, char *argvp[]) {
-  item_t *item1, *item2, *tmp1, *tmp2;
-
-  /* make initial element */
-  item_t *i = malloc(sizeof(*i));
-  strcpy(i->name, "bob");
-  i->sub = NULL;
-  i->val = 0;
-  HASH_ADD_STR(items, name, i);
-
-  /* add a sub hash table off this element */
-  item_t *s = malloc(sizeof(*s));
-  strcpy(s->name, "age");
-  s->sub = NULL;
-  s->val = 37;
-  HASH_ADD_STR(i->sub, name, s);
-
-  /* iterate over hash elements  */
-  HASH_ITER(hh, items, item1, tmp1) {
-    HASH_ITER(hh, item1->sub, item2, tmp2) {
-      printf("$items{%s}{%s} = %d\n", item1->name, item2->name, item2->val);
-    }
-  }
-
-  /* clean up both hash tables */
-  HASH_ITER(hh, items, item1, tmp1) {
-    HASH_ITER(hh, item1->sub, item2, tmp2) {
-      HASH_DEL(item1->sub, item2);
-      free(item2);
-    }
-    HASH_DEL(items, item1);
-    free(item1);
-  }
-
-  return 0;
-}
-
-

The example above is included in tests/test59.c.

-
-
-

Items in several hash tables

-

A structure can be added to more than one hash table. A few reasons you might do -this include:

-
    -
  • -

    -each hash table may use an alternative key; -

    -
  • -
  • -

    -each hash table may have its own sort order; -

    -
  • -
  • -

    -or you might simply use multiple hash tables for grouping purposes. E.g., - you could have users in an admin_users and a users hash table. -

    -
  • -
-

Your structure needs to have a UT_hash_handle field for each hash table to -which it might be added. You can name them anything. E.g.,

-
-
-
UT_hash_handle hh1, hh2;
-
-
-
-

Items with alternative keys

-

You might create a hash table keyed on an ID field, and another hash table keyed -on username (if usernames are unique). You can add the same user structure to -both hash tables (without duplication of the structure), allowing lookup of a -user structure by their name or ID. The way to achieve this is to have a -separate UT_hash_handle for each hash to which the structure may be added.

-
-
A structure with two alternative keys
-
-
struct my_struct {
-    int id;                    /* usual key */
-    char username[10];         /* alternative key */
-    UT_hash_handle hh1;        /* handle for first hash table */
-    UT_hash_handle hh2;        /* handle for second hash table */
-};
-
-

In the example above, the structure can now be added to two separate hash -tables. In one hash, id is its key, while in the other hash, username is -its key. (There is no requirement that the two hashes have different key -fields. They could both use the same key, such as id).

-

Notice the structure has two hash handles (hh1 and hh2). In the code -below, notice that each hash handle is used exclusively with a particular hash -table. (hh1 is always used with the users_by_id hash, while hh2 is -always used with the users_by_name hash table).

-
-
Two keys on a structure
-
-
    struct my_struct *users_by_id = NULL, *users_by_name = NULL, *s;
-    int i;
-    char *name;
-
-    s = malloc(sizeof(struct my_struct));
-    s->id = 1;
-    strcpy(s->username, "thanson");
-
-    /* add the structure to both hash tables */
-    HASH_ADD(hh1, users_by_id, id, sizeof(int), s);
-    HASH_ADD(hh2, users_by_name, username, strlen(s->username), s);
-
-    /* lookup user by ID in the "users_by_id" hash table */
-    i=1;
-    HASH_FIND(hh1, users_by_id, &i, sizeof(int), s);
-    if (s) printf("found id %d: %s\n", i, s->username);
-
-    /* lookup user by username in the "users_by_name" hash table */
-    name = "thanson";
-    HASH_FIND(hh2, users_by_name, name, strlen(name), s);
-    if (s) printf("found user %s: %d\n", name, s->id);
-
-
-
-

Several sort orders

-

It comes as no suprise that two hash tables can have different sort orders, but -this fact can also be used advantageously to sort the same items in several -ways. This is based on the ability to store a structure in several hash tables.

-

Extending the previous example, suppose we have many users. We have added each -user structure to the users_by_id hash table and the users_by_name hash table. -(To reiterate, this is done without the need to have two copies of each structure). -Now we can define two sort functions, then use HASH_SRT.

-
-
-
int sort_by_id(struct my_struct *a, struct my_struct *b) {
-  if (a->id == b->id) return 0;
-  return (a->id < b->id) ? -1 : 1;
-}
-
-
-
-
int sort_by_name(struct my_struct *a, struct my_struct *b) {
-  return strcmp(a->username,b->username);
-}
-
-
-
-
HASH_SRT(hh1, users_by_id, sort_by_id);
-HASH_SRT(hh2, users_by_name, sort_by_name);
-
-

Now iterating over the items in users_by_id will traverse them in id-order -while, naturally, iterating over users_by_name will traverse them in -name-order. The items are fully forward-and-backward linked in each order. -So even for one set of users, we might store them in two hash tables to provide -easy iteration in two different sort orders.

-
-
-

Bloom filter (faster misses)

-

Programs that generate a fair miss rate (HASH_FIND that result in NULL) may -benefit from the built-in Bloom filter support. This is disabled by default, -because programs that generate only hits would incur a slight penalty from it. -Also, programs that do deletes should not use the Bloom filter. While the -program would operate correctly, deletes diminish the benefit of the filter. -To enable the Bloom filter, simply compile with -DHASH_BLOOM=n like:

-
-
-
-DHASH_BLOOM=27
-
-

where the number can be any value up to 32 which determines the amount of memory -used by the filter, as shown below. Using more memory makes the filter more -accurate and has the potential to speed up your program by making misses bail -out faster.

-
- - --- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table 1. Bloom filter sizes for selected values of n
n Bloom filter size (per hash table)

16

8 kilobytes

20

128 kilobytes

24

2 megabytes

28

32 megabytes

32

512 megabytes

-
-

Bloom filters are only a performance feature; they do not change the results of -hash operations in any way. The only way to gauge whether or not a Bloom filter -is right for your program is to test it. Reasonable values for the size of the -Bloom filter are 16-32 bits.

-
-
-

Select

-

An experimental select operation is provided that inserts those items from a -source hash that satisfy a given condition into a destination hash. This -insertion is done with somewhat more efficiency than if this were using -HASH_ADD, namely because the hash function is not recalculated for keys of the -selected items. This operation does not remove any items from the source hash. -Rather the selected items obtain dual presence in both hashes. The destination -hash may already have items in it; the selected items are added to it. In order -for a structure to be usable with HASH_SELECT, it must have two or more hash -handles. (As described here, a structure can exist in many -hash tables at the same time; it must have a separate hash handle for each one).

-
-
-
user_t *users=NULL, *admins=NULL; /* two hash tables */
-
-
-
-
typedef struct {
-    int id;
-    UT_hash_handle hh;  /* handle for users hash */
-    UT_hash_handle ah;  /* handle for admins hash */
-} user_t;
-
-

Now suppose we have added some users, and want to select just the administrator -users who have id’s less than 1024.

-
-
-
#define is_admin(x) (((user_t*)x)->id < 1024)
-HASH_SELECT(ah,admins,hh,users,is_admin);
-
-

The first two parameters are the destination hash handle and hash table, the -second two parameters are the source hash handle and hash table, and the last -parameter is the select condition. Here we used a macro is_admin() but we -could just as well have used a function.

-
-
-
int is_admin(void *userv) {
-  user_t *user = (user_t*)userv;
-  return (user->id < 1024) ? 1 : 0;
-}
-
-

If the select condition always evaluates to true, this operation is -essentially a merge of the source hash into the destination hash. Of course, -the source hash remains unchanged under any use of HASH_SELECT. It only adds -items to the destination hash selectively.

-

The two hash handles must differ. An example of using HASH_SELECT is included -in tests/test36.c.

-
-
-

Built-in hash functions

-

Internally, a hash function transforms a key into a bucket number. You don’t -have to take any action to use the default hash function, currently Jenkin’s.

-

Some programs may benefit from using another of the built-in hash functions. -There is a simple analysis utility included with uthash to help you determine -if another hash function will give you better performance.

-

You can use a different hash function by compiling your program with --DHASH_FUNCTION=HASH_xyz where xyz is one of the symbolic names listed -below. E.g.,

-
-
-
cc -DHASH_FUNCTION=HASH_BER -o program program.c
-
-
- - --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table 2. Built-in hash functions
Symbol Name

JEN

Jenkins (default)

BER

Bernstein

SAX

Shift-Add-Xor

OAT

One-at-a-time

FNV

Fowler/Noll/Vo

SFH

Paul Hsieh

MUR

MurmurHash v3 (see note)

-
-
- - - -
-
Note
-
-
MurmurHash
-

A special symbol must be defined if you intend to use MurmurHash. To use it, add --DHASH_USING_NO_STRICT_ALIASING to your CFLAGS. And, if you are using -the gcc compiler with optimization, add -fno-strict-aliasing to your CFLAGS.

-
-
-
-

Which hash function is best?

-

You can easily determine the best hash function for your key domain. To do so, -you’ll need to run your program once in a data-collection pass, and then run -the collected data through an included analysis utility.

-

First you must build the analysis utility. From the top-level directory,

-
-
-
cd tests/
-make
-
-

We’ll use test14.c to demonstrate the data-collection and analysis steps -(here using sh syntax to redirect file descriptor 3 to a file):

-
-
Using keystats
-
-
% cc -DHASH_EMIT_KEYS=3 -I../src -o test14 test14.c
-% ./test14 3>test14.keys
-% ./keystats test14.keys
-fcn  ideal%     #items   #buckets  dup%  fl   add_usec  find_usec  del-all usec
----  ------ ---------- ---------- -----  -- ---------- ----------  ------------
-SFH   91.6%       1219        256    0%  ok         92        131            25
-FNV   90.3%       1219        512    0%  ok        107         97            31
-SAX   88.7%       1219        512    0%  ok        111        109            32
-OAT   87.2%       1219        256    0%  ok         99        138            26
-JEN   86.7%       1219        256    0%  ok         87        130            27
-BER   86.2%       1219        256    0%  ok        121        129            27
-
-
- - - -
-
Note
-
The number 3 in -DHASH_EMIT_KEYS=3 is a file descriptor. Any file descriptor -that your program doesn’t use for its own purposes can be used instead of 3. -The data-collection mode enabled by -DHASH_EMIT_KEYS=x should not be used in -production code.
-
-

Usually, you should just pick the first hash function that is listed. Here, this -is SFH. This is the function that provides the most even distribution for -your keys. If several have the same ideal%, then choose the fastest one -according to the find_usec column.

-
-
-

keystats column reference

-
-
-fcn -
-
-

- symbolic name of hash function -

-
-
-ideal% -
-
-

- The percentage of items in the hash table which can be looked up within an - ideal number of steps. (Further explained below). -

-
-
-#items -
-
-

- the number of keys that were read in from the emitted key file -

-
-
-#buckets -
-
-

- the number of buckets in the hash after all the keys were added -

-
-
-dup% -
-
-

- the percent of duplicate keys encountered in the emitted key file. - Duplicates keys are filtered out to maintain key uniqueness. (Duplicates - are normal. For example, if the application adds an item to a hash, - deletes it, then re-adds it, the key is written twice to the emitted file.) -

-
-
-flags -
-
-

- this is either ok, or nx (noexpand) if the expansion inhibited flag is - set, described in Expansion internals. It is not recommended - to use a hash function that has the noexpand flag set. -

-
-
-add_usec -
-
-

- the clock time in microseconds required to add all the keys to a hash -

-
-
-find_usec -
-
-

- the clock time in microseconds required to look up every key in the hash -

-
-
-del-all usec -
-
-

- the clock time in microseconds required to delete every item in the hash -

-
-
-
-
-

ideal%

-
-
-
What is ideal%?
-

The n items in a hash are distributed into k buckets. Ideally each bucket -would contain an equal share (n/k) of the items. In other words, the maximum -linear position of any item in a bucket chain would be n/k if every bucket is -equally used. If some buckets are overused and others are underused, the -overused buckets will contain items whose linear position surpasses n/k. -Such items are considered non-ideal.

-

As you might guess, ideal% is the percentage of ideal items in the hash. These -items have favorable linear positions in their bucket chains. As ideal% -approaches 100%, the hash table approaches constant-time lookup performance.

-
-
-
-
-

hashscan

-
- - - -
-
Note
-
This utility is only available on Linux, and on FreeBSD (8.1 and up).
-
-

A utility called hashscan is included in the tests/ directory. It -is built automatically when you run make in that directory. This tool -examines a running process and reports on the uthash tables that it finds in -that program’s memory. It can also save the keys from each table in a format -that can be fed into keystats.

-

Here is an example of using hashscan. First ensure that it is built:

-
-
-
cd tests/
-make
-
-

Since hashscan needs a running program to inspect, we’ll start up a simple -program that makes a hash table and then sleeps as our test subject:

-
-
-
./test_sleep &
-pid: 9711
-
-

Now that we have a test program, let’s run hashscan on it:

-
-
-
./hashscan 9711
-Address            ideal    items  buckets mc fl bloom/sat fcn keys saved to
------------------- ----- -------- -------- -- -- --------- --- -------------
-0x862e038            81%    10000     4096 11 ok 16    14% JEN
-
-

If we wanted to copy out all its keys for external analysis using keystats, -add the -k flag:

-
-
-
./hashscan -k 9711
-Address            ideal    items  buckets mc fl bloom/sat fcn keys saved to
------------------- ----- -------- -------- -- -- --------- --- -------------
-0x862e038            81%    10000     4096 11 ok 16    14% JEN /tmp/9711-0.key
-
-

Now we could run ./keystats /tmp/9711-0.key to analyze which hash function -has the best characteristics on this set of keys.

-
-

hashscan column reference

-
-
-Address -
-
-

- virtual address of the hash table -

-
-
-ideal -
-
-

- The percentage of items in the table which can be looked up within an ideal - number of steps. See [ideal] in the keystats section. -

-
-
-items -
-
-

- number of items in the hash table -

-
-
-buckets -
-
-

- number of buckets in the hash table -

-
-
-mc -
-
-

- the maximum chain length found in the hash table (uthash usually tries to - keep fewer than 10 items in each bucket, or in some cases a multiple of 10) -

-
-
-fl -
-
-

- flags (either ok, or NX if the expansion-inhibited flag is set) -

-
-
-bloom/sat -
-
-

- if the hash table uses a Bloom filter, this is the size (as a power of two) - of the filter (e.g. 16 means the filter is 2^16 bits in size). The second - number is the "saturation" of the bits expressed as a percentage. The lower - the percentage, the more potential benefit to identify cache misses quickly. -

-
-
-fcn -
-
-

- symbolic name of hash function -

-
-
-keys saved to -
-
-

- file to which keys were saved, if any -

-
-
-
-
-
How hashscan works
-

When hashscan runs, it attaches itself to the target process, which suspends -the target process momentarily. During this brief suspension, it scans the -target’s virtual memory for the signature of a uthash hash table. It then -checks if a valid hash table structure accompanies the signature and reports -what it finds. When it detaches, the target process resumes running normally. -The hashscan is performed "read-only"-- the target process is not modified. -Since hashscan is analyzing a momentary snapshot of a running process, it may -return different results from one run to another.

-
-
-
-
-

Expansion internals

-

Internally this hash manages the number of buckets, with the goal of having -enough buckets so that each one contains only a small number of items.

-
-
-
Why does the number of buckets matter?
-

When looking up an item by its key, this hash scans linearly through the items -in the appropriate bucket. In order for the linear scan to run in constant -time, the number of items in each bucket must be bounded. This is accomplished -by increasing the number of buckets as needed.

-
-
-

Normal expansion

-

This hash attempts to keep fewer than 10 items in each bucket. When an item is -added that would cause a bucket to exceed this number, the number of buckets in -the hash is doubled and the items are redistributed into the new buckets. In an -ideal world, each bucket will then contain half as many items as it did before.

-

Bucket expansion occurs automatically and invisibly as needed. There is -no need for the application to know when it occurs.

-
-
Per-bucket expansion threshold
-

Normally all buckets share the same threshold (10 items) at which point bucket -expansion is triggered. During the process of bucket expansion, uthash can -adjust this expansion-trigger threshold on a per-bucket basis if it sees that -certain buckets are over-utilized.

-

When this threshold is adjusted, it goes from 10 to a multiple of 10 (for that -particular bucket). The multiple is based on how many times greater the actual -chain length is than the ideal length. It is a practical measure to reduce -excess bucket expansion in the case where a hash function over-utilizes a few -buckets but has good overall distribution. However, if the overall distribution -gets too bad, uthash changes tactics.

-
-
-
-

Inhibited expansion

-

You usually don’t need to know or worry about this, particularly if you used -the keystats utility during development to select a good hash for your keys.

-

A hash function may yield an uneven distribution of items across the buckets. -In moderation this is not a problem. Normal bucket expansion takes place as -the chain lengths grow. But when significant imbalance occurs (because the hash -function is not well suited to the key domain), bucket expansion may be -ineffective at reducing the chain lengths.

-

Imagine a very bad hash function which always puts every item in bucket 0. No -matter how many times the number of buckets is doubled, the chain length of -bucket 0 stays the same. In a situation like this, the best behavior is to -stop expanding, and accept O(n) lookup performance. This is what uthash -does. It degrades gracefully if the hash function is ill-suited to the keys.

-

If two consecutive bucket expansions yield ideal% values below 50%, uthash -inhibits expansion for that hash table. Once set, the bucket expansion -inhibited flag remains in effect as long as the hash has items in it. -Inhibited expansion may cause HASH_FIND to exhibit worse than constant-time -performance.

-
-
-
-

Hooks

-

You don’t need to use these hooks- they are only here if you want to modify -the behavior of uthash. Hooks can be used to change how uthash allocates -memory, and to run code in response to certain internal events.

-
-

malloc/free

-

By default this hash implementation uses malloc and free to manage memory. -If your application uses its own custom allocator, this hash can use them too.

-
-
Specifying alternate memory management functions
-
-
#include "uthash.h"
-
-/* undefine the defaults */
-#undef uthash_malloc
-#undef uthash_free
-
-/* re-define, specifying alternate functions */
-#define uthash_malloc(sz) my_malloc(sz)
-#define uthash_free(ptr,sz) my_free(ptr)
-
-...
-
-

Notice that uthash_free receives two parameters. The sz parameter is for -convenience on embedded platforms that manage their own memory.

-
-
-

Out of memory

-

If memory allocation fails (i.e., the malloc function returned NULL), the -default behavior is to terminate the process by calling exit(-1). This can -be modified by re-defining the uthash_fatal macro.

-
-
-
#undef uthash_fatal
-#define uthash_fatal(msg) my_fatal_function(msg);
-
-

The fatal function should terminate the process or longjmp back to a safe -place. Uthash does not support "returning a failure" if memory cannot be -allocated.

-
-
-

Internal events

-

There is no need for the application to set these hooks or take action in -response to these events. They are mainly for diagnostic purposes.

-

These two hooks are "notification" hooks which get executed if uthash is -expanding buckets, or setting the bucket expansion inhibited flag. Normally -both of these hooks are undefined and thus compile away to nothing.

-
-
Expansion
-

There is a hook for the bucket expansion event.

-
-
Bucket expansion hook
-
-
#include "uthash.h"
-
-#undef uthash_expand_fyi
-#define uthash_expand_fyi(tbl) printf("expanded to %d buckets\n", tbl->num_buckets)
-
-...
-
-
-
-
Expansion-inhibition
-

This hook can be defined to code to execute in the event that uthash decides to -set the bucket expansion inhibited flag.

-
-
Bucket expansion inhibited hook
-
-
#include "uthash.h"
-
-#undef uthash_noexpand_fyi
-#define uthash_noexpand_fyi printf("warning: bucket expansion inhibited\n");
-
-...
-
-
-
-
-
-

Debug mode

-

If a program that uses this hash is compiled with -DHASH_DEBUG=1, a special -internal consistency-checking mode is activated. In this mode, the integrity -of the whole hash is checked following every add or delete operation. This is -for debugging the uthash software only, not for use in production code.

-

In the tests/ directory, running make debug will run all the tests in -this mode.

-

In this mode, any internal errors in the hash data structure will cause a -message to be printed to stderr and the program to exit.

-

The UT_hash_handle data structure includes next, prev, hh_next and -hh_prev fields. The former two fields determine the "application" ordering -(that is, insertion order-- the order the items were added). The latter two -fields determine the "bucket chain" order. These link the UT_hash_handles -together in a doubly-linked list that is a bucket chain.

-

Checks performed in -DHASH_DEBUG=1 mode:

-
    -
  • -

    -the hash is walked in its entirety twice: once in bucket order and a - second time in application order -

    -
  • -
  • -

    -the total number of items encountered in both walks is checked against the - stored number -

    -
  • -
  • -

    -during the walk in bucket order, each item’s hh_prev pointer is compared - for equality with the last visited item -

    -
  • -
  • -

    -during the walk in application order, each item’s prev pointer is compared - for equality with the last visited item -

    -
  • -
-
-
-
Macro debugging:
-

Sometimes it’s difficult to interpret a compiler warning on a line which -contains a macro call. In the case of uthash, one macro can expand to dozens of -lines. In this case, it is helpful to expand the macros and then recompile. -By doing so, the warning message will refer to the exact line within the macro.

-

Here is an example of how to expand the macros and then recompile. This uses the -test1.c program in the tests/ subdirectory.

-
-
-
gcc -E -I../src test1.c > /tmp/a.c
-egrep -v '^#' /tmp/a.c > /tmp/b.c
-indent /tmp/b.c
-gcc -o /tmp/b /tmp/b.c
-
-

The last line compiles the original program (test1.c) with all macros expanded. -If there was a warning, the referenced line number can be checked in /tmp/b.c.

-
-
-
-

Thread safety

-

You can use uthash in a threaded program. But you must do the locking. Use a -read-write lock to protect against concurrent writes. It is ok to have -concurrent readers (since uthash 1.5).

-

For example using pthreads you can create an rwlock like this:

-
-
-
pthread_rwlock_t lock;
-if (pthread_rwlock_init(&lock,NULL) != 0) fatal("can't create rwlock");
-
-

Then, readers must acquire the read lock before doing any HASH_FIND calls or -before iterating over the hash elements:

-
-
-
if (pthread_rwlock_rdlock(&lock) != 0) fatal("can't get rdlock");
-HASH_FIND_INT(elts, &i, e);
-pthread_rwlock_unlock(&lock);
-
-

Writers must acquire the exclusive write lock before doing any update. Add, -delete, and sort are all updates that must be locked.

-
-
-
if (pthread_rwlock_wrlock(&lock) != 0) fatal("can't get wrlock");
-HASH_DEL(elts, e);
-pthread_rwlock_unlock(&lock);
-
-

If you prefer, you can use a mutex instead of a read-write lock, but this will -reduce reader concurrency to a single thread at a time.

-

An example program using uthash with a read-write lock is included in -tests/threads/test1.c.

-
-
-
-
-

Macro reference

-
-
-

Convenience macros

-

The convenience macros do the same thing as the generalized macros, but -require fewer arguments.

-

In order to use the convenience macros,

-
    -
  1. -

    -the structure’s UT_hash_handle field must be named hh, and -

    -
  2. -
  3. -

    -for add or find, the key field must be of type int or char[] or pointer -

    -
  4. -
-
- - --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table 3. Convenience macros
macro arguments

HASH_ADD_INT

(head, keyfield_name, item_ptr)

HASH_REPLACE_INT

(head, keyfiled_name, item_ptr,replaced_item_ptr)

HASH_FIND_INT

(head, key_ptr, item_ptr)

HASH_ADD_STR

(head, keyfield_name, item_ptr)

HASH_REPLACE_STR

(head,keyfield_name, item_ptr, replaced_item_ptr)

HASH_FIND_STR

(head, key_ptr, item_ptr)

HASH_ADD_PTR

(head, keyfield_name, item_ptr)

HASH_REPLACE_PTR

(head, keyfield_name, item_ptr, replaced_item_ptr)

HASH_FIND_PTR

(head, key_ptr, item_ptr)

HASH_DEL

(head, item_ptr)

HASH_SORT

(head, cmp)

HASH_COUNT

(head)

-
-
-
-

General macros

-

These macros add, find, delete and sort the items in a hash. You need to -use the general macros if your UT_hash_handle is named something other -than hh, or if your key’s data type isn’t int or char[].

-
- - --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table 4. General macros
macro arguments

HASH_ADD

(hh_name, head, keyfield_name, key_len, item_ptr)

HASH_ADD_KEYPTR

(hh_name, head, key_ptr, key_len, item_ptr)

HASH_REPLACE

(hh_name, head, keyfield_name, key_len, item_ptr, replaced_item_ptr)

HASH_FIND

(hh_name, head, key_ptr, key_len, item_ptr)

HASH_DELETE

(hh_name, head, item_ptr)

HASH_SRT

(hh_name, head, cmp)

HASH_CNT

(hh_name, head)

HASH_CLEAR

(hh_name, head)

HASH_SELECT

(dst_hh_name, dst_head, src_hh_name, src_head, condition)

HASH_ITER

(hh_name, head, item_ptr, tmp_item_ptr)

HASH_OVERHEAD

(hh_name, head)

-
-
- - - -
-
Note
-
HASH_ADD_KEYPTR is used when the structure contains a pointer to the -key, rather than the key itself.
-
-
-

Argument descriptions

-
-
-hh_name -
-
-

- name of the UT_hash_handle field in the structure. Conventionally called - hh. -

-
-
-head -
-
-

- the structure pointer variable which acts as the "head" of the hash. So - named because it initially points to the first item that is added to the hash. -

-
-
-keyfield_name -
-
-

- the name of the key field in the structure. (In the case of a multi-field - key, this is the first field of the key). If you’re new to macros, it - might seem strange to pass the name of a field as a parameter. See - note. -

-
-
-key_len -
-
-

- the length of the key field in bytes. E.g. for an integer key, this is - sizeof(int), while for a string key it’s strlen(key). (For a - multi-field key, see the notes in this guide on calculating key length). -

-
-
-key_ptr -
-
-

- for HASH_FIND, this is a pointer to the key to look up in the hash - (since it’s a pointer, you can’t directly pass a literal value here). For - HASH_ADD_KEYPTR, this is the address of the key of the item being added. -

-
-
-item_ptr -
-
-

- pointer to the structure being added, deleted, or looked up, or the current - pointer during iteration. This is an input parameter for HASH_ADD and - HASH_DELETE macros, and an output parameter for HASH_FIND and - HASH_ITER. (When using HASH_ITER to iterate, tmp_item_ptr - is another variable of the same type as item_ptr, used internally). -

-
-
-replaced_item_ptr -
-
-

- used in HASH_REPLACE macros. This is an output parameter that is set to point - to the replaced item (if no item is replaced it is set to NULL). -

-
-
-cmp -
-
-

- pointer to comparison function which accepts two arguments (pointers to - items to compare) and returns an int specifying whether the first item - should sort before, equal to, or after the second item (like strcmp). -

-
-
-condition -
-
-

- a function or macro which accepts a single argument-- a void pointer to a - structure, which needs to be cast to the appropriate structure type. The - function or macro should return (or evaluate to) a non-zero value if the - structure should be "selected" for addition to the destination hash. -

-
-
-
-
-
-
-
-

- - - diff --git a/src/util/uthash/doc/userguide.txt b/src/util/uthash/doc/userguide.txt deleted file mode 100644 index 9d74f2a..0000000 --- a/src/util/uthash/doc/userguide.txt +++ /dev/null @@ -1,1793 +0,0 @@ -uthash User Guide -================= -Troy D. Hanson -v1.9.8, March 2013 - -To download uthash, follow this link back to the -https://github.com/troydhanson/uthash[GitHub project page]. - -A hash in C ------------ -This document is written for C programmers. Since you're reading this, chances -are that you know a hash is used for looking up items using a key. In scripting -languages, hashes or "dictionaries" are used all the time. In C, hashes don't -exist in the language itself. This software provides a hash table for C -structures. - -What can it do? -~~~~~~~~~~~~~~~~~ -This software supports these operations on items in a hash table: - -1. add/replace -2. find -3. delete -4. count -5. iterate -6. sort -7. select - -Is it fast? -~~~~~~~~~~~ -Add, find and delete are normally constant-time operations. This is influenced -by your key domain and the hash function. - -This hash aims to be minimalistic and efficient. It's around 900 lines of C. -It inlines automatically because it's implemented as macros. It's fast as long -as the hash function is suited to your keys. You can use the default hash -function, or easily compare performance and choose from among several other -<>. - -Is it a library? -~~~~~~~~~~~~~~~~ -No, it's just a single header file: `uthash.h`. All you need to do is copy -the header file into your project, and: - - #include "uthash.h" - -Since uthash is a header file only, there is no library code to link against. - -C/C++ and platforms -~~~~~~~~~~~~~~~~~~~ -This software can be used in C and C++ programs. It has been tested on: - - * Linux - * Mac OS X - * Windows using Visual Studio 2008 and 2010 - * Solaris - * OpenBSD - * FreeBSD - -Windows users: as of 2013 it's been a while since I had the environment to test -uthash under Visual Studio. If someone wants to run the unit tests under the latest -Visual Studio and confirm that its still clean, that'd be appreciated. - -Test suite -^^^^^^^^^^ -To run the test suite, enter the `tests` directory. Then, - - * on Unix platforms, run `make` - * on Windows, run the "do_tests_win32.cmd" batch file. (You may edit the - batch file if your Visual Studio is installed in a non-standard location). - -BSD licensed -~~~~~~~~~~~~ -This software is made available under the -link:license.html[revised BSD license]. -It is free and open source. - -Download uthash -~~~~~~~~~~~~~~~ -Follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file. - -Getting help -~~~~~~~~~~~~ -I encourage people to use the public Google Group to ask questions: mailto:uthash@googlegroups.com[] - -You can browse it at: https://groups.google.com/d/forum/uthash[] - -If you are experienced with uthash and like to answer questions, please join the -group and chime in when someone asks a question. That would be a great help! - -Contacting the author -^^^^^^^^^^^^^^^^^^^^^ -You can email me at tdh@tkhanson.net or message @troydhanson on Twitter. I -can't always answer my email, and when I do, it's sometimes weeks later. Sorry! - -Contributing -~~~~~~~~~~~~ -If you add a new feature or fix something in uthash or in the extras, please -make a pull request on Github. For anything other than a trivial change, include -a unit test and documentation if you possibly can. (And don't be discouraged if -it takes weeks or even months for me to merge it. Sorry, my life is busy!) Thanks! - -Extras included -~~~~~~~~~~~~~~~ -Three "extras" come with uthash. These provide lists, dynamic arrays and -strings: - - * link:utlist.html[utlist.h] provides linked list macros for C structures. - * link:utarray.html[utarray.h] implements dynamic arrays using macros. - * link:utstring.html[utstring.h] implements a basic dynamic string. - -There's also a small LRU cache API, based on uthash, in `tests/lru_cache`. - -Other software -^^^^^^^^^^^^^^ -Other open-source software by the author is listed at http://tkhanson.net. - -News -~~~~ -The author has a blog for http://troydhanson.wordpress.com/[software updates] -image:rss.png[(RSS)]. You can also follow @troydhanson on Twitter for updates. - -Who's using it? -~~~~~~~~~~~~~~~ -Uthash was downloaded around 30,000 times between 2006-2013 then transitioned to -GitHub. It's been incorporated into commercial software, academic research, and -into other open-source software. It has also been added to the native package -repositories for a number of Unix-y distros. - -When uthash was written, there were fewer options for doing generic hash tables -in C than exist today. There are faster hash tables, more memory-efficient hash -tables, with very different API's today. But, like driving a minivan, uthash is -convenient, and gets the job done without drawing a lot of attention to itself. - -Your structure --------------- - -In uthash, a hash table is comprised of structures. Each structure represents a -key-value association. One or more of the structure fields constitute the key. -The structure pointer itself is the value. - -.Defining a structure that can be hashed ----------------------------------------------------------------------- -#include "uthash.h" - -struct my_struct { - int id; /* key */ - char name[10]; - UT_hash_handle hh; /* makes this structure hashable */ -}; ----------------------------------------------------------------------- - -Note that, in uthash, your structure will never be moved or copied into another -location when you add it into a hash table. This means that you can keep other -data structures that safely point to your structure-- regardless of whether you -add or delete it from a hash table during your program's lifetime. - -The key -~~~~~~~ -There are no restrictions on the data type or name of the key field. The key -can also comprise multiple contiguous fields, having any names and data types. - -.Any data type... really? -***************************************************************************** -Yes, your key and structure can have any data type. Unlike function calls with -fixed prototypes, uthash consists of macros-- whose arguments are untyped-- and -thus able to work with any type of structure or key. -***************************************************************************** - -Unique keys -^^^^^^^^^^^ -As with any hash, every item must have a unique key. Your application must -enforce key uniqueness. Before you add an item to the hash table, you must -first know (if in doubt, check!) that the key is not already in use. You -can check whether a key already exists in the hash table using `HASH_FIND`. - -The hash handle -~~~~~~~~~~~~~~~ -The `UT_hash_handle` field must be present in your structure. It is used for -the internal bookkeeping that makes the hash work. It does not require -initialization. It can be named anything, but you can simplify matters by -naming it `hh`. This allows you to use the easier "convenience" macros to add, -find and delete items. - -A word about memory -~~~~~~~~~~~~~~~~~~~ - -Overhead -^^^^^^^^ -The hash handle consumes about 32 bytes per item on a 32-bit system, or 56 bytes -per item on a 64-bit system. The other overhead costs-- the buckets and the -table-- are negligible in comparison. You can use `HASH_OVERHEAD` to get the -overhead size, in bytes, for a hash table. See <>. - -How clean up occurs -^^^^^^^^^^^^^^^^^^^ -Some have asked how uthash cleans up its internal memory. The answer is simple: -'when you delete the final item' from a hash table, uthash releases all the -internal memory associated with that hash table, and sets its pointer to NULL. - - -Hash operations ---------------- - -This section introduces the uthash macros by example. For a more succinct -listing, see <>. - -.Convenience vs. general macros: -***************************************************************************** -The uthash macros fall into two categories. The 'convenience' macros can be used -with integer, pointer or string keys (and require that you chose the conventional -name `hh` for the `UT_hash_handle` field). The convenience macros take fewer -arguments than the general macros, making their usage a bit simpler for these -common types of keys. - -The 'general' macros can be used for any types of keys, or for multi-field keys, -or when the `UT_hash_handle` has been named something other than `hh`. These -macros take more arguments and offer greater flexibility in return. But if the -convenience macros suit your needs, use them-- your code will be more readable. -***************************************************************************** - -Declare the hash -~~~~~~~~~~~~~~~~ -Your hash must be declared as a `NULL`-initialized pointer to your structure. - - struct my_struct *users = NULL; /* important! initialize to NULL */ - -Add item -~~~~~~~~ -Allocate and initialize your structure as you see fit. The only aspect -of this that matters to uthash is that your key must be initialized to -a unique value. Then call `HASH_ADD`. (Here we use the convenience macro -`HASH_ADD_INT`, which offers simplified usage for keys of type `int`). - -.Add an item to a hash ----------------------------------------------------------------------- -void add_user(int user_id, char *name) { - struct my_struct *s; - - s = malloc(sizeof(struct my_struct)); - s->id = user_id; - strcpy(s->name, name); - HASH_ADD_INT( users, id, s ); /* id: name of key field */ -} ----------------------------------------------------------------------- - -The first parameter to `HASH_ADD_INT` is the hash table, and the -second parameter is the 'name' of the key field. Here, this is `id`. The -last parameter is a pointer to the structure being added. - -[[validc]] -.Wait.. the field name is a parameter? -******************************************************************************* -If you find it strange that `id`, which is the 'name of a field' in the -structure, can be passed as a parameter, welcome to the world of macros. Don't -worry- the C preprocessor expands this to valid C code. -******************************************************************************* - -Key must not be modified while in-use -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Once a structure has been added to the hash, do not change the value of its key. -Instead, delete the item from the hash, change the key, and then re-add it. - -Checking uniquness -^^^^^^^^^^^^^^^^^^ -In the example above, we didn't check to see if `user_id` was already a key -of some existing item in the hash. *If there's any chance that duplicate keys -could be generated by your program, you must explicitly check the uniqueness* -before adding the key to the hash. If the key is already in the hash, you can -simply modify the existing structure in the hash rather than adding the item. -'It is an error to add two items with the same key to the hash table'. - -Let's rewrite the `add_user` function to check whether the id is in the hash. -Only if the id is not present in the hash, do we create the item and add it. -Otherwise we just modify the structure that already exists. - - void add_user(int user_id, char *name) { - struct my_struct *s; - - HASH_FIND_INT(users, &user_id, s); /* id already in the hash? */ - if (s==NULL) { - s = (struct my_struct*)malloc(sizeof(struct my_struct)); - s->id = user_id; - HASH_ADD_INT( users, id, s ); /* id: name of key field */ - } - strcpy(s->name, name); - } - - -Why doesn't uthash check key uniqueness for you? It saves the cost of a hash -lookup for those programs which don't need it- for example, programs whose keys -are generated by an incrementing, non-repeating counter. - -However, if replacement is a common operation, it is possible to use the -`HASH_REPLACE` macro. This macro, before adding the item, will try to find an -item with the same key and delete it first. It also returns a pointer to the -replaced item, so the user has a chance to de-allocate its memory. - -Passing the hash pointer into functions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In the example above `users` is a global variable, but what if the caller wanted -to pass the hash pointer 'into' the `add_user` function? At first glance it would -appear that you could simply pass `users` as an argument, but that won't work -right. - - /* bad */ - void add_user(struct my_struct *users, int user_id, char *name) { - ... - HASH_ADD_INT( users, id, s ); - } - -You really need to pass 'a pointer' to the hash pointer: - - /* good */ - void add_user(struct my_struct **users, int user_id, char *name) { ... - ... - HASH_ADD_INT( *users, id, s ); - } - -Note that we dereferenced the pointer in the `HASH_ADD` also. - -The reason it's necessary to deal with a pointer to the hash pointer is simple: -the hash macros modify it (in other words, they modify the 'pointer itself' not -just what it points to). - - -Replace item -~~~~~~~~~~~~ -`HASH_REPLACE` macros are equivalent to HASH_ADD macros except they attempt -to find and delete the item first. If it find and deletes and item, it will -also return that items pointer as an output parameter. - - -Find item -~~~~~~~~~ -To look up a structure in a hash, you need its key. Then call `HASH_FIND`. -(Here we use the convenience macro `HASH_FIND_INT` for keys of type `int`). - -.Find a structure using its key ----------------------------------------------------------------------- -struct my_struct *find_user(int user_id) { - struct my_struct *s; - - HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */ - return s; -} ----------------------------------------------------------------------- - -Here, the hash table is `users`, and `&user_id` points to the key (an integer -in this case). Last, `s` is the 'output' variable of `HASH_FIND_INT`. The -final result is that `s` points to the structure with the given key, or -is `NULL` if the key wasn't found in the hash. - -[NOTE] -The middle argument is a 'pointer' to the key. You can't pass a literal key -value to `HASH_FIND`. Instead assign the literal value to a variable, and pass -a pointer to the variable. - - -Delete item -~~~~~~~~~~~ -To delete a structure from a hash, you must have a pointer to it. (If you only -have the key, first do a `HASH_FIND` to get the structure pointer). - -.Delete an item from a hash ----------------------------------------------------------------------- -void delete_user(struct my_struct *user) { - HASH_DEL( users, user); /* user: pointer to deletee */ - free(user); /* optional; it's up to you! */ -} ----------------------------------------------------------------------- - -Here again, `users` is the hash table, and `user` is a pointer to the -structure we want to remove from the hash. - -uthash never frees your structure -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Deleting a structure just removes it from the hash table-- it doesn't `free` -it. The choice of when to free your structure is entirely up to you; uthash -will never free your structure. For example when using `HASH_REPLACE` macros, -a replaced output argument is returned back, in order to make it possible for -the user to de-allocate it. - -Delete can change the pointer -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The hash table pointer (which initially points to the first item added to the -hash) can change in response to `HASH_DEL` (i.e. if you delete the first item -in the hash table). - -Iterative deletion -^^^^^^^^^^^^^^^^^^ -The `HASH_ITER` macro is a deletion-safe iteration construct which expands -to a simple 'for' loop. - -.Delete all items from a hash ----------------------------------------------------------------------- -void delete_all() { - struct my_struct *current_user, *tmp; - - HASH_ITER(hh, users, current_user, tmp) { - HASH_DEL(users,current_user); /* delete; users advances to next */ - free(current_user); /* optional- if you want to free */ - } -} ----------------------------------------------------------------------- - -All-at-once deletion -^^^^^^^^^^^^^^^^^^^^ -If you only want to delete all the items, but not free them or do any -per-element clean up, you can do this more efficiently in a single operation: - - HASH_CLEAR(hh,users); - -Afterward, the list head (here, `users`) will be set to `NULL`. - -Count items -~~~~~~~~~~~ - -The number of items in the hash table can be obtained using `HASH_COUNT`: - -.Count of items in the hash table ----------------------------------------------------------------------- -unsigned int num_users; -num_users = HASH_COUNT(users); -printf("there are %u users\n", num_users); ----------------------------------------------------------------------- - -Incidentally, this works even the list (`users`, here) is `NULL`, in -which case the count is 0. - -Iterating and sorting -~~~~~~~~~~~~~~~~~~~~~ - -You can loop over the items in the hash by starting from the beginning and -following the `hh.next` pointer. - -.Iterating over all the items in a hash ----------------------------------------------------------------------- -void print_users() { - struct my_struct *s; - - for(s=users; s != NULL; s=s->hh.next) { - printf("user id %d: name %s\n", s->id, s->name); - } -} ----------------------------------------------------------------------- - -There is also an `hh.prev` pointer you could use to iterate backwards through -the hash, starting from any known item. - -[[deletesafe]] -Deletion-safe iteration -^^^^^^^^^^^^^^^^^^^^^^^ -In the example above, it would not be safe to delete and free `s` in the body -of the 'for' loop, (because `s` is derefenced each time the loop iterates). -This is easy to rewrite correctly (by copying the `s->hh.next` pointer to a -temporary variable 'before' freeing `s`), but it comes up often enough that a -deletion-safe iteration macro, `HASH_ITER`, is included. It expands to a -`for`-loop header. Here is how it could be used to rewrite the last example: - - struct my_struct *s, *tmp; - - HASH_ITER(hh, users, s, tmp) { - printf("user id %d: name %s\n", s->id, s->name); - /* ... it is safe to delete and free s here */ - } - -.A hash is also a doubly-linked list. -******************************************************************************* -Iterating backward and forward through the items in the hash is possible -because of the `hh.prev` and `hh.next` fields. All the items in the hash can -be reached by repeatedly following these pointers, thus the hash is also a -doubly-linked list. -******************************************************************************* - -If you're using uthash in a C++ program, you need an extra cast on the `for` -iterator, e.g., `s=(struct my_struct*)s->hh.next`. - -Sorting -^^^^^^^ -The items in the hash are visited in "insertion order" when you follow the -`hh.next` pointer. You can sort the items into a new order using `HASH_SORT`. - - HASH_SORT( users, name_sort ); - -The second argument is a pointer to a comparison function. It must accept two -pointer arguments (the items to compare), and must return an `int` which is -less than zero, zero, or greater than zero, if the first item sorts before, -equal to, or after the second item, respectively. (This is the same convention -used by `strcmp` or `qsort` in the standard C library). - - int sort_function(void *a, void *b) { - /* compare a to b (cast a and b appropriately) - * return (int) -1 if (a < b) - * return (int) 0 if (a == b) - * return (int) 1 if (a > b) - */ - } - -Below, `name_sort` and `id_sort` are two examples of sort functions. - -.Sorting the items in the hash ----------------------------------------------------------------------- -int name_sort(struct my_struct *a, struct my_struct *b) { - return strcmp(a->name,b->name); -} - -int id_sort(struct my_struct *a, struct my_struct *b) { - return (a->id - b->id); -} - -void sort_by_name() { - HASH_SORT(users, name_sort); -} - -void sort_by_id() { - HASH_SORT(users, id_sort); -} ----------------------------------------------------------------------- - -When the items in the hash are sorted, the first item may change position. In -the example above, `users` may point to a different structure after calling -`HASH_SORT`. - -A complete example -~~~~~~~~~~~~~~~~~~ - -We'll repeat all the code and embellish it with a `main()` function to form a -working example. - -If this code was placed in a file called `example.c` in the same directory as -`uthash.h`, it could be compiled and run like this: - - cc -o example example.c - ./example - -Follow the prompts to try the program. - -.A complete program ----------------------------------------------------------------------- -#include /* gets */ -#include /* atoi, malloc */ -#include /* strcpy */ -#include "uthash.h" - -struct my_struct { - int id; /* key */ - char name[10]; - UT_hash_handle hh; /* makes this structure hashable */ -}; - -struct my_struct *users = NULL; - -void add_user(int user_id, char *name) { - struct my_struct *s; - - HASH_FIND_INT(users, &user_id, s); /* id already in the hash? */ - if (s==NULL) { - s = (struct my_struct*)malloc(sizeof(struct my_struct)); - s->id = user_id; - HASH_ADD_INT( users, id, s ); /* id: name of key field */ - } - strcpy(s->name, name); -} - -struct my_struct *find_user(int user_id) { - struct my_struct *s; - - HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */ - return s; -} - -void delete_user(struct my_struct *user) { - HASH_DEL( users, user); /* user: pointer to deletee */ - free(user); -} - -void delete_all() { - struct my_struct *current_user, *tmp; - - HASH_ITER(hh, users, current_user, tmp) { - HASH_DEL(users,current_user); /* delete it (users advances to next) */ - free(current_user); /* free it */ - } -} - -void print_users() { - struct my_struct *s; - - for(s=users; s != NULL; s=(struct my_struct*)(s->hh.next)) { - printf("user id %d: name %s\n", s->id, s->name); - } -} - -int name_sort(struct my_struct *a, struct my_struct *b) { - return strcmp(a->name,b->name); -} - -int id_sort(struct my_struct *a, struct my_struct *b) { - return (a->id - b->id); -} - -void sort_by_name() { - HASH_SORT(users, name_sort); -} - -void sort_by_id() { - HASH_SORT(users, id_sort); -} - -int main(int argc, char *argv[]) { - char in[10]; - int id=1, running=1; - struct my_struct *s; - unsigned num_users; - - while (running) { - printf(" 1. add user\n"); - printf(" 2. add/rename user by id\n"); - printf(" 3. find user\n"); - printf(" 4. delete user\n"); - printf(" 5. delete all users\n"); - printf(" 6. sort items by name\n"); - printf(" 7. sort items by id\n"); - printf(" 8. print users\n"); - printf(" 9. count users\n"); - printf("10. quit\n"); - gets(in); - switch(atoi(in)) { - case 1: - printf("name?\n"); - add_user(id++, gets(in)); - break; - case 2: - printf("id?\n"); - gets(in); id = atoi(in); - printf("name?\n"); - add_user(id, gets(in)); - break; - case 3: - printf("id?\n"); - s = find_user(atoi(gets(in))); - printf("user: %s\n", s ? s->name : "unknown"); - break; - case 4: - printf("id?\n"); - s = find_user(atoi(gets(in))); - if (s) delete_user(s); - else printf("id unknown\n"); - break; - case 5: - delete_all(); - break; - case 6: - sort_by_name(); - break; - case 7: - sort_by_id(); - break; - case 8: - print_users(); - break; - case 9: - num_users=HASH_COUNT(users); - printf("there are %u users\n", num_users); - break; - case 10: - running=0; - break; - } - } - - delete_all(); /* free any structures */ - return 0; -} ----------------------------------------------------------------------- - -This program is included in the distribution in `tests/example.c`. You can run -`make example` in that directory to compile it easily. - -Standard key types ------------------- -This section goes into specifics of how to work with different kinds of keys. -You can use nearly any type of key-- integers, strings, pointers, structures, etc. - -[NOTE] -.A note about float -================================================================================ -You can use floating point keys. This comes with the same caveats as with any -program that tests floating point equality. In other words, even the tiniest -difference in two floating point numbers makes them distinct keys. -================================================================================ - -Integer keys -~~~~~~~~~~~~ -The preceding examples demonstrated use of integer keys. To recap, use the -convenience macros `HASH_ADD_INT` and `HASH_FIND_INT` for structures with -integer keys. (The other operations such as `HASH_DELETE` and `HASH_SORT` are -the same for all types of keys). - -String keys -~~~~~~~~~~~ -If your structure has a string key, the operations to use depend on whether your -structure 'points to' the key (`char *`) or the string resides `within` the -structure (`char a[10]`). *This distinction is important*. As we'll see below, -you need to use `HASH_ADD_KEYPTR` when your structure 'points' to a key (that is, -the key itself is 'outside' of the structure); in contrast, use `HASH_ADD_STR` -for a string key that is contained *within* your structure. - -[NOTE] -.char[ ] vs. char* -================================================================================ -The string is 'within' the structure in the first example below-- `name` is a -`char[10]` field. In the second example, the key is 'outside' of the -structure-- `name` is a `char *`. So the first example uses `HASH_ADD_STR` but -the second example uses `HASH_ADD_KEYPTR`. For information on this macro, see -the <>. -================================================================================ - -String 'within' structure -^^^^^^^^^^^^^^^^^^^^^^^^^ - -.A string-keyed hash (string within structure) ----------------------------------------------------------------------- -#include /* strcpy */ -#include /* malloc */ -#include /* printf */ -#include "uthash.h" - -struct my_struct { - char name[10]; /* key (string is WITHIN the structure) */ - int id; - UT_hash_handle hh; /* makes this structure hashable */ -}; - - -int main(int argc, char *argv[]) { - const char **n, *names[] = { "joe", "bob", "betty", NULL }; - struct my_struct *s, *tmp, *users = NULL; - int i=0; - - for (n = names; *n != NULL; n++) { - s = (struct my_struct*)malloc(sizeof(struct my_struct)); - strncpy(s->name, *n,10); - s->id = i++; - HASH_ADD_STR( users, name, s ); - } - - HASH_FIND_STR( users, "betty", s); - if (s) printf("betty's id is %d\n", s->id); - - /* free the hash table contents */ - HASH_ITER(hh, users, s, tmp) { - HASH_DEL(users, s); - free(s); - } - return 0; -} ----------------------------------------------------------------------- - -This example is included in the distribution in `tests/test15.c`. It prints: - - betty's id is 2 - -String 'pointer' in structure -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Now, here is the same example but using a `char *` key instead of `char [ ]`: - -.A string-keyed hash (structure points to string) ----------------------------------------------------------------------- -#include /* strcpy */ -#include /* malloc */ -#include /* printf */ -#include "uthash.h" - -struct my_struct { - const char *name; /* key */ - int id; - UT_hash_handle hh; /* makes this structure hashable */ -}; - - -int main(int argc, char *argv[]) { - const char **n, *names[] = { "joe", "bob", "betty", NULL }; - struct my_struct *s, *tmp, *users = NULL; - int i=0; - - for (n = names; *n != NULL; n++) { - s = (struct my_struct*)malloc(sizeof(struct my_struct)); - s->name = *n; - s->id = i++; - HASH_ADD_KEYPTR( hh, users, s->name, strlen(s->name), s ); - } - - HASH_FIND_STR( users, "betty", s); - if (s) printf("betty's id is %d\n", s->id); - - /* free the hash table contents */ - HASH_ITER(hh, users, s, tmp) { - HASH_DEL(users, s); - free(s); - } - return 0; -} ----------------------------------------------------------------------- - -This example is included in `tests/test40.c`. - -Pointer keys -~~~~~~~~~~~~ -Your key can be a pointer. To be very clear, this means the 'pointer itself' -can be the key (in contrast, if the thing 'pointed to' is the key, this is a -different use case handled by `HASH_ADD_KEYPTR`). - -Here is a simple example where a structure has a pointer member, called `key`. - -.A pointer key ----------------------------------------------------------------------- -#include -#include -#include "uthash.h" - -typedef struct { - void *key; - int i; - UT_hash_handle hh; -} el_t; - -el_t *hash = NULL; -char *someaddr = NULL; - -int main() { - el_t *d; - el_t *e = (el_t*)malloc(sizeof(el_t)); - if (!e) return -1; - e->key = (void*)someaddr; - e->i = 1; - HASH_ADD_PTR(hash,key,e); - HASH_FIND_PTR(hash, &someaddr, d); - if (d) printf("found\n"); - - /* release memory */ - HASH_DEL(hash,e); - free(e); - return 0; -} ----------------------------------------------------------------------- - -This example is included in `tests/test57.c`. Note that the end of the program -deletes the element out of the hash, (and since no more elements remain in the -hash), uthash releases its internal memory. - -Structure keys -~~~~~~~~~~~~~~ -Your key field can have any data type. To uthash, it is just a sequence of -bytes. Therefore, even a nested structure can be used as a key. We'll use the -general macros `HASH_ADD` and `HASH_FIND` to demonstrate. - -NOTE: Structures contain padding (wasted internal space used to fulfill -alignment requirements for the members of the structure). These padding bytes -'must be zeroed' before adding an item to the hash or looking up an item. -Therefore always zero the whole structure before setting the members of -interest. The example below does this-- see the two calls to `memset`. - -.A key which is a structure ----------------------------------------------------------------------- -#include -#include -#include "uthash.h" - -typedef struct { - char a; - int b; -} record_key_t; - -typedef struct { - record_key_t key; - /* ... other data ... */ - UT_hash_handle hh; -} record_t; - -int main(int argc, char *argv[]) { - record_t l, *p, *r, *tmp, *records = NULL; - - r = (record_t*)malloc( sizeof(record_t) ); - memset(r, 0, sizeof(record_t)); - r->key.a = 'a'; - r->key.b = 1; - HASH_ADD(hh, records, key, sizeof(record_key_t), r); - - memset(&l, 0, sizeof(record_t)); - l.key.a = 'a'; - l.key.b = 1; - HASH_FIND(hh, records, &l.key, sizeof(record_key_t), p); - - if (p) printf("found %c %d\n", p->key.a, p->key.b); - - HASH_ITER(hh, records, p, tmp) { - HASH_DEL(records, p); - free(p); - } - return 0; -} - ----------------------------------------------------------------------- - -This usage is nearly the same as use of a compound key explained below. - -Note that the general macros require the name of the `UT_hash_handle` to be -passed as the first argument (here, this is `hh`). The general macros are -documented in <>. - -Advanced Topics ---------------- - -Compound keys -~~~~~~~~~~~~~ -Your key can even comprise multiple contiguous fields. - -.A multi-field key ----------------------------------------------------------------------- -#include /* malloc */ -#include /* offsetof */ -#include /* printf */ -#include /* memset */ -#include "uthash.h" - -#define UTF32 1 - -typedef struct { - UT_hash_handle hh; - int len; - char encoding; /* these two fields */ - int text[]; /* comprise the key */ -} msg_t; - -typedef struct { - char encoding; - int text[]; -} lookup_key_t; - -int main(int argc, char *argv[]) { - unsigned keylen; - msg_t *msg, *tmp, *msgs = NULL; - lookup_key_t *lookup_key; - - int beijing[] = {0x5317, 0x4eac}; /* UTF-32LE for 北京 */ - - /* allocate and initialize our structure */ - msg = (msg_t*)malloc( sizeof(msg_t) + sizeof(beijing) ); - memset(msg, 0, sizeof(msg_t)+sizeof(beijing)); /* zero fill */ - msg->len = sizeof(beijing); - msg->encoding = UTF32; - memcpy(msg->text, beijing, sizeof(beijing)); - - /* calculate the key length including padding, using formula */ - keylen = offsetof(msg_t, text) /* offset of last key field */ - + sizeof(beijing) /* size of last key field */ - - offsetof(msg_t, encoding); /* offset of first key field */ - - /* add our structure to the hash table */ - HASH_ADD( hh, msgs, encoding, keylen, msg); - - /* look it up to prove that it worked :-) */ - msg=NULL; - - lookup_key = (lookup_key_t*)malloc(sizeof(*lookup_key) + sizeof(beijing)); - memset(lookup_key, 0, sizeof(*lookup_key) + sizeof(beijing)); - lookup_key->encoding = UTF32; - memcpy(lookup_key->text, beijing, sizeof(beijing)); - HASH_FIND( hh, msgs, &lookup_key->encoding, keylen, msg ); - if (msg) printf("found \n"); - free(lookup_key); - - HASH_ITER(hh, msgs, msg, tmp) { - HASH_DEL(msgs, msg); - free(msg); - } - return 0; -} ----------------------------------------------------------------------- - -This example is included in the distribution in `tests/test22.c`. - -If you use multi-field keys, recognize that the compiler pads adjacent fields -(by inserting unused space between them) in order to fulfill the alignment -requirement of each field. For example a structure containing a `char` followed -by an `int` will normally have 3 "wasted" bytes of padding after the char, in -order to make the `int` field start on a multiple-of-4 address (4 is the length -of the int). - -.Calculating the length of a multi-field key: -******************************************************************************* -To determine the key length when using a multi-field key, you must include any -intervening structure padding the compiler adds for alignment purposes. - -An easy way to calculate the key length is to use the `offsetof` macro from -``. The formula is: - - key length = offsetof(last_key_field) - + sizeof(last_key_field) - - offsetof(first_key_field) - -In the example above, the `keylen` variable is set using this formula. -******************************************************************************* - -When dealing with a multi-field key, you must zero-fill your structure before -`HASH_ADD`'ing it to a hash table, or using its fields in a `HASH_FIND` key. - -In the previous example, `memset` is used to initialize the structure by -zero-filling it. This zeroes out any padding between the key fields. If we -didn't zero-fill the structure, this padding would contain random values. The -random values would lead to `HASH_FIND` failures; as two "identical" keys will -appear to mismatch if there are any differences within their padding. - -[[multilevel]] -Multi-level hash tables -~~~~~~~~~~~~~~~~~~~~~~~ -A multi-level hash table arises when each element of a hash table contains its -own secondary hash table. There can be any number of levels. In a scripting -language you might see: - - $items{bob}{age}=37 - -The C program below builds this example in uthash: the hash table is called -`items`. It contains one element (`bob`) whose own hash table contains one -element (`age`) with value 37. No special functions are necessary to build -a multi-level hash table. - -While this example represents both levels (`bob` and `age`) using the same -structure, it would also be fine to use two different structure definitions. -It would also be fine if there were three or more levels instead of two. - -.Multi-level hash table ----------------------------------------------------------------------- -#include -#include -#include -#include "uthash.h" - -/* hash of hashes */ -typedef struct item { - char name[10]; - struct item *sub; - int val; - UT_hash_handle hh; -} item_t; - -item_t *items=NULL; - -int main(int argc, char *argvp[]) { - item_t *item1, *item2, *tmp1, *tmp2; - - /* make initial element */ - item_t *i = malloc(sizeof(*i)); - strcpy(i->name, "bob"); - i->sub = NULL; - i->val = 0; - HASH_ADD_STR(items, name, i); - - /* add a sub hash table off this element */ - item_t *s = malloc(sizeof(*s)); - strcpy(s->name, "age"); - s->sub = NULL; - s->val = 37; - HASH_ADD_STR(i->sub, name, s); - - /* iterate over hash elements */ - HASH_ITER(hh, items, item1, tmp1) { - HASH_ITER(hh, item1->sub, item2, tmp2) { - printf("$items{%s}{%s} = %d\n", item1->name, item2->name, item2->val); - } - } - - /* clean up both hash tables */ - HASH_ITER(hh, items, item1, tmp1) { - HASH_ITER(hh, item1->sub, item2, tmp2) { - HASH_DEL(item1->sub, item2); - free(item2); - } - HASH_DEL(items, item1); - free(item1); - } - - return 0; -} ----------------------------------------------------------------------- -The example above is included in `tests/test59.c`. - -[[multihash]] -Items in several hash tables -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A structure can be added to more than one hash table. A few reasons you might do -this include: - -- each hash table may use an alternative key; -- each hash table may have its own sort order; -- or you might simply use multiple hash tables for grouping purposes. E.g., - you could have users in an `admin_users` and a `users` hash table. - -Your structure needs to have a `UT_hash_handle` field for each hash table to -which it might be added. You can name them anything. E.g., - - UT_hash_handle hh1, hh2; - -Items with alternative keys -~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You might create a hash table keyed on an ID field, and another hash table keyed -on username (if usernames are unique). You can add the same user structure to -both hash tables (without duplication of the structure), allowing lookup of a -user structure by their name or ID. The way to achieve this is to have a -separate `UT_hash_handle` for each hash to which the structure may be added. - -.A structure with two alternative keys ----------------------------------------------------------------------- -struct my_struct { - int id; /* usual key */ - char username[10]; /* alternative key */ - UT_hash_handle hh1; /* handle for first hash table */ - UT_hash_handle hh2; /* handle for second hash table */ -}; ----------------------------------------------------------------------- - -In the example above, the structure can now be added to two separate hash -tables. In one hash, `id` is its key, while in the other hash, `username` is -its key. (There is no requirement that the two hashes have different key -fields. They could both use the same key, such as `id`). - -Notice the structure has two hash handles (`hh1` and `hh2`). In the code -below, notice that each hash handle is used exclusively with a particular hash -table. (`hh1` is always used with the `users_by_id` hash, while `hh2` is -always used with the `users_by_name` hash table). - -.Two keys on a structure ----------------------------------------------------------------------- - struct my_struct *users_by_id = NULL, *users_by_name = NULL, *s; - int i; - char *name; - - s = malloc(sizeof(struct my_struct)); - s->id = 1; - strcpy(s->username, "thanson"); - - /* add the structure to both hash tables */ - HASH_ADD(hh1, users_by_id, id, sizeof(int), s); - HASH_ADD(hh2, users_by_name, username, strlen(s->username), s); - - /* lookup user by ID in the "users_by_id" hash table */ - i=1; - HASH_FIND(hh1, users_by_id, &i, sizeof(int), s); - if (s) printf("found id %d: %s\n", i, s->username); - - /* lookup user by username in the "users_by_name" hash table */ - name = "thanson"; - HASH_FIND(hh2, users_by_name, name, strlen(name), s); - if (s) printf("found user %s: %d\n", name, s->id); ----------------------------------------------------------------------- - - -Several sort orders -~~~~~~~~~~~~~~~~~~~ -It comes as no suprise that two hash tables can have different sort orders, but -this fact can also be used advantageously to sort the 'same items' in several -ways. This is based on the ability to store a structure in several hash tables. - -Extending the previous example, suppose we have many users. We have added each -user structure to the `users_by_id` hash table and the `users_by_name` hash table. -(To reiterate, this is done without the need to have two copies of each structure). -Now we can define two sort functions, then use `HASH_SRT`. - - int sort_by_id(struct my_struct *a, struct my_struct *b) { - if (a->id == b->id) return 0; - return (a->id < b->id) ? -1 : 1; - } - - int sort_by_name(struct my_struct *a, struct my_struct *b) { - return strcmp(a->username,b->username); - } - - HASH_SRT(hh1, users_by_id, sort_by_id); - HASH_SRT(hh2, users_by_name, sort_by_name); - -Now iterating over the items in `users_by_id` will traverse them in id-order -while, naturally, iterating over `users_by_name` will traverse them in -name-order. The items are fully forward-and-backward linked in each order. -So even for one set of users, we might store them in two hash tables to provide -easy iteration in two different sort orders. - -Bloom filter (faster misses) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Programs that generate a fair miss rate (`HASH_FIND` that result in `NULL`) may -benefit from the built-in Bloom filter support. This is disabled by default, -because programs that generate only hits would incur a slight penalty from it. -Also, programs that do deletes should not use the Bloom filter. While the -program would operate correctly, deletes diminish the benefit of the filter. -To enable the Bloom filter, simply compile with `-DHASH_BLOOM=n` like: - - -DHASH_BLOOM=27 - -where the number can be any value up to 32 which determines the amount of memory -used by the filter, as shown below. Using more memory makes the filter more -accurate and has the potential to speed up your program by making misses bail -out faster. - -.Bloom filter sizes for selected values of n -[width="50%",cols="10m,30",grid="none",options="header"] -|===================================================================== -| n | Bloom filter size (per hash table) -| 16 | 8 kilobytes -| 20 | 128 kilobytes -| 24 | 2 megabytes -| 28 | 32 megabytes -| 32 | 512 megabytes -|===================================================================== - -Bloom filters are only a performance feature; they do not change the results of -hash operations in any way. The only way to gauge whether or not a Bloom filter -is right for your program is to test it. Reasonable values for the size of the -Bloom filter are 16-32 bits. - -Select -~~~~~~ -An experimental 'select' operation is provided that inserts those items from a -source hash that satisfy a given condition into a destination hash. This -insertion is done with somewhat more efficiency than if this were using -`HASH_ADD`, namely because the hash function is not recalculated for keys of the -selected items. This operation does not remove any items from the source hash. -Rather the selected items obtain dual presence in both hashes. The destination -hash may already have items in it; the selected items are added to it. In order -for a structure to be usable with `HASH_SELECT`, it must have two or more hash -handles. (As described <>, a structure can exist in many -hash tables at the same time; it must have a separate hash handle for each one). - - user_t *users=NULL, *admins=NULL; /* two hash tables */ - - typedef struct { - int id; - UT_hash_handle hh; /* handle for users hash */ - UT_hash_handle ah; /* handle for admins hash */ - } user_t; - -Now suppose we have added some users, and want to select just the administrator -users who have id's less than 1024. - - #define is_admin(x) (((user_t*)x)->id < 1024) - HASH_SELECT(ah,admins,hh,users,is_admin); - -The first two parameters are the 'destination' hash handle and hash table, the -second two parameters are the 'source' hash handle and hash table, and the last -parameter is the 'select condition'. Here we used a macro `is_admin()` but we -could just as well have used a function. - - int is_admin(void *userv) { - user_t *user = (user_t*)userv; - return (user->id < 1024) ? 1 : 0; - } - -If the select condition always evaluates to true, this operation is -essentially a 'merge' of the source hash into the destination hash. Of course, -the source hash remains unchanged under any use of `HASH_SELECT`. It only adds -items to the destination hash selectively. - -The two hash handles must differ. An example of using `HASH_SELECT` is included -in `tests/test36.c`. - - -[[hash_functions]] -Built-in hash functions -~~~~~~~~~~~~~~~~~~~~~~~ -Internally, a hash function transforms a key into a bucket number. You don't -have to take any action to use the default hash function, currently Jenkin's. - -Some programs may benefit from using another of the built-in hash functions. -There is a simple analysis utility included with uthash to help you determine -if another hash function will give you better performance. - -You can use a different hash function by compiling your program with -`-DHASH_FUNCTION=HASH_xyz` where `xyz` is one of the symbolic names listed -below. E.g., - - cc -DHASH_FUNCTION=HASH_BER -o program program.c - -.Built-in hash functions -[width="50%",cols="^5m,20",grid="none",options="header"] -|=============================================================================== -|Symbol | Name -|JEN | Jenkins (default) -|BER | Bernstein -|SAX | Shift-Add-Xor -|OAT | One-at-a-time -|FNV | Fowler/Noll/Vo -|SFH | Paul Hsieh -|MUR | MurmurHash v3 (see note) -|=============================================================================== - -[NOTE] -.MurmurHash -================================================================================ -A special symbol must be defined if you intend to use MurmurHash. To use it, add -`-DHASH_USING_NO_STRICT_ALIASING` to your `CFLAGS`. And, if you are using -the gcc compiler with optimization, add `-fno-strict-aliasing` to your `CFLAGS`. -================================================================================ - -Which hash function is best? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You can easily determine the best hash function for your key domain. To do so, -you'll need to run your program once in a data-collection pass, and then run -the collected data through an included analysis utility. - -First you must build the analysis utility. From the top-level directory, - - cd tests/ - make - -We'll use `test14.c` to demonstrate the data-collection and analysis steps -(here using `sh` syntax to redirect file descriptor 3 to a file): - -.Using keystats --------------------------------------------------------------------------------- -% cc -DHASH_EMIT_KEYS=3 -I../src -o test14 test14.c -% ./test14 3>test14.keys -% ./keystats test14.keys -fcn ideal% #items #buckets dup% fl add_usec find_usec del-all usec ---- ------ ---------- ---------- ----- -- ---------- ---------- ------------ -SFH 91.6% 1219 256 0% ok 92 131 25 -FNV 90.3% 1219 512 0% ok 107 97 31 -SAX 88.7% 1219 512 0% ok 111 109 32 -OAT 87.2% 1219 256 0% ok 99 138 26 -JEN 86.7% 1219 256 0% ok 87 130 27 -BER 86.2% 1219 256 0% ok 121 129 27 --------------------------------------------------------------------------------- - -[NOTE] -The number 3 in `-DHASH_EMIT_KEYS=3` is a file descriptor. Any file descriptor -that your program doesn't use for its own purposes can be used instead of 3. -The data-collection mode enabled by `-DHASH_EMIT_KEYS=x` should not be used in -production code. - -Usually, you should just pick the first hash function that is listed. Here, this -is `SFH`. This is the function that provides the most even distribution for -your keys. If several have the same `ideal%`, then choose the fastest one -according to the `find_usec` column. - -keystats column reference -^^^^^^^^^^^^^^^^^^^^^^^^^ -fcn:: - symbolic name of hash function -ideal%:: - The percentage of items in the hash table which can be looked up within an - ideal number of steps. (Further explained below). -#items:: - the number of keys that were read in from the emitted key file -#buckets:: - the number of buckets in the hash after all the keys were added -dup%:: - the percent of duplicate keys encountered in the emitted key file. - Duplicates keys are filtered out to maintain key uniqueness. (Duplicates - are normal. For example, if the application adds an item to a hash, - deletes it, then re-adds it, the key is written twice to the emitted file.) -flags:: - this is either `ok`, or `nx` (noexpand) if the expansion inhibited flag is - set, described in <>. It is not recommended - to use a hash function that has the `noexpand` flag set. -add_usec:: - the clock time in microseconds required to add all the keys to a hash -find_usec:: - the clock time in microseconds required to look up every key in the hash -del-all usec:: - the clock time in microseconds required to delete every item in the hash - -[[ideal]] -ideal% -^^^^^^ - -.What is ideal%? -***************************************************************************** -The 'n' items in a hash are distributed into 'k' buckets. Ideally each bucket -would contain an equal share '(n/k)' of the items. In other words, the maximum -linear position of any item in a bucket chain would be 'n/k' if every bucket is -equally used. If some buckets are overused and others are underused, the -overused buckets will contain items whose linear position surpasses 'n/k'. -Such items are considered non-ideal. - -As you might guess, `ideal%` is the percentage of ideal items in the hash. These -items have favorable linear positions in their bucket chains. As `ideal%` -approaches 100%, the hash table approaches constant-time lookup performance. -***************************************************************************** - -[[hashscan]] -hashscan -~~~~~~~~ -NOTE: This utility is only available on Linux, and on FreeBSD (8.1 and up). - -A utility called `hashscan` is included in the `tests/` directory. It -is built automatically when you run `make` in that directory. This tool -examines a running process and reports on the uthash tables that it finds in -that program's memory. It can also save the keys from each table in a format -that can be fed into `keystats`. - -Here is an example of using `hashscan`. First ensure that it is built: - - cd tests/ - make - -Since `hashscan` needs a running program to inspect, we'll start up a simple -program that makes a hash table and then sleeps as our test subject: - - ./test_sleep & - pid: 9711 - -Now that we have a test program, let's run `hashscan` on it: - - ./hashscan 9711 - Address ideal items buckets mc fl bloom/sat fcn keys saved to - ------------------ ----- -------- -------- -- -- --------- --- ------------- - 0x862e038 81% 10000 4096 11 ok 16 14% JEN - -If we wanted to copy out all its keys for external analysis using `keystats`, -add the `-k` flag: - - ./hashscan -k 9711 - Address ideal items buckets mc fl bloom/sat fcn keys saved to - ------------------ ----- -------- -------- -- -- --------- --- ------------- - 0x862e038 81% 10000 4096 11 ok 16 14% JEN /tmp/9711-0.key - -Now we could run `./keystats /tmp/9711-0.key` to analyze which hash function -has the best characteristics on this set of keys. - -hashscan column reference -^^^^^^^^^^^^^^^^^^^^^^^^^ -Address:: - virtual address of the hash table -ideal:: - The percentage of items in the table which can be looked up within an ideal - number of steps. See <> in the `keystats` section. -items:: - number of items in the hash table -buckets:: - number of buckets in the hash table -mc:: - the maximum chain length found in the hash table (uthash usually tries to - keep fewer than 10 items in each bucket, or in some cases a multiple of 10) -fl:: - flags (either `ok`, or `NX` if the expansion-inhibited flag is set) -bloom/sat:: - if the hash table uses a Bloom filter, this is the size (as a power of two) - of the filter (e.g. 16 means the filter is 2^16 bits in size). The second - number is the "saturation" of the bits expressed as a percentage. The lower - the percentage, the more potential benefit to identify cache misses quickly. -fcn:: - symbolic name of hash function -keys saved to:: - file to which keys were saved, if any - -.How hashscan works -***************************************************************************** -When hashscan runs, it attaches itself to the target process, which suspends -the target process momentarily. During this brief suspension, it scans the -target's virtual memory for the signature of a uthash hash table. It then -checks if a valid hash table structure accompanies the signature and reports -what it finds. When it detaches, the target process resumes running normally. -The hashscan is performed "read-only"-- the target process is not modified. -Since hashscan is analyzing a momentary snapshot of a running process, it may -return different results from one run to another. -***************************************************************************** - -[[expansion]] -Expansion internals -~~~~~~~~~~~~~~~~~~~ -Internally this hash manages the number of buckets, with the goal of having -enough buckets so that each one contains only a small number of items. - -.Why does the number of buckets matter? -******************************************************************************** -When looking up an item by its key, this hash scans linearly through the items -in the appropriate bucket. In order for the linear scan to run in constant -time, the number of items in each bucket must be bounded. This is accomplished -by increasing the number of buckets as needed. -******************************************************************************** - -Normal expansion -^^^^^^^^^^^^^^^^ -This hash attempts to keep fewer than 10 items in each bucket. When an item is -added that would cause a bucket to exceed this number, the number of buckets in -the hash is doubled and the items are redistributed into the new buckets. In an -ideal world, each bucket will then contain half as many items as it did before. - -Bucket expansion occurs automatically and invisibly as needed. There is -no need for the application to know when it occurs. - -Per-bucket expansion threshold -++++++++++++++++++++++++++++++ -Normally all buckets share the same threshold (10 items) at which point bucket -expansion is triggered. During the process of bucket expansion, uthash can -adjust this expansion-trigger threshold on a per-bucket basis if it sees that -certain buckets are over-utilized. - -When this threshold is adjusted, it goes from 10 to a multiple of 10 (for that -particular bucket). The multiple is based on how many times greater the actual -chain length is than the ideal length. It is a practical measure to reduce -excess bucket expansion in the case where a hash function over-utilizes a few -buckets but has good overall distribution. However, if the overall distribution -gets too bad, uthash changes tactics. - -Inhibited expansion -^^^^^^^^^^^^^^^^^^^ -You usually don't need to know or worry about this, particularly if you used -the `keystats` utility during development to select a good hash for your keys. - -A hash function may yield an uneven distribution of items across the buckets. -In moderation this is not a problem. Normal bucket expansion takes place as -the chain lengths grow. But when significant imbalance occurs (because the hash -function is not well suited to the key domain), bucket expansion may be -ineffective at reducing the chain lengths. - -Imagine a very bad hash function which always puts every item in bucket 0. No -matter how many times the number of buckets is doubled, the chain length of -bucket 0 stays the same. In a situation like this, the best behavior is to -stop expanding, and accept O(n) lookup performance. This is what uthash -does. It degrades gracefully if the hash function is ill-suited to the keys. - -If two consecutive bucket expansions yield `ideal%` values below 50%, uthash -inhibits expansion for that hash table. Once set, the 'bucket expansion -inhibited' flag remains in effect as long as the hash has items in it. -Inhibited expansion may cause `HASH_FIND` to exhibit worse than constant-time -performance. - -Hooks -~~~~~ -You don't need to use these hooks- they are only here if you want to modify -the behavior of uthash. Hooks can be used to change how uthash allocates -memory, and to run code in response to certain internal events. - -malloc/free -^^^^^^^^^^^ -By default this hash implementation uses `malloc` and `free` to manage memory. -If your application uses its own custom allocator, this hash can use them too. - -.Specifying alternate memory management functions ----------------------------------------------------------------------------- -#include "uthash.h" - -/* undefine the defaults */ -#undef uthash_malloc -#undef uthash_free - -/* re-define, specifying alternate functions */ -#define uthash_malloc(sz) my_malloc(sz) -#define uthash_free(ptr,sz) my_free(ptr) - -... ----------------------------------------------------------------------------- - -Notice that `uthash_free` receives two parameters. The `sz` parameter is for -convenience on embedded platforms that manage their own memory. - -Out of memory -^^^^^^^^^^^^^ -If memory allocation fails (i.e., the malloc function returned `NULL`), the -default behavior is to terminate the process by calling `exit(-1)`. This can -be modified by re-defining the `uthash_fatal` macro. - - #undef uthash_fatal - #define uthash_fatal(msg) my_fatal_function(msg); - -The fatal function should terminate the process or `longjmp` back to a safe -place. Uthash does not support "returning a failure" if memory cannot be -allocated. - -Internal events -^^^^^^^^^^^^^^^ -There is no need for the application to set these hooks or take action in -response to these events. They are mainly for diagnostic purposes. - -These two hooks are "notification" hooks which get executed if uthash is -expanding buckets, or setting the 'bucket expansion inhibited' flag. Normally -both of these hooks are undefined and thus compile away to nothing. - -Expansion -+++++++++ -There is a hook for the bucket expansion event. - -.Bucket expansion hook ----------------------------------------------------------------------------- -#include "uthash.h" - -#undef uthash_expand_fyi -#define uthash_expand_fyi(tbl) printf("expanded to %d buckets\n", tbl->num_buckets) - -... ----------------------------------------------------------------------------- - -Expansion-inhibition -++++++++++++++++++++ -This hook can be defined to code to execute in the event that uthash decides to -set the 'bucket expansion inhibited' flag. - -.Bucket expansion inhibited hook ----------------------------------------------------------------------------- -#include "uthash.h" - -#undef uthash_noexpand_fyi -#define uthash_noexpand_fyi printf("warning: bucket expansion inhibited\n"); - -... ----------------------------------------------------------------------------- - - -Debug mode -~~~~~~~~~~ -If a program that uses this hash is compiled with `-DHASH_DEBUG=1`, a special -internal consistency-checking mode is activated. In this mode, the integrity -of the whole hash is checked following every add or delete operation. This is -for debugging the uthash software only, not for use in production code. - -In the `tests/` directory, running `make debug` will run all the tests in -this mode. - -In this mode, any internal errors in the hash data structure will cause a -message to be printed to `stderr` and the program to exit. - -The `UT_hash_handle` data structure includes `next`, `prev`, `hh_next` and -`hh_prev` fields. The former two fields determine the "application" ordering -(that is, insertion order-- the order the items were added). The latter two -fields determine the "bucket chain" order. These link the `UT_hash_handles` -together in a doubly-linked list that is a bucket chain. - -Checks performed in `-DHASH_DEBUG=1` mode: - -- the hash is walked in its entirety twice: once in 'bucket' order and a - second time in 'application' order -- the total number of items encountered in both walks is checked against the - stored number -- during the walk in 'bucket' order, each item's `hh_prev` pointer is compared - for equality with the last visited item -- during the walk in 'application' order, each item's `prev` pointer is compared - for equality with the last visited item - -.Macro debugging: -******************************************************************************** -Sometimes it's difficult to interpret a compiler warning on a line which -contains a macro call. In the case of uthash, one macro can expand to dozens of -lines. In this case, it is helpful to expand the macros and then recompile. -By doing so, the warning message will refer to the exact line within the macro. - -Here is an example of how to expand the macros and then recompile. This uses the -`test1.c` program in the `tests/` subdirectory. - - gcc -E -I../src test1.c > /tmp/a.c - egrep -v '^#' /tmp/a.c > /tmp/b.c - indent /tmp/b.c - gcc -o /tmp/b /tmp/b.c - -The last line compiles the original program (test1.c) with all macros expanded. -If there was a warning, the referenced line number can be checked in `/tmp/b.c`. -******************************************************************************** - -Thread safety -~~~~~~~~~~~~~ -You can use uthash in a threaded program. But you must do the locking. Use a -read-write lock to protect against concurrent writes. It is ok to have -concurrent readers (since uthash 1.5). - -For example using pthreads you can create an rwlock like this: - - pthread_rwlock_t lock; - if (pthread_rwlock_init(&lock,NULL) != 0) fatal("can't create rwlock"); - -Then, readers must acquire the read lock before doing any `HASH_FIND` calls or -before iterating over the hash elements: - - if (pthread_rwlock_rdlock(&lock) != 0) fatal("can't get rdlock"); - HASH_FIND_INT(elts, &i, e); - pthread_rwlock_unlock(&lock); - -Writers must acquire the exclusive write lock before doing any update. Add, -delete, and sort are all updates that must be locked. - - if (pthread_rwlock_wrlock(&lock) != 0) fatal("can't get wrlock"); - HASH_DEL(elts, e); - pthread_rwlock_unlock(&lock); - -If you prefer, you can use a mutex instead of a read-write lock, but this will -reduce reader concurrency to a single thread at a time. - -An example program using uthash with a read-write lock is included in -`tests/threads/test1.c`. - -[[Macro_reference]] -Macro reference ---------------- - -Convenience macros -~~~~~~~~~~~~~~~~~~ -The convenience macros do the same thing as the generalized macros, but -require fewer arguments. - -In order to use the convenience macros, - -1. the structure's `UT_hash_handle` field must be named `hh`, and -2. for add or find, the key field must be of type `int` or `char[]` or pointer - -.Convenience macros -[width="90%",cols="10m,30m",grid="none",options="header"] -|=============================================================================== -|macro | arguments -|HASH_ADD_INT | (head, keyfield_name, item_ptr) -|HASH_REPLACE_INT | (head, keyfiled_name, item_ptr,replaced_item_ptr) -|HASH_FIND_INT | (head, key_ptr, item_ptr) -|HASH_ADD_STR | (head, keyfield_name, item_ptr) -|HASH_REPLACE_STR | (head,keyfield_name, item_ptr, replaced_item_ptr) -|HASH_FIND_STR | (head, key_ptr, item_ptr) -|HASH_ADD_PTR | (head, keyfield_name, item_ptr) -|HASH_REPLACE_PTR | (head, keyfield_name, item_ptr, replaced_item_ptr) -|HASH_FIND_PTR | (head, key_ptr, item_ptr) -|HASH_DEL | (head, item_ptr) -|HASH_SORT | (head, cmp) -|HASH_COUNT | (head) -|=============================================================================== - -General macros -~~~~~~~~~~~~~~ - -These macros add, find, delete and sort the items in a hash. You need to -use the general macros if your `UT_hash_handle` is named something other -than `hh`, or if your key's data type isn't `int` or `char[]`. - -.General macros -[width="90%",cols="10m,30m",grid="none",options="header"] -|=============================================================================== -|macro | arguments -|HASH_ADD | (hh_name, head, keyfield_name, key_len, item_ptr) -|HASH_ADD_KEYPTR| (hh_name, head, key_ptr, key_len, item_ptr) -|HASH_REPLACE | (hh_name, head, keyfield_name, key_len, item_ptr, replaced_item_ptr) -|HASH_FIND | (hh_name, head, key_ptr, key_len, item_ptr) -|HASH_DELETE | (hh_name, head, item_ptr) -|HASH_SRT | (hh_name, head, cmp) -|HASH_CNT | (hh_name, head) -|HASH_CLEAR | (hh_name, head) -|HASH_SELECT | (dst_hh_name, dst_head, src_hh_name, src_head, condition) -|HASH_ITER | (hh_name, head, item_ptr, tmp_item_ptr) -|HASH_OVERHEAD | (hh_name, head) -|=============================================================================== - -[NOTE] -`HASH_ADD_KEYPTR` is used when the structure contains a pointer to the -key, rather than the key itself. - - -Argument descriptions -^^^^^^^^^^^^^^^^^^^^^ -hh_name:: - name of the `UT_hash_handle` field in the structure. Conventionally called - `hh`. -head:: - the structure pointer variable which acts as the "head" of the hash. So - named because it initially points to the first item that is added to the hash. -keyfield_name:: - the name of the key field in the structure. (In the case of a multi-field - key, this is the first field of the key). If you're new to macros, it - might seem strange to pass the name of a field as a parameter. See - <>. -key_len:: - the length of the key field in bytes. E.g. for an integer key, this is - `sizeof(int)`, while for a string key it's `strlen(key)`. (For a - multi-field key, see the notes in this guide on calculating key length). -key_ptr:: - for `HASH_FIND`, this is a pointer to the key to look up in the hash - (since it's a pointer, you can't directly pass a literal value here). For - `HASH_ADD_KEYPTR`, this is the address of the key of the item being added. -item_ptr:: - pointer to the structure being added, deleted, or looked up, or the current - pointer during iteration. This is an input parameter for `HASH_ADD` and - `HASH_DELETE` macros, and an output parameter for `HASH_FIND` and - `HASH_ITER`. (When using `HASH_ITER` to iterate, `tmp_item_ptr` - is another variable of the same type as `item_ptr`, used internally). -replaced_item_ptr:: - used in HASH_REPLACE macros. This is an output parameter that is set to point - to the replaced item (if no item is replaced it is set to NULL). -cmp:: - pointer to comparison function which accepts two arguments (pointers to - items to compare) and returns an int specifying whether the first item - should sort before, equal to, or after the second item (like `strcmp`). -condition:: - a function or macro which accepts a single argument-- a void pointer to a - structure, which needs to be cast to the appropriate structure type. The - function or macro should return (or evaluate to) a non-zero value if the - structure should be "selected" for addition to the destination hash. - -// vim: set tw=80 wm=2 syntax=asciidoc: - diff --git a/src/util/uthash/doc/utarray.html b/src/util/uthash/doc/utarray.html deleted file mode 100644 index 5b46176..0000000 --- a/src/util/uthash/doc/utarray.html +++ /dev/null @@ -1,1265 +0,0 @@ - - - - - -utarray: dynamic array macros for C - - - - - -
-
-
-

Here’s a link back to the GitHub project page.

-
-
-
-

Introduction

-
-

A set of general-purpose dynamic array macros for C structures are included with -uthash in utarray.h. To use these macros in your own C program, just -copy utarray.h into your source directory and use it in your programs.

-
-
-
#include "utarray.h"
-
-

The dynamic array supports basic operations such as push, pop, and erase on the -array elements. These array elements can be any simple datatype or structure. -The array operations are based loosely on the C++ STL vector methods.

-

Internally the dynamic array contains a contiguous memory region into which -the elements are copied. This buffer is grown as needed using realloc to -accomodate all the data that is pushed into it.

-
-

Download

-

To download the utarray.h header file, -follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file, -then look in the src/ sub-directory.

-
-
-

BSD licensed

-

This software is made available under the -revised BSD license. -It is free and open source.

-
-
-

Platforms

-

The utarray macros have been tested on:

-
    -
  • -

    -Linux, -

    -
  • -
  • -

    -Mac OS X, -

    -
  • -
  • -

    -Windows, using Visual Studio 2008 and Visual Studio 2010 -

    -
  • -
-
-
-
-
-

Usage

-
-
-

Declaration

-

The array itself has the data type UT_array, regardless of the type of -elements to be stored in it. It is declared like,

-
-
-
UT_array *nums;
-
-
-
-

New and free

-

The next step is to create the array using utarray_new. Later when you’re -done with the array, utarray_free will free it and all its elements.

-
-
-

Push, pop, etc

-

The central features of the utarray involve putting elements into it, taking -them out, and iterating over them. There are several operations -to pick from that deal with either single elements or ranges of elements at a -time. In the examples below we will use only the push operation to insert -elements.

-
-
-
-
-

Elements

-
-

Support for dynamic arrays of integers or strings is especially easy. These are -best shown by example:

-
-

Integers

-

This example makes a utarray of integers, pushes 0-9 into it, then prints it. -Lastly it frees it.

-
-
Integer elements
-
-
#include <stdio.h>
-#include "utarray.h"
-
-int main() {
-  UT_array *nums;
-  int i, *p;
-
-  utarray_new(nums,&ut_int_icd);
-  for(i=0; i < 10; i++) utarray_push_back(nums,&i);
-
-  for(p=(int*)utarray_front(nums);
-      p!=NULL;
-      p=(int*)utarray_next(nums,p)) {
-    printf("%d\n",*p);
-  }
-
-  utarray_free(nums);
-
-  return 0;
-}
-
-

The second argument to utarray_push_back is always a pointer to the type -(so a literal cannot be used). So for integers, it is an int*.

-
-
-

Strings

-

In this example we make a utarray of strings, push two strings into it, print -it and free it.

-
-
String elements
-
-
#include <stdio.h>
-#include "utarray.h"
-
-int main() {
-  UT_array *strs;
-  char *s, **p;
-
-  utarray_new(strs,&ut_str_icd);
-
-  s = "hello"; utarray_push_back(strs, &s);
-  s = "world"; utarray_push_back(strs, &s);
-  p = NULL;
-  while ( (p=(char**)utarray_next(strs,p))) {
-    printf("%s\n",*p);
-  }
-
-  utarray_free(strs);
-
-  return 0;
-}
-
-

In this example, since the element is a char*, we pass a pointer to it -(char**) as the second argument to utarray_push_back. Note that "push" makes -a copy of the source string and pushes that copy into the array.

-
-
-

About UT_icd

-

Arrays be made of any type of element, not just integers and strings. The -elements can be basic types or structures. Unless you’re dealing with integers -and strings (which use pre-defined ut_int_icd and ut_str_icd), you’ll need -to define a UT_icd helper structure. This structure contains everything that -utarray needs to initialize, copy or destruct elements.

-
-
-
typedef struct {
-    size_t sz;
-    init_f *init;
-    ctor_f *copy;
-    dtor_f *dtor;
-} UT_icd;
-
-

The three function pointers init, copy, and dtor have these prototypes:

-
-
-
typedef void (ctor_f)(void *dst, const void *src);
-typedef void (dtor_f)(void *elt);
-typedef void (init_f)(void *elt);
-
-

The sz is just the size of the element being stored in the array.

-

The init function will be invoked whenever utarray needs to initialize an -empty element. This only happens as a byproduct of utarray_resize or -utarray_extend_back. If init is NULL, it defaults to zero filling the -new element using memset.

-

The copy function is used whenever an element is copied into the array. -It is invoked during utarray_push_back, utarray_insert, utarray_inserta, -or utarray_concat. If copy is NULL, it defaults to a bitwise copy using -memcpy.

-

The dtor function is used to clean up an element that is being removed from -the array. It may be invoked due to utarray_resize, utarray_pop_back, -utarray_erase, utarray_clear, utarray_done or utarray_free. If the -elements need no cleanup upon destruction, dtor may be NULL.

-
-
-

Scalar types

-

The next example uses UT_icd with all its defaults to make a utarray of -long elements. This example pushes two longs, prints them, and frees the -array.

-
-
long elements
-
-
#include <stdio.h>
-#include "utarray.h"
-
-UT_icd long_icd = {sizeof(long), NULL, NULL, NULL };
-
-int main() {
-  UT_array *nums;
-  long l, *p;
-  utarray_new(nums, &long_icd);
-
-  l=1; utarray_push_back(nums, &l);
-  l=2; utarray_push_back(nums, &l);
-
-  p=NULL;
-  while( (p=(long*)utarray_next(nums,p))) printf("%ld\n", *p);
-
-  utarray_free(nums);
-  return 0;
-}
-
-
-
-

Structures

-

Structures can be used as utarray elements. If the structure requires no -special effort to initialize, copy or destruct, we can use UT_icd with all -its defaults. This example shows a structure that consists of two integers. Here -we push two values, print them and free the array.

-
-
Structure (simple)
-
-
#include <stdio.h>
-#include "utarray.h"
-
-typedef struct {
-    int a;
-    int b;
-} intpair_t;
-
-UT_icd intpair_icd = {sizeof(intpair_t), NULL, NULL, NULL};
-
-int main() {
-
-  UT_array *pairs;
-  intpair_t ip, *p;
-  utarray_new(pairs,&intpair_icd);
-
-  ip.a=1;  ip.b=2;  utarray_push_back(pairs, &ip);
-  ip.a=10; ip.b=20; utarray_push_back(pairs, &ip);
-
-  for(p=(intpair_t*)utarray_front(pairs);
-      p!=NULL;
-      p=(intpair_t*)utarray_next(pairs,p)) {
-    printf("%d %d\n", p->a, p->b);
-  }
-
-  utarray_free(pairs);
-  return 0;
-}
-
-

The real utility of UT_icd is apparent when the elements of the utarray are -structures that require special work to initialize, copy or destruct.

-

For example, when a structure contains pointers to related memory areas that -need to be copied when the structure is copied (and freed when the structure is -freed), we can use custom init, copy, and dtor members in the UT_icd.

-

Here we take an example of a structure that contains an integer and a string. -When this element is copied (such as when an element is pushed into the array), -we want to "deep copy" the s pointer (so the original element and the new -element point to their own copies of s). When an element is destructed, we -want to "deep free" its copy of s. Lastly, this example is written to work -even if s has the value NULL.

-
-
Structure (complex)
-
-
#include <stdio.h>
-#include <stdlib.h>
-#include "utarray.h"
-
-typedef struct {
-    int a;
-    char *s;
-} intchar_t;
-
-void intchar_copy(void *_dst, const void *_src) {
-  intchar_t *dst = (intchar_t*)_dst, *src = (intchar_t*)_src;
-  dst->a = src->a;
-  dst->s = src->s ? strdup(src->s) : NULL;
-}
-
-void intchar_dtor(void *_elt) {
-  intchar_t *elt = (intchar_t*)_elt;
-  if (elt->s) free(elt->s);
-}
-
-UT_icd intchar_icd = {sizeof(intchar_t), NULL, intchar_copy, intchar_dtor};
-
-int main() {
-  UT_array *intchars;
-  intchar_t ic, *p;
-  utarray_new(intchars, &intchar_icd);
-
-  ic.a=1; ic.s="hello"; utarray_push_back(intchars, &ic);
-  ic.a=2; ic.s="world"; utarray_push_back(intchars, &ic);
-
-  p=NULL;
-  while( (p=(intchar_t*)utarray_next(intchars,p))) {
-    printf("%d %s\n", p->a, (p->s ? p->s : "null"));
-  }
-
-  utarray_free(intchars);
-  return 0;
-}
-
-
-
-
-
-

Reference

-
-

This table lists all the utarray operations. These are loosely based on the C++ -vector class.

-
-

Operations

-
- --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

utarray_new(UT_array *a, UT_icd *icd)

allocate a new array

utarray_free(UT_array *a)

free an allocated array

utarray_init(UT_array *a,UT_icd *icd)

init an array (non-alloc)

utarray_done(UT_array *a)

dispose of an array (non-allocd)

utarray_reserve(UT_array *a,int n)

ensure space available for n more elements

utarray_push_back(UT_array *a,void *p)

push element p onto a

utarray_pop_back(UT_array *a)

pop last element from a

utarray_extend_back(UT_array *a)

push empty element onto a

utarray_len(UT_array *a)

get length of a

utarray_eltptr(UT_array *a,int j)

get pointer of element from index

utarray_eltidx(UT_array *a,void *e)

get index of element from pointer

utarray_insert(UT_array *a,void *p, int j)

insert element p to index j

utarray_inserta(UT_array *a,UT_array *w, int j)

insert array w into array a at index j

utarray_resize(UT_array *dst,int num)

extend or shrink array to num elements

utarray_concat(UT_array *dst,UT_array *src)

copy src to end of dst array

utarray_erase(UT_array *a,int pos,int len)

remove len elements from a[pos]..a[pos+len-1]

utarray_clear(UT_array *a)

clear all elements from a, setting its length to zero

utarray_sort(UT_array *a,cmpfcn *cmp)

sort elements of a using comparison function

utarray_find(UT_array *a,void *v, cmpfcn *cmp)

find element v in utarray (must be sorted)

utarray_front(UT_array *a)

get first element of a

utarray_next(UT_array *a,void *e)

get element of a following e (front if e is NULL)

utarray_prev(UT_array *a,void *e)

get element of a before e (back if e is NULL)

utarray_back(UT_array *a)

get last element of a

-
-
-
-

Notes

-
    -
  1. -

    -utarray_new and utarray_free are used to allocate a new array and free it, - while utarray_init and utarray_done can be used if the UT_array is already - allocated and just needs to be initialized or have its internal resources - freed. -

    -
  2. -
  3. -

    -utarray_reserve takes the "delta" of elements to reserve (not the total - desired capacity of the array-- this differs from the C++ STL "reserve" notion) -

    -
  4. -
  5. -

    -utarray_sort expects a comparison function having the usual strcmp -like - convention where it accepts two elements (a and b) and returns a negative - value if a precedes b, 0 if a and b sort equally, and positive if b precedes a. - This is an example of a comparison function: -

    -
    -
    -
    int intsort(const void *a,const void*b) {
    -    int _a = *(int*)a;
    -    int _b = *(int*)b;
    -    return _a - _b;
    -}
    -
    -
  6. -
  7. -

    -utarray_find uses a binary search to locate an element having a certain value - according to the given comparison function. The utarray must be first sorted - using the same comparison function. An example of using utarray_find with - a utarray of strings is included in tests/test61.c. -

    -
  8. -
  9. -

    -A pointer to a particular element (obtained using utarray_eltptr or - utarray_front, utarray_next, utarray_prev, utarray_back) becomes invalid whenever - another element is inserted into the utarray. This is because the internal - memory management may need to realloc the element storage to a new address. - For this reason, it’s usually better to refer to an element by its integer - index in code whose duration may include element insertion. -

    -
  10. -
-
-
-
-
-

- - - diff --git a/src/util/uthash/doc/utarray.txt b/src/util/uthash/doc/utarray.txt deleted file mode 100644 index 903d5d1..0000000 --- a/src/util/uthash/doc/utarray.txt +++ /dev/null @@ -1,374 +0,0 @@ -utarray: dynamic array macros for C -=================================== -Troy D. Hanson -v1.9.8, March 2013 - -Here's a link back to the https://github.com/troydhanson/uthash[GitHub project page]. - -Introduction ------------- -A set of general-purpose dynamic array macros for C structures are included with -uthash in `utarray.h`. To use these macros in your own C program, just -copy `utarray.h` into your source directory and use it in your programs. - - #include "utarray.h" - -The dynamic array supports basic operations such as push, pop, and erase on the -array elements. These array elements can be any simple datatype or structure. -The array <> are based loosely on the C++ STL vector methods. - -Internally the dynamic array contains a contiguous memory region into which -the elements are copied. This buffer is grown as needed using `realloc` to -accomodate all the data that is pushed into it. - -Download -~~~~~~~~ -To download the `utarray.h` header file, -follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file, -then look in the src/ sub-directory. - -BSD licensed -~~~~~~~~~~~~ -This software is made available under the -link:license.html[revised BSD license]. -It is free and open source. - -Platforms -~~~~~~~~~ -The 'utarray' macros have been tested on: - - * Linux, - * Mac OS X, - * Windows, using Visual Studio 2008 and Visual Studio 2010 - -Usage ------ - -Declaration -~~~~~~~~~~~ - -The array itself has the data type `UT_array`, regardless of the type of -elements to be stored in it. It is declared like, - - UT_array *nums; - -New and free -~~~~~~~~~~~~ -The next step is to create the array using `utarray_new`. Later when you're -done with the array, `utarray_free` will free it and all its elements. - -Push, pop, etc -~~~~~~~~~~~~~~ -The central features of the utarray involve putting elements into it, taking -them out, and iterating over them. There are several <> -to pick from that deal with either single elements or ranges of elements at a -time. In the examples below we will use only the push operation to insert -elements. - -Elements --------- - -Support for dynamic arrays of integers or strings is especially easy. These are -best shown by example: - -Integers -~~~~~~~~ -This example makes a utarray of integers, pushes 0-9 into it, then prints it. -Lastly it frees it. - -.Integer elements -------------------------------------------------------------------------------- -#include -#include "utarray.h" - -int main() { - UT_array *nums; - int i, *p; - - utarray_new(nums,&ut_int_icd); - for(i=0; i < 10; i++) utarray_push_back(nums,&i); - - for(p=(int*)utarray_front(nums); - p!=NULL; - p=(int*)utarray_next(nums,p)) { - printf("%d\n",*p); - } - - utarray_free(nums); - - return 0; -} -------------------------------------------------------------------------------- - -The second argument to `utarray_push_back` is always a 'pointer' to the type -(so a literal cannot be used). So for integers, it is an `int*`. - -Strings -~~~~~~~ -In this example we make a utarray of strings, push two strings into it, print -it and free it. - -.String elements -------------------------------------------------------------------------------- -#include -#include "utarray.h" - -int main() { - UT_array *strs; - char *s, **p; - - utarray_new(strs,&ut_str_icd); - - s = "hello"; utarray_push_back(strs, &s); - s = "world"; utarray_push_back(strs, &s); - p = NULL; - while ( (p=(char**)utarray_next(strs,p))) { - printf("%s\n",*p); - } - - utarray_free(strs); - - return 0; -} -------------------------------------------------------------------------------- - -In this example, since the element is a `char*`, we pass a pointer to it -(`char**`) as the second argument to `utarray_push_back`. Note that "push" makes -a copy of the source string and pushes that copy into the array. - -About UT_icd -~~~~~~~~~~~~ - -Arrays be made of any type of element, not just integers and strings. The -elements can be basic types or structures. Unless you're dealing with integers -and strings (which use pre-defined `ut_int_icd` and `ut_str_icd`), you'll need -to define a `UT_icd` helper structure. This structure contains everything that -utarray needs to initialize, copy or destruct elements. - - typedef struct { - size_t sz; - init_f *init; - ctor_f *copy; - dtor_f *dtor; - } UT_icd; - -The three function pointers `init`, `copy`, and `dtor` have these prototypes: - - typedef void (ctor_f)(void *dst, const void *src); - typedef void (dtor_f)(void *elt); - typedef void (init_f)(void *elt); - -The `sz` is just the size of the element being stored in the array. - -The `init` function will be invoked whenever utarray needs to initialize an -empty element. This only happens as a byproduct of `utarray_resize` or -`utarray_extend_back`. If `init` is `NULL`, it defaults to zero filling the -new element using memset. - -The `copy` function is used whenever an element is copied into the array. -It is invoked during `utarray_push_back`, `utarray_insert`, `utarray_inserta`, -or `utarray_concat`. If `copy` is `NULL`, it defaults to a bitwise copy using -memcpy. - -The `dtor` function is used to clean up an element that is being removed from -the array. It may be invoked due to `utarray_resize`, `utarray_pop_back`, -`utarray_erase`, `utarray_clear`, `utarray_done` or `utarray_free`. If the -elements need no cleanup upon destruction, `dtor` may be `NULL`. - -Scalar types -~~~~~~~~~~~~ - -The next example uses `UT_icd` with all its defaults to make a utarray of -`long` elements. This example pushes two longs, prints them, and frees the -array. - -.long elements -------------------------------------------------------------------------------- -#include -#include "utarray.h" - -UT_icd long_icd = {sizeof(long), NULL, NULL, NULL }; - -int main() { - UT_array *nums; - long l, *p; - utarray_new(nums, &long_icd); - - l=1; utarray_push_back(nums, &l); - l=2; utarray_push_back(nums, &l); - - p=NULL; - while( (p=(long*)utarray_next(nums,p))) printf("%ld\n", *p); - - utarray_free(nums); - return 0; -} -------------------------------------------------------------------------------- - -Structures -~~~~~~~~~~ - -Structures can be used as utarray elements. If the structure requires no -special effort to initialize, copy or destruct, we can use `UT_icd` with all -its defaults. This example shows a structure that consists of two integers. Here -we push two values, print them and free the array. - -.Structure (simple) -------------------------------------------------------------------------------- -#include -#include "utarray.h" - -typedef struct { - int a; - int b; -} intpair_t; - -UT_icd intpair_icd = {sizeof(intpair_t), NULL, NULL, NULL}; - -int main() { - - UT_array *pairs; - intpair_t ip, *p; - utarray_new(pairs,&intpair_icd); - - ip.a=1; ip.b=2; utarray_push_back(pairs, &ip); - ip.a=10; ip.b=20; utarray_push_back(pairs, &ip); - - for(p=(intpair_t*)utarray_front(pairs); - p!=NULL; - p=(intpair_t*)utarray_next(pairs,p)) { - printf("%d %d\n", p->a, p->b); - } - - utarray_free(pairs); - return 0; -} -------------------------------------------------------------------------------- - -The real utility of `UT_icd` is apparent when the elements of the utarray are -structures that require special work to initialize, copy or destruct. - -For example, when a structure contains pointers to related memory areas that -need to be copied when the structure is copied (and freed when the structure is -freed), we can use custom `init`, `copy`, and `dtor` members in the `UT_icd`. - -Here we take an example of a structure that contains an integer and a string. -When this element is copied (such as when an element is pushed into the array), -we want to "deep copy" the `s` pointer (so the original element and the new -element point to their own copies of `s`). When an element is destructed, we -want to "deep free" its copy of `s`. Lastly, this example is written to work -even if `s` has the value `NULL`. - -.Structure (complex) -------------------------------------------------------------------------------- -#include -#include -#include "utarray.h" - -typedef struct { - int a; - char *s; -} intchar_t; - -void intchar_copy(void *_dst, const void *_src) { - intchar_t *dst = (intchar_t*)_dst, *src = (intchar_t*)_src; - dst->a = src->a; - dst->s = src->s ? strdup(src->s) : NULL; -} - -void intchar_dtor(void *_elt) { - intchar_t *elt = (intchar_t*)_elt; - if (elt->s) free(elt->s); -} - -UT_icd intchar_icd = {sizeof(intchar_t), NULL, intchar_copy, intchar_dtor}; - -int main() { - UT_array *intchars; - intchar_t ic, *p; - utarray_new(intchars, &intchar_icd); - - ic.a=1; ic.s="hello"; utarray_push_back(intchars, &ic); - ic.a=2; ic.s="world"; utarray_push_back(intchars, &ic); - - p=NULL; - while( (p=(intchar_t*)utarray_next(intchars,p))) { - printf("%d %s\n", p->a, (p->s ? p->s : "null")); - } - - utarray_free(intchars); - return 0; -} - -------------------------------------------------------------------------------- - -[[operations]] -Reference ---------- -This table lists all the utarray operations. These are loosely based on the C++ -vector class. - -Operations -~~~~~~~~~~ - -[width="100%",cols="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 diff --git a/src/util/uthash/doc/uthash-mini.svg b/src/util/uthash/doc/uthash-mini.svg deleted file mode 100644 index ea2d074..0000000 --- a/src/util/uthash/doc/uthash-mini.svg +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - ut hash - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/util/uthash/doc/uthash.png b/src/util/uthash/doc/uthash.png deleted file mode 100644 index 20df5a7d3566fa1210102c6512956916d30d43a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21518 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�L6@iTtUNOob*ju%^I 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 FV1mJ@2TK3| diff --git a/src/util/uthash/doc/utlist.html b/src/util/uthash/doc/utlist.html deleted file mode 100644 index 298594e..0000000 --- a/src/util/uthash/doc/utlist.html +++ /dev/null @@ -1,1189 +0,0 @@ - - - - - -utlist: linked list macros for C structures - - - - - -
-
-
-

Here’s a link back to the GitHub project page.

-
-
-
-

Introduction

-
-

A set of general-purpose linked list macros for C structures are included with -uthash in utlist.h. To use these macros in your own C program, just -copy utlist.h into your source directory and use it in your programs.

-
-
-
#include "utlist.h"
-
-

These macros support the basic linked list operations: adding and deleting -elements, sorting them and iterating over them.

-
-

Download

-

To download the utlist.h header file, -follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file, -then look in the src/ sub-directory.

-
-
-

BSD licensed

-

This software is made available under the -revised BSD license. -It is free and open source.

-
-
-

Platforms

-

The utlist macros have been tested on:

-
    -
  • -

    -Linux, -

    -
  • -
  • -

    -Mac OS X, and -

    -
  • -
  • -

    -Windows, using Visual Studio 2008, Visual Studio 2010, or Cygwin/MinGW. -

    -
  • -
-
-
-
-
-

Using utlist

-
-
-

Types of lists

-

Three types of linked lists are supported:

-
    -
  • -

    -singly-linked lists, -

    -
  • -
  • -

    -doubly-linked lists, and -

    -
  • -
  • -

    -circular, doubly-linked lists -

    -
  • -
-
-

Efficiency

-

For all types of lists, prepending elements and deleting elements are -constant-time operations. Appending to a singly-linked list is an O(n) -operation but appending to a doubly-linked list is constant time using these -macros. (This is because, in the utlist implementation of the doubly-linked -list, the head element’s prev member points back to the list tail, even when -the list is non-circular). Sorting is an O(n log(n)) operation. Iteration -and searching are O(n) for all list types.

-
-
-
-

List elements

-

You can use any structure with these macros, as long as the structure -contains a next pointer. If you want to make a doubly-linked list, -the element also needs to have a prev pointer.

-
-
-
typedef struct element {
-    char *name;
-    struct element *prev; /* needed for a doubly-linked list only */
-    struct element *next; /* needed for singly- or doubly-linked lists */
-} element;
-
-

You can name your structure anything. In the example above it is called element. -Within a particular list, all elements must be of the same type.

-
-

Flexible prev/next naming

-

You can name your prev and next pointers something else. If you do, there is -a family of macros that work identically but take these names as -extra arguments.

-
-
-
-

List head

-

The list head is simply a pointer to your element structure. You can name it -anything. It must be initialized to NULL.

-
-
-
element *head = NULL;
-
-
-
-

List operations

-

The lists support inserting or deleting elements, sorting the elements and -iterating over them.

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Singly-linked Doubly-linked Circular, doubly-linked

LL_PREPEND(head,add);

DL_PREPEND(head,add);

CDL_PREPEND(head,add;

LL_PREPEND_ELEM(head,elt,add)

DL_PREPEND_ELEM(head,elt,add)

CDL_PREPEND_ELEM(head,elt,add)

LL_REPLACE_ELEM(head,elt,add)

DL_REPLACE_ELEM(head,elt,add)

CDL_REPLACE_ELEM(head,elt,add)

LL_APPEND(head,add);

DL_APPEND(head,add);

LL_CONCAT(head1,head2);

DL_CONCAT(head1,head2);

LL_DELETE(head,del);

DL_DELETE(head,del);

CDL_DELETE(head,del);

LL_SORT(head,cmp);

DL_SORT(head,cmp);

CDL_SORT(head,cmp);

LL_FOREACH(head,elt) {…}

DL_FOREACH(head,elt) {…}

CDL_FOREACH(head,elt) {…}

LL_FOREACH_SAFE(head,elt,tmp) {…}

DL_FOREACH_SAFE(head,elt,tmp) {…}

CDL_FOREACH_SAFE(head,elt,tmp1,tmp2) {…}

LL_SEARCH_SCALAR(head,elt,mbr,val);

DL_SEARCH_SCALAR(head,elt,mbr,val);

CDL_SEARCH_SCALAR(head,elt,mbr,val);

LL_SEARCH(head,elt,like,cmp);

DL_SEARCH(head,elt,like,cmp);

CDL_SEARCH(head,elt,like,cmp);

-
-

Prepend means to insert an element in front of the existing list head (if any), -changing the list head to the new element. Append means to add an element at the -end of the list, so it becomes the new tail element. Concatenate takes two -properly constructed lists and appends the second list to the first. (Visual -Studio 2008 does not support LL_CONCAT and DL_CONCAT, but VS2010 is ok.) -To prepend before an arbitrary element instead of the list head, use the -_PREPEND_ELEM macro family. To replace an arbitary list element with another -element use the _REPLACE_ELEM family of macros.

-

The sort operation never moves the elements in memory; rather it only adjusts -the list order by altering the prev and next pointers in each element. Also -the sort operation can change the list head to point to a new element.

-

The foreach operation is for easy iteration over the list from the head to the -tail. A usage example is shown below. You can of course just use the prev and -next pointers directly instead of using the foreach macros. -The foreach_safe operation should be used if you plan to delete any of the list -elements while iterating.

-

The search operation is a shortcut for iteration in search of a particular -element. It is not any faster than manually iterating and testing each element. -There are two forms: the "scalar" version searches for an element using a -simple equality test on a given structure member, while the general version takes an -element to which all others in the list will be compared using a cmp function.

-

The parameters shown in the table above are explained here:

-
-
-head -
-
-

- The list head (a pointer to your list element structure). -

-
-
-add -
-
-

- A pointer to the list element structure you are adding to the list. -

-
-
-del -
-
-

- A pointer to the list element structure you are deleting from the list. -

-
-
-elt -
-
-

- A pointer that will be assigned to each list element in succession (see - example) in the case of iteration macros; or, the output pointer from - the search macros; or the element to be prepended to or replaced. -

-
-
-like -
-
-

- An element pointer, having the same type as elt, for which the search macro - seeks a match (if found, the match is stored in elt). A match is determined - by the given cmp function. -

-
-
-cmp -
-
-

- pointer to comparison function which accepts two arguments-- these are - pointers to two element structures to be compared. The comparison function - must return an int that is negative, zero, or positive, which specifies - whether the first item should sort before, equal to, or after the second item, - respectively. (In other words, the same convention that is used by strcmp). - Note that under Visual Studio 2008 you may need to declare the two arguments - as void * and then cast them back to their actual types. -

-
-
-tmp -
-
-

- A pointer of the same type as elt. Used internally. Need not be initialized. -

-
-
-mbr -
-
-

- In the scalar search macro, the name of a member within the elt structure which - will be tested (using ==) for equality with the value val. -

-
-
-val -
-
-

- In the scalar search macro, specifies the value of (of structure member - field) of the element being sought. -

-
-
-
-
-

Example

-

This example program reads names from a text file (one name per line), and -appends each name to a doubly-linked list. Then it sorts and prints them.

-
-
A doubly-linked list
-
-
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "utlist.h"
-
-#define BUFLEN 20
-
-typedef struct el {
-    char bname[BUFLEN];
-    struct el *next, *prev;
-} el;
-
-int namecmp(el *a, el *b) {
-    return strcmp(a->bname,b->bname);
-}
-
-el *head = NULL; /* important- initialize to NULL! */
-
-int main(int argc, char *argv[]) {
-    el *name, *elt, *tmp, etmp;
-
-    char linebuf[BUFLEN];
-    FILE *file;
-
-    if ( (file = fopen( "test11.dat", "r" )) == NULL ) {
-        perror("can't open: ");
-        exit(-1);
-    }
-
-    while (fgets(linebuf,BUFLEN,file) != NULL) {
-        if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1);
-        strncpy(name->bname,linebuf,BUFLEN);
-        DL_APPEND(head, name);
-    }
-    DL_SORT(head, namecmp);
-    DL_FOREACH(head,elt) printf("%s", elt->bname);
-
-    memcpy(&etmp.bname, "WES\n", 5);
-    DL_SEARCH(head,elt,&etmp,namecmp);
-    if (elt) printf("found %s\n", elt->bname);
-
-    /* now delete each element, use the safe iterator */
-    DL_FOREACH_SAFE(head,elt,tmp) {
-      DL_DELETE(head,elt);
-    }
-
-    fclose(file);
-
-    return 0;
-}
-
-
-
-

Other names for prev and next

-

If the prev and next fields are named something else, a separate group of -macros must be used. These work the same as the regular macros, but take the -field names as extra parameters.

-

These "flexible field name" macros are shown below. They all end with "2". Each -operates the same as its counterpart without the 2, but they take the name of -the prev and next fields (as applicable) as trailing arguments.

-
-
Flexible field name macros
-
-
LL_SORT2(list, cmp, next)
-DL_SORT2(list, cmp, prev, next)
-CDL_SORT2(list, cmp, prev, next)
-LL_PREPEND2(head,add,next)
-LL_CONCAT2(head1,head2,next)
-LL_APPEND2(head,add,next)
-LL_DELETE2(head,del,next)
-LL_FOREACH2(head,el,next)
-LL_FOREACH_SAFE2(head,el,tmp,next)
-LL_SEARCH_SCALAR2(head,out,field,val,next)
-LL_SEARCH2(head,out,elt,cmp,next)
-DL_PREPEND2(head,add,prev,next)
-DL_APPEND2(head,add,prev,next)
-DL_CONCAT2(head1,head2,prev,next)
-DL_DELETE2(head,del,prev,next)
-DL_FOREACH2(head,el,next)
-DL_FOREACH_SAFE2(head,el,tmp,next)
-CDL_PREPEND2(head,add,prev,next)
-CDL_DELETE2(head,del,prev,next)
-CDL_FOREACH2(head,el,next)
-CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next)
-CDL_SEARCH_SCALAR2(head,out,field,val,next)
-CDL_SEARCH2(head,out,elt,cmp,next)
-
-
-
-
-
-

- - - diff --git a/src/util/uthash/doc/utlist.txt b/src/util/uthash/doc/utlist.txt deleted file mode 100644 index c795042..0000000 --- a/src/util/uthash/doc/utlist.txt +++ /dev/null @@ -1,264 +0,0 @@ -utlist: linked list macros for C structures -=========================================== -Troy D. Hanson -v1.9.8, March 2013 - -Here's a link back to the https://github.com/troydhanson/uthash[GitHub project page]. - -Introduction ------------- -A set of general-purpose 'linked list' macros for C structures are included with -uthash in `utlist.h`. To use these macros in your own C program, just -copy `utlist.h` into your source directory and use it in your programs. - - #include "utlist.h" - -These macros support the basic linked list operations: adding and deleting -elements, sorting them and iterating over them. - -Download -~~~~~~~~ -To download the `utlist.h` header file, -follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file, -then look in the src/ sub-directory. - -BSD licensed -~~~~~~~~~~~~ -This software is made available under the -link:license.html[revised BSD license]. -It is free and open source. - -Platforms -~~~~~~~~~ -The 'utlist' macros have been tested on: - - * Linux, - * Mac OS X, and - * Windows, using Visual Studio 2008, Visual Studio 2010, or Cygwin/MinGW. - -Using utlist ------------- - -Types of lists -~~~~~~~~~~~~~~ -Three types of linked lists are supported: - -- *singly-linked* lists, -- *doubly-linked* lists, and -- *circular, doubly-linked* lists - -Efficiency -^^^^^^^^^^ -For all types of lists, prepending elements and deleting elements are -constant-time operations. Appending to a singly-linked list is an 'O(n)' -operation but appending to a doubly-linked list is constant time using these -macros. (This is because, in the utlist implementation of the doubly-linked -list, the head element's `prev` member points back to the list tail, even when -the list is non-circular). Sorting is an 'O(n log(n))' operation. Iteration -and searching are `O(n)` for all list types. - -List elements -~~~~~~~~~~~~~ -You can use any structure with these macros, as long as the structure -contains a `next` pointer. If you want to make a doubly-linked list, -the element also needs to have a `prev` pointer. - - typedef struct element { - char *name; - struct element *prev; /* needed for a doubly-linked list only */ - struct element *next; /* needed for singly- or doubly-linked lists */ - } element; - -You can name your structure anything. In the example above it is called `element`. -Within a particular list, all elements must be of the same type. - -Flexible prev/next naming -^^^^^^^^^^^^^^^^^^^^^^^^^ -You can name your `prev` and `next` pointers something else. If you do, there is -a <> that work identically but take these names as -extra arguments. - -List head -~~~~~~~~~ -The list head is simply a pointer to your element structure. You can name it -anything. *It must be initialized to `NULL`*. - - element *head = NULL; - -List operations -~~~~~~~~~~~~~~~ -The lists support inserting or deleting elements, sorting the elements and -iterating over them. - -[width="100%",cols="10 -#include -#include -#include "utlist.h" - -#define BUFLEN 20 - -typedef struct el { - char bname[BUFLEN]; - struct el *next, *prev; -} el; - -int namecmp(el *a, el *b) { - return strcmp(a->bname,b->bname); -} - -el *head = NULL; /* important- initialize to NULL! */ - -int main(int argc, char *argv[]) { - el *name, *elt, *tmp, etmp; - - char linebuf[BUFLEN]; - FILE *file; - - if ( (file = fopen( "test11.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); - strncpy(name->bname,linebuf,BUFLEN); - DL_APPEND(head, name); - } - DL_SORT(head, namecmp); - DL_FOREACH(head,elt) printf("%s", elt->bname); - - memcpy(&etmp.bname, "WES\n", 5); - DL_SEARCH(head,elt,&etmp,namecmp); - if (elt) printf("found %s\n", elt->bname); - - /* now delete each element, use the safe iterator */ - DL_FOREACH_SAFE(head,elt,tmp) { - DL_DELETE(head,elt); - } - - fclose(file); - - return 0; -} --------------------------------------------------------------------------------- - -[[flex_names]] -Other names for prev and next -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If the `prev` and `next` fields are named something else, a separate group of -macros must be used. These work the same as the regular macros, but take the -field names as extra parameters. - -These "flexible field name" macros are shown below. They all end with "2". Each -operates the same as its counterpart without the 2, but they take the name of -the `prev` and `next` fields (as applicable) as trailing arguments. - -.Flexible field name macros - LL_SORT2(list, cmp, next) - DL_SORT2(list, cmp, prev, next) - CDL_SORT2(list, cmp, prev, next) - LL_PREPEND2(head,add,next) - LL_CONCAT2(head1,head2,next) - LL_APPEND2(head,add,next) - LL_DELETE2(head,del,next) - LL_FOREACH2(head,el,next) - LL_FOREACH_SAFE2(head,el,tmp,next) - LL_SEARCH_SCALAR2(head,out,field,val,next) - LL_SEARCH2(head,out,elt,cmp,next) - DL_PREPEND2(head,add,prev,next) - DL_APPEND2(head,add,prev,next) - DL_CONCAT2(head1,head2,prev,next) - DL_DELETE2(head,del,prev,next) - DL_FOREACH2(head,el,next) - DL_FOREACH_SAFE2(head,el,tmp,next) - CDL_PREPEND2(head,add,prev,next) - CDL_DELETE2(head,del,prev,next) - CDL_FOREACH2(head,el,next) - CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) - CDL_SEARCH_SCALAR2(head,out,field,val,next) - CDL_SEARCH2(head,out,elt,cmp,next) - -// vim: set tw=80 wm=2 syntax=asciidoc: - diff --git a/src/util/uthash/doc/utstring.html b/src/util/uthash/doc/utstring.html deleted file mode 100644 index 8d5a705..0000000 --- a/src/util/uthash/doc/utstring.html +++ /dev/null @@ -1,1074 +0,0 @@ - - - - - -utstring: dynamic string macros for C - - - - - -
-
-
-

Here’s a link back to the GitHub project page.

-
-
-
-

Introduction

-
-

A set of basic dynamic string macros for C programs are included with -uthash in utstring.h. To use these in your own C program, just copy -utstring.h into your source directory and use it in your programs.

-
-
-
#include "utstring.h"
-
-

The dynamic string supports operations such as inserting data, concatenation, -getting the length and content, substring search, and clear. It’s ok to put -binary data into a utstring too. The string operations are -listed below.

-

Some utstring operations are implemented as functions rather than macros.

-
-

Download

-

To download the utstring.h header file, -follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file, -then look in the src/ sub-directory.

-
-
-

BSD licensed

-

This software is made available under the -revised BSD license. -It is free and open source.

-
-
-

Platforms

-

The utstring macros have been tested on:

-
    -
  • -

    -Linux, -

    -
  • -
  • -

    -Windows, using Visual Studio 2008 and Visual Studio 2010 -

    -
  • -
-
-
-
-
-

Usage

-
-
-

Declaration

-

The dynamic string itself has the data type UT_string. It is declared like,

-
-
-
UT_string *str;
-
-
-
-

New and free

-

The next step is to create the string using utstring_new. Later when you’re -done with it, utstring_free will free it and all its content.

-
-
-

Manipulation

-

The utstring_printf or utstring_bincpy operations insert (copy) data into -the string. To concatenate one utstring to another, use utstring_concat. To -clear the content of the string, use utstring_clear. The length of the string -is available from utstring_len, and its content from utstring_body. This -evaluates to a char*. The buffer it points to is always null-terminated. -So, it can be used directly with external functions that expect a string. -This automatic null terminator is not counted in the length of the string.

-
-
-

Samples

-

These examples show how to use utstring.

-
-
Sample 1
-
-
#include <stdio.h>
-#include "utstring.h"
-
-int main() {
-    UT_string *s;
-
-    utstring_new(s);
-    utstring_printf(s, "hello world!" );
-    printf("%s\n", utstring_body(s));
-
-    utstring_free(s);
-    return 0;
-}
-
-

The next example demonstrates that utstring_printf appends to the string. -It also shows concatenation.

-
-
Sample 2
-
-
#include <stdio.h>
-#include "utstring.h"
-
-int main() {
-    UT_string *s, *t;
-
-    utstring_new(s);
-    utstring_new(t);
-
-    utstring_printf(s, "hello " );
-    utstring_printf(s, "world " );
-
-    utstring_printf(t, "hi " );
-    utstring_printf(t, "there " );
-
-    utstring_concat(s, t);
-    printf("length: %u\n", utstring_len(s));
-    printf("%s\n", utstring_body(s));
-
-    utstring_free(s);
-    utstring_free(t);
-    return 0;
-}
-
-

The next example shows how binary data can be inserted into the string. It also -clears the string and prints new data into it.

-
-
Sample 3
-
-
#include <stdio.h>
-#include "utstring.h"
-
-int main() {
-    UT_string *s;
-    char binary[] = "\xff\xff";
-
-    utstring_new(s);
-    utstring_bincpy(s, binary, sizeof(binary));
-    printf("length is %u\n", utstring_len(s));
-
-    utstring_clear(s);
-    utstring_printf(s,"number %d", 10);
-    printf("%s\n", utstring_body(s));
-
-    utstring_free(s);
-    return 0;
-}
-
-
-
-
-
-

Reference

-
-

These are the utstring operations.

-
-

Operations

-
- --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

utstring_new(s)

allocate a new utstring

utstring_renew(s)

allocate a new utstring (if s is NULL) otherwise clears it

utstring_free(s)

free an allocated utstring

utstring_init(s)

init a utstring (non-alloc)

utstring_done(s)

dispose of a utstring (non-allocd)

utstring_printf(s,fmt,…)

printf into a utstring (appends)

utstring_bincpy(s,bin,len)

insert binary data of length len (appends)

utstring_concat(dst,src)

concatenate src utstring to end of dst utstring

utstring_clear(s)

clear the content of s (setting its length to 0)

utstring_len(s)

obtain the length of s as an unsigned integer

utstring_body(s)

get char* to body of s (buffer is always null-terminated)

utstring_find(s,pos,str,len)

forward search from pos for a substring

utstring_findR(s,pos,str,len)

reverse search from pos a substring

-
-
-
-

New/free vs. init/done

-

Use utstring_new and utstring_free to allocate a new string or free it. If -the UT_string is statically allocated, use utstring_init and utstring_done -to initialize or free its internal memory.

-
-
- -

Use utstring_find and utstring_findR to search for a substring in a utstring. -It comes in forward and reverse varieties. The reverse search scans from the end of -the string backward. These take a position to start searching from, measured from 0 -(the start of the utstring). A negative position is counted from the end of -the string, so, -1 is the last position. Note that in the reverse search, the -initial position anchors to the end of the substring being searched for- -e.g., the t in cat. The return value always refers to the offset where the -substring starts in the utstring. When no substring match is found, -1 is -returned.

-

For example if a utstring called s contains:

-
-
-
ABC ABCDAB ABCDABCDABDE
-
-

Then these forward and reverse substring searches for ABC produce these results:

-
-
-
utstring_find(  s, -9, "ABC", 3 ) = 15
-utstring_find(  s,  3, "ABC", 3 ) =  4
-utstring_find(  s, 16, "ABC", 3 ) = -1
-utstring_findR( s, -9, "ABC", 3 ) = 11
-utstring_findR( s, 12, "ABC", 3 ) =  4
-utstring_findR( s,  2, "ABC", 3 ) =  0
-
-
- -

The preceding examples show "single use" versions of substring matching, where -the internal Knuth-Morris-Pratt (KMP) table is internally built and then freed -after the search. If your program needs to run many searches for a given -substring, it is more efficient to save the KMP table and reuse it.

-

To reuse the KMP table, build it manually and then pass it into the internal -search functions. The functions involved are:

-
-
-
_utstring_BuildTable  (build the KMP table for a forward search)
-_utstring_BuildTableR (build the KMP table for a reverse search)
-_utstring_find        (forward search using a prebuilt KMP table)
-_utstring_findR       (reverse search using a prebuilt KMP table)
-
-

This is an example of building a forward KMP table for the substring "ABC", and -then using it in a search:

-
-
-
long *KPM_TABLE, offset;
-KPM_TABLE = (long *)malloc( sizeof(long) * (strlen("ABC")) + 1));
-_utstring_BuildTable("ABC", 3, KPM_TABLE);
-offset = _utstring_find(utstring_body(s), utstring_len(s), "ABC", 3, KPM_TABLE );
-free(KPM_TABLE);
-
-

Note that the internal _utstring_find has the length of the UT_string as its -second argument, rather than the start position. You can emulate the position -parameter by adding to the string start address and subtracting from its length.

-
-
-
-
-
-

- - - diff --git a/src/util/uthash/doc/utstring.txt b/src/util/uthash/doc/utstring.txt deleted file mode 100644 index b1c6664..0000000 --- a/src/util/uthash/doc/utstring.txt +++ /dev/null @@ -1,229 +0,0 @@ -utstring: dynamic string macros for C -===================================== -Troy D. Hanson -v1.9.8, March 2013 - -Here's a link back to the https://github.com/troydhanson/uthash[GitHub project page]. - -Introduction ------------- -A set of basic dynamic string macros for C programs are included with -uthash in `utstring.h`. To use these in your own C program, just copy -`utstring.h` into your source directory and use it in your programs. - - #include "utstring.h" - -The dynamic string supports operations such as inserting data, concatenation, -getting the length and content, substring search, and clear. It's ok to put -binary data into a utstring too. The string <> are -listed below. - -Some utstring operations are implemented as functions rather than macros. - -Download -~~~~~~~~ -To download the `utstring.h` header file, -follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file, -then look in the src/ sub-directory. - -BSD licensed -~~~~~~~~~~~~ -This software is made available under the -link:license.html[revised BSD license]. -It is free and open source. - -Platforms -~~~~~~~~~ -The 'utstring' macros have been tested on: - - * Linux, - * Windows, using Visual Studio 2008 and Visual Studio 2010 - -Usage ------ - -Declaration -~~~~~~~~~~~ - -The dynamic string itself has the data type `UT_string`. It is declared like, - - UT_string *str; - -New and free -~~~~~~~~~~~~ -The next step is to create the string using `utstring_new`. Later when you're -done with it, `utstring_free` will free it and all its content. - -Manipulation -~~~~~~~~~~~~ -The `utstring_printf` or `utstring_bincpy` operations insert (copy) data into -the string. To concatenate one utstring to another, use `utstring_concat`. To -clear the content of the string, use `utstring_clear`. The length of the string -is available from `utstring_len`, and its content from `utstring_body`. This -evaluates to a `char*`. The buffer it points to is always null-terminated. -So, it can be used directly with external functions that expect a string. -This automatic null terminator is not counted in the length of the string. - -Samples -~~~~~~~ - -These examples show how to use utstring. - -.Sample 1 -------------------------------------------------------------------------------- -#include -#include "utstring.h" - -int main() { - UT_string *s; - - utstring_new(s); - utstring_printf(s, "hello world!" ); - printf("%s\n", utstring_body(s)); - - utstring_free(s); - return 0; -} -------------------------------------------------------------------------------- - -The next example demonstrates that `utstring_printf` 'appends' to the string. -It also shows concatenation. - -.Sample 2 -------------------------------------------------------------------------------- -#include -#include "utstring.h" - -int main() { - UT_string *s, *t; - - utstring_new(s); - utstring_new(t); - - utstring_printf(s, "hello " ); - utstring_printf(s, "world " ); - - utstring_printf(t, "hi " ); - utstring_printf(t, "there " ); - - utstring_concat(s, t); - printf("length: %u\n", utstring_len(s)); - printf("%s\n", utstring_body(s)); - - utstring_free(s); - utstring_free(t); - return 0; -} -------------------------------------------------------------------------------- - -The next example shows how binary data can be inserted into the string. It also -clears the string and prints new data into it. - -.Sample 3 -------------------------------------------------------------------------------- -#include -#include "utstring.h" - -int main() { - UT_string *s; - char binary[] = "\xff\xff"; - - utstring_new(s); - utstring_bincpy(s, binary, sizeof(binary)); - printf("length is %u\n", utstring_len(s)); - - utstring_clear(s); - utstring_printf(s,"number %d", 10); - printf("%s\n", utstring_body(s)); - - utstring_free(s); - return 0; -} -------------------------------------------------------------------------------- - -[[operations]] -Reference ---------- -These are the utstring operations. - -Operations -~~~~~~~~~~ - -[width="100%",cols="50 /* size_t */ #include /* memset, etc */ #include /* exit */ -#define oom() exit(-1) +#ifdef __GNUC__ +#define UTARRAY_UNUSED __attribute__((__unused__)) +#else +#define UTARRAY_UNUSED +#endif + +#ifdef oom +#error "The name of macro 'oom' has been changed to 'utarray_oom'. Please update your code." +#define utarray_oom() oom() +#endif + +#ifndef utarray_oom +#define utarray_oom() exit(-1) +#endif typedef void (ctor_f)(void *dst, const void *src); typedef void (dtor_f)(void *elt); @@ -58,13 +65,13 @@ typedef struct { #define utarray_init(a,_icd) do { \ memset(a,0,sizeof(UT_array)); \ - (a)->icd=*_icd; \ + (a)->icd = *(_icd); \ } while(0) #define utarray_done(a) do { \ if ((a)->n) { \ if ((a)->icd.dtor) { \ - size_t _ut_i; \ + unsigned _ut_i; \ for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \ } \ @@ -75,7 +82,10 @@ typedef struct { } while(0) #define utarray_new(a,_icd) do { \ - a=(UT_array*)malloc(sizeof(UT_array)); \ + (a) = (UT_array*)malloc(sizeof(UT_array)); \ + if ((a) == NULL) { \ + utarray_oom(); \ + } \ utarray_init(a,_icd); \ } while(0) @@ -85,9 +95,14 @@ typedef struct { } while(0) #define utarray_reserve(a,by) do { \ - if (((a)->i+by) > ((a)->n)) { \ - while(((a)->i+by) > ((a)->n)) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \ - if ( ((a)->d=(char*)realloc((a)->d, (a)->n*(a)->icd.sz)) == NULL) oom(); \ + if (((a)->i+(by)) > (a)->n) { \ + char *utarray_tmp; \ + while (((a)->i+(by)) > (a)->n) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \ + utarray_tmp=(char*)realloc((a)->d, (a)->n*(a)->icd.sz); \ + if (utarray_tmp == NULL) { \ + utarray_oom(); \ + } \ + (a)->d=utarray_tmp; \ } \ } while(0) @@ -112,10 +127,10 @@ typedef struct { #define utarray_len(a) ((a)->i) #define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL) -#define _utarray_eltptr(a,j) ((char*)((a)->d + ((a)->icd.sz*(j) ))) +#define _utarray_eltptr(a,j) ((void*)((a)->d + ((a)->icd.sz * (j)))) #define utarray_insert(a,p,j) do { \ - if (j > (a)->i) utarray_resize(a,j); \ + if ((j) > (a)->i) utarray_resize(a,j); \ utarray_reserve(a,1); \ if ((j) < (a)->i) { \ memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \ @@ -128,7 +143,7 @@ typedef struct { #define utarray_inserta(a,w,j) do { \ if (utarray_len(w) == 0) break; \ - if (j > (a)->i) utarray_resize(a,j); \ + if ((j) > (a)->i) utarray_resize(a,j); \ utarray_reserve(a,utarray_len(w)); \ if ((j) < (a)->i) { \ memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \ @@ -136,9 +151,9 @@ typedef struct { ((a)->i - (j))*((a)->icd.sz)); \ } \ if ((a)->icd.copy) { \ - size_t _ut_i; \ + unsigned _ut_i; \ for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \ - (a)->icd.copy(_utarray_eltptr(a,j+_ut_i), _utarray_eltptr(w,_ut_i)); \ + (a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), _utarray_eltptr(w, _ut_i)); \ } \ } else { \ memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \ @@ -148,55 +163,55 @@ typedef struct { } while(0) #define utarray_resize(dst,num) do { \ - size_t _ut_i; \ - if (dst->i > (size_t)(num)) { \ + unsigned _ut_i; \ + if ((dst)->i > (unsigned)(num)) { \ if ((dst)->icd.dtor) { \ - for(_ut_i=num; _ut_i < dst->i; _ut_i++) { \ - (dst)->icd.dtor(utarray_eltptr(dst,_ut_i)); \ + for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \ + (dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \ } \ } \ - } else if (dst->i < (size_t)(num)) { \ - utarray_reserve(dst,num-dst->i); \ + } else if ((dst)->i < (unsigned)(num)) { \ + utarray_reserve(dst, (num) - (dst)->i); \ if ((dst)->icd.init) { \ - for(_ut_i=dst->i; _ut_i < num; _ut_i++) { \ - (dst)->icd.init(utarray_eltptr(dst,_ut_i)); \ + for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \ + (dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \ } \ } else { \ - memset(_utarray_eltptr(dst,dst->i),0,(dst)->icd.sz*(num-dst->i)); \ + memset(_utarray_eltptr(dst, (dst)->i), 0, (dst)->icd.sz*((num) - (dst)->i)); \ } \ } \ - dst->i = num; \ + (dst)->i = (num); \ } while(0) #define utarray_concat(dst,src) do { \ - utarray_inserta((dst),(src),utarray_len(dst)); \ + utarray_inserta(dst, src, utarray_len(dst)); \ } while(0) #define utarray_erase(a,pos,len) do { \ if ((a)->icd.dtor) { \ - size_t _ut_i; \ - for(_ut_i=0; _ut_i < len; _ut_i++) { \ - (a)->icd.dtor(utarray_eltptr((a),pos+_ut_i)); \ + unsigned _ut_i; \ + for (_ut_i = 0; _ut_i < (len); _ut_i++) { \ + (a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \ } \ } \ - if ((a)->i > (pos+len)) { \ - memmove( _utarray_eltptr((a),pos), _utarray_eltptr((a),pos+len), \ - (((a)->i)-(pos+len))*((a)->icd.sz)); \ + if ((a)->i > ((pos) + (len))) { \ + memmove(_utarray_eltptr(a, pos), _utarray_eltptr(a, (pos) + (len)), \ + ((a)->i - ((pos) + (len))) * (a)->icd.sz); \ } \ (a)->i -= (len); \ } while(0) #define utarray_renew(a,u) do { \ - if (a) utarray_clear(a); \ - else utarray_new((a),(u)); \ -} while(0) + if (a) utarray_clear(a); \ + else utarray_new(a, u); \ +} while(0) #define utarray_clear(a) do { \ if ((a)->i > 0) { \ if ((a)->icd.dtor) { \ - size_t _ut_i; \ + unsigned _ut_i; \ for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ - (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \ + (a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \ } \ } \ (a)->i = 0; \ @@ -210,23 +225,24 @@ typedef struct { #define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp) #define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL) -#define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : ((((a)->i) > (utarray_eltidx(a,e)+1)) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL)) -#define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) > 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL)) +#define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : (((a)->i != utarray_eltidx(a,e)+1) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL)) +#define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) != 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL)) #define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL) -#define utarray_eltidx(a,e) (((char*)(e) >= (char*)((a)->d)) ? (((char*)(e) - (char*)((a)->d))/(ssize_t)(a)->icd.sz) : -1) +#define utarray_eltidx(a,e) (((char*)(e) - (a)->d) / (a)->icd.sz) /* last we pre-define a few icd for common utarrays of ints and strings */ static void utarray_str_cpy(void *dst, const void *src) { - char **_src = (char**)src, **_dst = (char**)dst; - *_dst = (*_src == NULL) ? NULL : strdup(*_src); + char *const *srcc = (char *const *)src; + char **dstc = (char**)dst; + *dstc = (*srcc == NULL) ? NULL : strdup(*srcc); } static void utarray_str_dtor(void *elt) { char **eltc = (char**)elt; - if (*eltc) free(*eltc); + if (*eltc != NULL) free(*eltc); } -static const UT_icd ut_str_icd _UNUSED_ = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor}; -static const UT_icd ut_int_icd _UNUSED_ = {sizeof(int),NULL,NULL,NULL}; -static const UT_icd ut_ptr_icd _UNUSED_ = {sizeof(void*),NULL,NULL,NULL}; +static const UT_icd ut_str_icd UTARRAY_UNUSED = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor}; +static const UT_icd ut_int_icd UTARRAY_UNUSED = {sizeof(int),NULL,NULL,NULL}; +static const UT_icd ut_ptr_icd UTARRAY_UNUSED = {sizeof(void*),NULL,NULL,NULL}; #endif /* UTARRAY_H */ diff --git a/src/util/uthash/src/uthash.h b/src/util/uthash/src/uthash.h index f0e50f9..ac78fda 100644 --- a/src/util/uthash/src/uthash.h +++ b/src/util/uthash/src/uthash.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2013, Troy D. Hanson http://troydhanson.github.com/uthash/ +Copyright (c) 2003-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without @@ -22,59 +22,76 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UTHASH_H -#define UTHASH_H +#define UTHASH_H -#include /* memcmp,strlen */ +#define UTHASH_VERSION 2.3.0 + +#include /* memcmp, memset, strlen */ #include /* ptrdiff_t */ -#include /* exit() */ +#include /* exit */ + +#if defined(HASH_DEFINE_OWN_STDINT) && HASH_DEFINE_OWN_STDINT +/* This codepath is provided for backward compatibility, but I plan to remove it. */ +#warning "HASH_DEFINE_OWN_STDINT is deprecated; please use HASH_NO_STDINT instead" +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#elif defined(HASH_NO_STDINT) && HASH_NO_STDINT +#else +#include /* uint8_t, uint32_t */ +#endif /* These macros use decltype or the earlier __typeof GNU extension. As decltype is only available in newer compilers (VS2010 or gcc 4.3+ when compiling c++ source) this code uses whatever method is needed or, for VS2008 where neither is available, uses casting workarounds. */ -#ifdef _MSC_VER /* MS compiler */ +#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ #if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ #define DECLTYPE(x) (decltype(x)) #else /* VS2008 or older (or VS2010 in C mode) */ #define NO_DECLTYPE -#define DECLTYPE(x) #endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE #else /* GNU, Sun and other compilers */ #define DECLTYPE(x) (__typeof(x)) #endif +#endif #ifdef NO_DECLTYPE +#define DECLTYPE(x) #define DECLTYPE_ASSIGN(dst,src) \ do { \ char **_da_dst = (char**)(&(dst)); \ *_da_dst = (char*)(src); \ -} while(0) -#else +} while (0) +#else #define DECLTYPE_ASSIGN(dst,src) \ do { \ (dst) = DECLTYPE(dst)(src); \ -} while(0) +} while (0) #endif -/* a number of the hash function use uint32_t which isn't defined on win32 */ -#ifdef _MSC_VER -typedef unsigned int uint32_t; -typedef unsigned char uint8_t; -#else -#include /* uint32_t */ -#endif - -#define UTHASH_VERSION 1.9.8 - -#ifndef uthash_fatal -#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ -#endif #ifndef uthash_malloc #define uthash_malloc(sz) malloc(sz) /* malloc fcn */ #endif #ifndef uthash_free #define uthash_free(ptr,sz) free(ptr) /* free fcn */ #endif +#ifndef uthash_bzero +#define uthash_bzero(a,n) memset(a,'\0',n) +#endif +#ifndef uthash_strlen +#define uthash_strlen(s) strlen(s) +#endif + +#ifndef HASH_FUNCTION +#define HASH_FUNCTION(keyptr,keylen,hashv) HASH_JEN(keyptr, keylen, hashv) +#endif + +#ifndef HASH_KEYCMP +#define HASH_KEYCMP(a,b,n) memcmp(a,b,n) +#endif #ifndef uthash_noexpand_fyi #define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ @@ -83,122 +100,338 @@ typedef unsigned char uint8_t; #define uthash_expand_fyi(tbl) /* can be defined to log expands */ #endif -/* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ -#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ +#ifndef HASH_NONFATAL_OOM +#define HASH_NONFATAL_OOM 0 +#endif -/* calculate the element whose hash handle address is hhe */ +#if HASH_NONFATAL_OOM +/* malloc failures can be recovered from */ + +#ifndef uthash_nonfatal_oom +#define uthash_nonfatal_oom(obj) do {} while (0) /* non-fatal OOM error */ +#endif + +#define HASH_RECORD_OOM(oomed) do { (oomed) = 1; } while (0) +#define IF_HASH_NONFATAL_OOM(x) x + +#else +/* malloc failures result in lost memory, hash tables are unusable */ + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal OOM error */ +#endif + +#define HASH_RECORD_OOM(oomed) uthash_fatal("out of memory") +#define IF_HASH_NONFATAL_OOM(x) + +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhp */ #define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) +/* calculate the hash handle from element address elp */ +#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle*)(void*)(((char*)(elp)) + ((tbl)->hho))) + +#define HASH_ROLLBACK_BKT(hh, head, itemptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_item = (itemptrhh); \ + unsigned _hd_bkt; \ + HASH_TO_BKT(_hd_hh_item->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + (head)->hh.tbl->buckets[_hd_bkt].count++; \ + _hd_hh_item->hh_next = NULL; \ + _hd_hh_item->hh_prev = NULL; \ +} while (0) + +#define HASH_VALUE(keyptr,keylen,hashv) \ +do { \ + HASH_FUNCTION(keyptr, keylen, hashv); \ +} while (0) + +#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_bkt; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ + } \ + } \ +} while (0) #define HASH_FIND(hh,head,keyptr,keylen,out) \ do { \ - unsigned _hf_bkt,_hf_hashv; \ - out=NULL; \ + (out) = NULL; \ if (head) { \ - HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ - if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ - HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ - keyptr,keylen,out); \ - } \ + unsigned _hf_hashv; \ + HASH_VALUE(keyptr, keylen, _hf_hashv); \ + HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ } \ } while (0) #ifdef HASH_BLOOM -#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) -#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) -#define HASH_BLOOM_MAKE(tbl) \ +#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) +#define HASH_BLOOM_MAKE(tbl,oomed) \ do { \ (tbl)->bloom_nbits = HASH_BLOOM; \ (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ - if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ - memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ - (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ -} while (0) + if (!(tbl)->bloom_bv) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ + } \ +} while (0) #define HASH_BLOOM_FREE(tbl) \ do { \ uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ -} while (0) +} while (0) -#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) -#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) #define HASH_BLOOM_ADD(tbl,hashv) \ - HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) #define HASH_BLOOM_TEST(tbl,hashv) \ - HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + HASH_BLOOM_BITTEST((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) #else -#define HASH_BLOOM_MAKE(tbl) -#define HASH_BLOOM_FREE(tbl) -#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_MAKE(tbl,oomed) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) #define HASH_BLOOM_TEST(tbl,hashv) (1) -#define HASH_BLOOM_BYTELEN 0 +#define HASH_BLOOM_BYTELEN 0U #endif -#define HASH_MAKE_TABLE(hh,head) \ +#define HASH_MAKE_TABLE(hh,head,oomed) \ do { \ - (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ - sizeof(UT_hash_table)); \ - if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ - memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ - (head)->hh.tbl->tail = &((head)->hh); \ - (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ - (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ - (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ - (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ - HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ - if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ - memset((head)->hh.tbl->buckets, 0, \ - HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ - HASH_BLOOM_MAKE((head)->hh.tbl); \ - (head)->hh.tbl->signature = HASH_SIGNATURE; \ -} while(0) + (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ + if (!(head)->hh.tbl) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ + if (!(head)->hh.tbl->buckets) { \ + HASH_RECORD_OOM(oomed); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + } else { \ + uthash_bzero((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl, oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (oomed) { \ + uthash_free((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + } \ + ) \ + } \ + } \ +} while (0) -#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ - HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add) +#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ +} while (0) #define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ do { \ - replaced=NULL; \ - HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \ - if (replaced!=NULL) { \ - HASH_DELETE(hh,head,replaced); \ - }; \ - HASH_ADD(hh,head,fieldname,keylen_in,add); \ -} while(0) - + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ +} while (0) + +#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ +} while (0) + +#define HASH_APPEND_LIST(hh, head, add) \ +do { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail->next = (add); \ + (head)->hh.tbl->tail = &((add)->hh); \ +} while (0) + +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + do { \ + if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ + break; \ + } \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) + +#ifdef NO_DECLTYPE +#undef HASH_AKBI_INNER_LOOP +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + char *_hs_saved_head = (char*)(head); \ + do { \ + DECLTYPE_ASSIGN(head, _hs_iter); \ + if (cmpfcn(head, add) > 0) { \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + break; \ + } \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) +#endif + +#if HASH_NONFATAL_OOM + +#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ +do { \ + if (!(oomed)) { \ + unsigned _ha_bkt; \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ + if (oomed) { \ + HASH_ROLLBACK_BKT(hh, head, &(add)->hh); \ + HASH_DELETE_HH(hh, head, &(add)->hh); \ + (add)->hh.tbl = NULL; \ + uthash_nonfatal_oom(add); \ + } else { \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + } \ + } else { \ + (add)->hh.tbl = NULL; \ + uthash_nonfatal_oom(add); \ + } \ +} while (0) + +#else + +#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ +do { \ + unsigned _ha_bkt; \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ +} while (0) + +#endif + + +#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ +do { \ + IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh, add, _ha_oomed); \ + IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ + (head) = (add); \ + IF_HASH_NONFATAL_OOM( } ) \ + } else { \ + void *_hs_iter = (head); \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ + if (_hs_iter) { \ + (add)->hh.next = _hs_iter; \ + if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ + HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ + } else { \ + (head) = (add); \ + } \ + HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ + } else { \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + } \ + HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ +} while (0) + +#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ +do { \ + unsigned _hs_hashv; \ + HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) + +#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ + HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) + +#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ +do { \ + IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (const void*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh, add, _ha_oomed); \ + IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ + (head) = (add); \ + IF_HASH_NONFATAL_OOM( } ) \ + } else { \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ +} while (0) + #define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ do { \ - unsigned _ha_bkt; \ - (add)->hh.next = NULL; \ - (add)->hh.key = (char*)keyptr; \ - (add)->hh.keylen = (unsigned)keylen_in; \ - if (!(head)) { \ - head = (add); \ - (head)->hh.prev = NULL; \ - HASH_MAKE_TABLE(hh,head); \ - } else { \ - (head)->hh.tbl->tail->next = (add); \ - (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ - (head)->hh.tbl->tail = &((add)->hh); \ - } \ - (head)->hh.tbl->num_items++; \ - (add)->hh.tbl = (head)->hh.tbl; \ - HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ - (add)->hh.hashv, _ha_bkt); \ - HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ - HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ - HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ - HASH_FSCK(hh,head); \ -} while(0) + unsigned _ha_hashv; \ + HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ +} while (0) -#define HASH_TO_BKT( hashv, num_bkts, bkt ) \ +#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) + +#define HASH_TO_BKT(hashv,num_bkts,bkt) \ do { \ - bkt = ((hashv) & ((num_bkts) - 1)); \ -} while(0) + bkt = ((hashv) & ((num_bkts) - 1U)); \ +} while (0) /* delete "delptr" from the hash table. * "the usual" patch-up process for the app-order doubly-linked-list. @@ -213,48 +446,53 @@ do { * scratch pointer rather than through the repointed (users) symbol. */ #define HASH_DELETE(hh,head,delptr) \ -do { \ - unsigned _hd_bkt; \ - struct UT_hash_handle *_hd_hh_del; \ - if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ - uthash_free((head)->hh.tbl->buckets, \ - (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ - HASH_BLOOM_FREE((head)->hh.tbl); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - head = NULL; \ - } else { \ - _hd_hh_del = &((delptr)->hh); \ - if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ - (head)->hh.tbl->tail = \ - (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ - (head)->hh.tbl->hho); \ - } \ - if ((delptr)->hh.prev) { \ - ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ - (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ - } else { \ - DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ - } \ - if (_hd_hh_del->next) { \ - ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ - (head)->hh.tbl->hho))->prev = \ - _hd_hh_del->prev; \ - } \ - HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ - HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ - (head)->hh.tbl->num_items--; \ - } \ - HASH_FSCK(hh,head); \ -} while (0) + HASH_DELETE_HH(hh, head, &(delptr)->hh) +#define HASH_DELETE_HH(hh,head,delptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_del = (delptrhh); \ + if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } else { \ + unsigned _hd_bkt; \ + if (_hd_hh_del == (head)->hh.tbl->tail) { \ + (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ + } \ + if (_hd_hh_del->prev != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ + } else { \ + DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ + } \ + if (_hd_hh_del->next != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ + } \ + HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh, head, "HASH_DELETE_HH"); \ +} while (0) /* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ #define HASH_FIND_STR(head,findstr,out) \ - HASH_FIND(hh,head,findstr,strlen(findstr),out) +do { \ + unsigned _uthash_hfstr_keylen = (unsigned)uthash_strlen(findstr); \ + HASH_FIND(hh, head, findstr, _uthash_hfstr_keylen, out); \ +} while (0) #define HASH_ADD_STR(head,strfield,add) \ - HASH_ADD(hh,head,strfield,strlen(add->strfield),add) +do { \ + unsigned _uthash_hastr_keylen = (unsigned)uthash_strlen((add)->strfield); \ + HASH_ADD(hh, head, strfield[0], _uthash_hastr_keylen, add); \ +} while (0) #define HASH_REPLACE_STR(head,strfield,add,replaced) \ - HASH_REPLACE(hh,head,strfield,strlen(add->strfield),add,replaced) +do { \ + unsigned _uthash_hrstr_keylen = (unsigned)uthash_strlen((add)->strfield); \ + HASH_REPLACE(hh, head, strfield[0], _uthash_hrstr_keylen, add, replaced); \ +} while (0) #define HASH_FIND_INT(head,findint,out) \ HASH_FIND(hh,head,findint,sizeof(int),out) #define HASH_ADD_INT(head,intfield,add) \ @@ -265,7 +503,7 @@ do { HASH_FIND(hh,head,findptr,sizeof(void *),out) #define HASH_ADD_PTR(head,ptrfield,add) \ HASH_ADD(hh,head,ptrfield,sizeof(void *),add) -#define HASH_REPLACE_PTR(head,ptrfield,add) \ +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) #define HASH_DEL(head,delptr) \ HASH_DELETE(hh,head,delptr) @@ -274,120 +512,113 @@ do { * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. */ #ifdef HASH_DEBUG -#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) -#define HASH_FSCK(hh,head) \ +#include /* fprintf, stderr */ +#define HASH_OOPS(...) do { fprintf(stderr, __VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head,where) \ do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ unsigned _bkt_i; \ - unsigned _count, _bkt_count; \ + unsigned _count = 0; \ char *_prev; \ - struct UT_hash_handle *_thh; \ - if (head) { \ - _count = 0; \ - for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ - _bkt_count = 0; \ - _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ - _prev = NULL; \ - while (_thh) { \ - if (_prev != (char*)(_thh->hh_prev)) { \ - HASH_OOPS("invalid hh_prev %p, actual %p\n", \ - _thh->hh_prev, _prev ); \ - } \ - _bkt_count++; \ - _prev = (char*)(_thh); \ - _thh = _thh->hh_next; \ - } \ - _count += _bkt_count; \ - if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ - HASH_OOPS("invalid bucket count %d, actual %d\n", \ - (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ - } \ - } \ - if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("invalid hh item count %d, actual %d\n", \ - (head)->hh.tbl->num_items, _count ); \ - } \ - /* traverse hh in app order; check next/prev integrity, count */ \ - _count = 0; \ - _prev = NULL; \ - _thh = &(head)->hh; \ - while (_thh) { \ - _count++; \ - if (_prev !=(char*)(_thh->prev)) { \ - HASH_OOPS("invalid prev %p, actual %p\n", \ - _thh->prev, _prev ); \ - } \ - _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ - _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ - (head)->hh.tbl->hho) : NULL ); \ - } \ - if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("invalid app item count %d, actual %d\n", \ - (head)->hh.tbl->num_items, _count ); \ + for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ + (where), (void*)_thh->hh_prev, (void*)_prev); \ } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ + (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev != (char*)_thh->prev) { \ + HASH_OOPS("%s: invalid prev %p, actual %p\n", \ + (where), (void*)_thh->prev, (void*)_prev); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + } \ } while (0) #else -#define HASH_FSCK(hh,head) +#define HASH_FSCK(hh,head,where) #endif -/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to * the descriptor to which this macro is defined for tuning the hash function. * The app can #include to get the prototype for write(2). */ #ifdef HASH_EMIT_KEYS #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ do { \ - unsigned _klen = fieldlen; \ - write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ - write(HASH_EMIT_KEYS, keyptr, fieldlen); \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ } while (0) -#else -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) -#endif - -/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ -#ifdef HASH_FUNCTION -#define HASH_FCN HASH_FUNCTION #else -#define HASH_FCN HASH_JEN +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) #endif -/* The Bernstein hash function, used in Perl prior to v5.6 */ -#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,hashv) \ do { \ - unsigned _hb_keylen=keylen; \ - char *_hb_key=(char*)(key); \ + unsigned _hb_keylen = (unsigned)keylen; \ + const unsigned char *_hb_key = (const unsigned char*)(key); \ (hashv) = 0; \ - while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ - bkt = (hashv) & (num_bkts-1); \ + while (_hb_keylen-- != 0U) { \ + (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ + } \ } while (0) -/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ -#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ +#define HASH_SAX(key,keylen,hashv) \ do { \ unsigned _sx_i; \ - char *_hs_key=(char*)(key); \ + const unsigned char *_hs_key = (const unsigned char*)(key); \ hashv = 0; \ - for(_sx_i=0; _sx_i < keylen; _sx_i++) \ - hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ - bkt = hashv & (num_bkts-1); \ + for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + } \ } while (0) - -#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,hashv) \ do { \ unsigned _fn_i; \ - char *_hf_key=(char*)(key); \ - hashv = 2166136261UL; \ - for(_fn_i=0; _fn_i < keylen; _fn_i++) \ - hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ - bkt = hashv & (num_bkts-1); \ -} while(0) - -#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ + const unsigned char *_hf_key = (const unsigned char*)(key); \ + (hashv) = 2166136261U; \ + for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619U; \ + } \ +} while (0) + +#define HASH_OAT(key,keylen,hashv) \ do { \ unsigned _ho_i; \ - char *_ho_key=(char*)(key); \ + const unsigned char *_ho_key=(const unsigned char*)(key); \ hashv = 0; \ for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ hashv += _ho_key[_ho_i]; \ @@ -397,8 +628,7 @@ do { hashv += (hashv << 3); \ hashv ^= (hashv >> 11); \ hashv += (hashv << 15); \ - bkt = hashv & (num_bkts-1); \ -} while(0) +} while (0) #define HASH_JEN_MIX(a,b,c) \ do { \ @@ -413,14 +643,14 @@ do { c -= a; c -= b; c ^= ( b >> 15 ); \ } while (0) -#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ +#define HASH_JEN(key,keylen,hashv) \ do { \ unsigned _hj_i,_hj_j,_hj_k; \ - const unsigned char *_hj_key=(const unsigned char*)(key); \ - hashv = 0xfeedbeef; \ - _hj_i = _hj_j = 0x9e3779b9; \ - _hj_k = (unsigned)keylen; \ - while (_hj_k >= 12) { \ + unsigned const char *_hj_key=(unsigned const char*)(key); \ + hashv = 0xfeedbeefu; \ + _hj_i = _hj_j = 0x9e3779b9u; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12U) { \ _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + ( (unsigned)_hj_key[2] << 16 ) \ + ( (unsigned)_hj_key[3] << 24 ) ); \ @@ -434,25 +664,25 @@ do { HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ \ _hj_key += 12; \ - _hj_k -= 12; \ + _hj_k -= 12U; \ } \ - hashv += keylen; \ + hashv += (unsigned)(keylen); \ switch ( _hj_k ) { \ - case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ - case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ - case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ - case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ - case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ - case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ - case 5: _hj_j += _hj_key[4]; \ - case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ - case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ - case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ - case 1: _hj_i += _hj_key[0]; \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ + case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ + case 1: _hj_i += _hj_key[0]; /* FALLTHROUGH */ \ + default: ; \ } \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ - bkt = hashv & (num_bkts-1); \ -} while(0) +} while (0) /* The Paul Hsieh hash function */ #undef get16bits @@ -465,21 +695,21 @@ do { #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ +(uint32_t)(((const uint8_t *)(d))[0]) ) #endif -#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ +#define HASH_SFH(key,keylen,hashv) \ do { \ - unsigned char *_sfh_key=(unsigned char*)(key); \ - uint32_t _sfh_tmp, _sfh_len = keylen; \ + unsigned const char *_sfh_key=(unsigned const char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ \ - int _sfh_rem = _sfh_len & 3; \ + unsigned _sfh_rem = _sfh_len & 3U; \ _sfh_len >>= 2; \ - hashv = 0xcafebabe; \ + hashv = 0xcafebabeu; \ \ /* Main loop */ \ - for (;_sfh_len > 0; _sfh_len--) { \ + for (;_sfh_len > 0U; _sfh_len--) { \ hashv += get16bits (_sfh_key); \ - _sfh_tmp = (uint32_t)(get16bits (_sfh_key+2)) << 11 ^ hashv; \ + _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ hashv = (hashv << 16) ^ _sfh_tmp; \ - _sfh_key += 2*sizeof (uint16_t); \ + _sfh_key += 2U*sizeof (uint16_t); \ hashv += hashv >> 11; \ } \ \ @@ -487,7 +717,7 @@ do { switch (_sfh_rem) { \ case 3: hashv += get16bits (_sfh_key); \ hashv ^= hashv << 16; \ - hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18); \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ hashv += hashv >> 11; \ break; \ case 2: hashv += get16bits (_sfh_key); \ @@ -497,223 +727,163 @@ do { case 1: hashv += *_sfh_key; \ hashv ^= hashv << 10; \ hashv += hashv >> 1; \ + break; \ + default: ; \ } \ \ - /* Force "avalanching" of final 127 bits */ \ - hashv ^= hashv << 3; \ - hashv += hashv >> 5; \ - hashv ^= hashv << 4; \ - hashv += hashv >> 17; \ - hashv ^= hashv << 25; \ - hashv += hashv >> 6; \ - bkt = hashv & (num_bkts-1); \ -} while(0) - -#ifdef HASH_USING_NO_STRICT_ALIASING -/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. - * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. - * MurmurHash uses the faster approach only on CPU's where we know it's safe. - * - * Note the preprocessor built-in defines can be emitted using: - * - * gcc -m64 -dM -E - < /dev/null (on gcc) - * cc -## a.c (where a.c is a simple test file) (Sun Studio) - */ -#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) -#define MUR_GETBLOCK(p,i) p[i] -#else /* non intel */ -#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) -#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) -#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) -#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) -#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) -#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) -#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) -#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) -#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) -#else /* assume little endian non-intel */ -#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) -#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) -#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) -#endif -#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ - (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ - (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ - MUR_ONE_THREE(p)))) -#endif -#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) -#define MUR_FMIX(_h) \ -do { \ - _h ^= _h >> 16; \ - _h *= 0x85ebca6b; \ - _h ^= _h >> 13; \ - _h *= 0xc2b2ae35l; \ - _h ^= _h >> 16; \ -} while(0) - -#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ -do { \ - const uint8_t *_mur_data = (const uint8_t*)(key); \ - const int _mur_nblocks = (keylen) / 4; \ - uint32_t _mur_h1 = 0xf88D5353; \ - uint32_t _mur_c1 = 0xcc9e2d51; \ - uint32_t _mur_c2 = 0x1b873593; \ - uint32_t _mur_k1 = 0; \ - const uint8_t *_mur_tail; \ - const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ - int _mur_i; \ - for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ - _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ - _mur_k1 *= _mur_c1; \ - _mur_k1 = MUR_ROTL32(_mur_k1,15); \ - _mur_k1 *= _mur_c2; \ - \ - _mur_h1 ^= _mur_k1; \ - _mur_h1 = MUR_ROTL32(_mur_h1,13); \ - _mur_h1 = _mur_h1*5+0xe6546b64; \ - } \ - _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ - _mur_k1=0; \ - switch((keylen) & 3) { \ - case 3: _mur_k1 ^= _mur_tail[2] << 16; \ - case 2: _mur_k1 ^= _mur_tail[1] << 8; \ - case 1: _mur_k1 ^= _mur_tail[0]; \ - _mur_k1 *= _mur_c1; \ - _mur_k1 = MUR_ROTL32(_mur_k1,15); \ - _mur_k1 *= _mur_c2; \ - _mur_h1 ^= _mur_k1; \ - } \ - _mur_h1 ^= (keylen); \ - MUR_FMIX(_mur_h1); \ - hashv = _mur_h1; \ - bkt = hashv & (num_bkts-1); \ -} while(0) -#endif /* HASH_USING_NO_STRICT_ALIASING */ - -/* key comparison function; return 0 if keys equal */ -#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ +} while (0) /* iterate over items in a known bucket to find desired item */ -#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ do { \ - if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ - else out=NULL; \ - while (out) { \ - if ((out)->hh.keylen == keylen_in) { \ - if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \ + if ((head).hh_head != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ + } else { \ + (out) = NULL; \ + } \ + while ((out) != NULL) { \ + if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ + if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \ + break; \ + } \ } \ - if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \ - else out = NULL; \ - } \ -} while(0) + if ((out)->hh.hh_next != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ + } else { \ + (out) = NULL; \ + } \ + } \ +} while (0) /* add an item to a bucket */ -#define HASH_ADD_TO_BKT(head,addhh) \ +#define HASH_ADD_TO_BKT(head,hh,addhh,oomed) \ do { \ - head.count++; \ - (addhh)->hh_next = head.hh_head; \ - (addhh)->hh_prev = NULL; \ - if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ - (head).hh_head=addhh; \ - if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ - && (addhh)->tbl->noexpand != 1) { \ - HASH_EXPAND_BUCKETS((addhh)->tbl); \ - } \ -} while(0) + UT_hash_bucket *_ha_head = &(head); \ + _ha_head->count++; \ + (addhh)->hh_next = _ha_head->hh_head; \ + (addhh)->hh_prev = NULL; \ + if (_ha_head->hh_head != NULL) { \ + _ha_head->hh_head->hh_prev = (addhh); \ + } \ + _ha_head->hh_head = (addhh); \ + if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ + && !(addhh)->tbl->noexpand) { \ + HASH_EXPAND_BUCKETS(addhh,(addhh)->tbl, oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (oomed) { \ + HASH_DEL_IN_BKT(head,addhh); \ + } \ + ) \ + } \ +} while (0) /* remove an item from a given bucket */ -#define HASH_DEL_IN_BKT(hh,head,hh_del) \ - (head).count--; \ - if ((head).hh_head == hh_del) { \ - (head).hh_head = hh_del->hh_next; \ - } \ - if (hh_del->hh_prev) { \ - hh_del->hh_prev->hh_next = hh_del->hh_next; \ - } \ - if (hh_del->hh_next) { \ - hh_del->hh_next->hh_prev = hh_del->hh_prev; \ - } +#define HASH_DEL_IN_BKT(head,delhh) \ +do { \ + UT_hash_bucket *_hd_head = &(head); \ + _hd_head->count--; \ + if (_hd_head->hh_head == (delhh)) { \ + _hd_head->hh_head = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_prev) { \ + (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_next) { \ + (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ + } \ +} while (0) /* Bucket expansion has the effect of doubling the number of buckets * and redistributing the items into the new buckets. Ideally the * items will distribute more or less evenly into the new buckets * (the extent to which this is true is a measure of the quality of - * the hash function as it applies to the key domain). - * + * the hash function as it applies to the key domain). + * * With the items distributed into more buckets, the chain length * (item count) in each bucket is reduced. Thus by expanding buckets - * the hash keeps a bound on the chain length. This bounded chain + * the hash keeps a bound on the chain length. This bounded chain * length is the essence of how a hash provides constant time lookup. - * + * * The calculation of tbl->ideal_chain_maxlen below deserves some * explanation. First, keep in mind that we're calculating the ideal * maximum chain length based on the *new* (doubled) bucket count. * In fractions this is just n/b (n=number of items,b=new num buckets). - * Since the ideal chain length is an integer, we want to calculate + * Since the ideal chain length is an integer, we want to calculate * ceil(n/b). We don't depend on floating point arithmetic in this * hash, so to calculate ceil(n/b) with integers we could write - * + * * ceil(n/b) = (n/b) + ((n%b)?1:0) - * + * * and in fact a previous version of this hash did just that. * But now we have improved things a bit by recognizing that b is * always a power of two. We keep its base 2 log handy (call it lb), * so now we can write this with a bit shift and logical AND: - * + * * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) - * + * */ -#define HASH_EXPAND_BUCKETS(tbl) \ +#define HASH_EXPAND_BUCKETS(hh,tbl,oomed) \ do { \ - unsigned _he_bkt; \ - unsigned _he_bkt_i; \ - struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ - UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ - _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ - 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ - if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ - memset(_he_new_buckets, 0, \ - 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ - tbl->ideal_chain_maxlen = \ - (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ - ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ - tbl->nonideal_items = 0; \ - for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ - { \ - _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ - while (_he_thh) { \ - _he_hh_nxt = _he_thh->hh_next; \ - HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ - _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ - if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ - tbl->nonideal_items++; \ - _he_newbkt->expand_mult = _he_newbkt->count / \ - tbl->ideal_chain_maxlen; \ - } \ - _he_thh->hh_prev = NULL; \ - _he_thh->hh_next = _he_newbkt->hh_head; \ - if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ - _he_thh; \ - _he_newbkt->hh_head = _he_thh; \ - _he_thh = _he_hh_nxt; \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \ + if (!_he_new_buckets) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero(_he_new_buckets, \ + sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \ + (tbl)->ideal_chain_maxlen = \ + ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ + ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ + (tbl)->nonideal_items = 0; \ + for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ + _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh != NULL) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[_he_bkt]); \ + if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ + (tbl)->nonideal_items++; \ + if (_he_newbkt->count > _he_newbkt->expand_mult * (tbl)->ideal_chain_maxlen) { \ + _he_newbkt->expand_mult++; \ + } \ } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head != NULL) { \ + _he_newbkt->hh_head->hh_prev = _he_thh; \ + } \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ } \ - uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ - tbl->num_buckets *= 2; \ - tbl->log2_num_buckets++; \ - tbl->buckets = _he_new_buckets; \ - tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ - (tbl->ineff_expands+1) : 0; \ - if (tbl->ineff_expands > 1) { \ - tbl->noexpand=1; \ - uthash_noexpand_fyi(tbl); \ + uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->num_buckets *= 2U; \ + (tbl)->log2_num_buckets++; \ + (tbl)->buckets = _he_new_buckets; \ + (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ + ((tbl)->ineff_expands+1U) : 0U; \ + if ((tbl)->ineff_expands > 1U) { \ + (tbl)->noexpand = 1; \ + uthash_noexpand_fyi(tbl); \ } \ uthash_expand_fyi(tbl); \ -} while(0) + } \ +} while (0) /* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ -/* Note that HASH_SORT assumes the hash handle name to be hh. +/* Note that HASH_SORT assumes the hash handle name to be hh. * HASH_SRT was added to allow the hash handle name to be passed in. */ #define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) #define HASH_SRT(hh,head,cmpfcn) \ @@ -721,153 +891,179 @@ do { unsigned _hs_i; \ unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ - if (head) { \ - _hs_insize = 1; \ - _hs_looping = 1; \ - _hs_list = &((head)->hh); \ - while (_hs_looping) { \ - _hs_p = _hs_list; \ - _hs_list = NULL; \ - _hs_tail = NULL; \ - _hs_nmerges = 0; \ - while (_hs_p) { \ - _hs_nmerges++; \ - _hs_q = _hs_p; \ - _hs_psize = 0; \ - for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ - _hs_psize++; \ - _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ - ((void*)((char*)(_hs_q->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - if (! (_hs_q) ) break; \ - } \ - _hs_qsize = _hs_insize; \ - while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ - if (_hs_psize == 0) { \ - _hs_e = _hs_q; \ - _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ - ((void*)((char*)(_hs_q->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_qsize--; \ - } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ - _hs_e = _hs_p; \ - _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ - ((void*)((char*)(_hs_p->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_psize--; \ - } else if (( \ - cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ - DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ - ) <= 0) { \ - _hs_e = _hs_p; \ - _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ - ((void*)((char*)(_hs_p->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_psize--; \ - } else { \ - _hs_e = _hs_q; \ - _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ - ((void*)((char*)(_hs_q->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_qsize--; \ - } \ - if ( _hs_tail ) { \ - _hs_tail->next = ((_hs_e) ? \ - ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ - } else { \ - _hs_list = _hs_e; \ - } \ - _hs_e->prev = ((_hs_tail) ? \ - ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ - _hs_tail = _hs_e; \ - } \ - _hs_p = _hs_q; \ + if (head != NULL) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping != 0U) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p != NULL) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ + _hs_psize++; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + if (_hs_q == NULL) { \ + break; \ } \ - _hs_tail->next = NULL; \ - if ( _hs_nmerges <= 1 ) { \ - _hs_looping=0; \ - (head)->hh.tbl->tail = _hs_tail; \ - DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ + if (_hs_psize == 0U) { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else if ((cmpfcn( \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ + )) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ } \ - _hs_insize *= 2; \ + if ( _hs_tail != NULL ) { \ + _hs_tail->next = ((_hs_e != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e != NULL) { \ + _hs_e->prev = ((_hs_tail != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ } \ - HASH_FSCK(hh,head); \ - } \ + if (_hs_tail != NULL) { \ + _hs_tail->next = NULL; \ + } \ + if (_hs_nmerges <= 1U) { \ + _hs_looping = 0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2U; \ + } \ + HASH_FSCK(hh, head, "HASH_SRT"); \ + } \ } while (0) -/* This function selects items from one hash into another hash. - * The end result is that the selected items have dual presence - * in both hashes. There is no copy of the items made; rather - * they are added into the new hash through a secondary hash +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash * hash handle that must be present in the structure. */ #define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ do { \ unsigned _src_bkt, _dst_bkt; \ - void *_last_elt=NULL, *_elt; \ + void *_last_elt = NULL, *_elt; \ UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ - if (src) { \ - for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ - for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ - _src_hh; \ - _src_hh = _src_hh->hh_next) { \ - _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ - if (cond(_elt)) { \ - _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ - _dst_hh->key = _src_hh->key; \ - _dst_hh->keylen = _src_hh->keylen; \ - _dst_hh->hashv = _src_hh->hashv; \ - _dst_hh->prev = _last_elt; \ - _dst_hh->next = NULL; \ - if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ - if (!dst) { \ - DECLTYPE_ASSIGN(dst,_elt); \ - HASH_MAKE_TABLE(hh_dst,dst); \ - } else { \ - _dst_hh->tbl = (dst)->hh_dst.tbl; \ - } \ - HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ - HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ - (dst)->hh_dst.tbl->num_items++; \ - _last_elt = _elt; \ - _last_elt_hh = _dst_hh; \ + if ((src) != NULL) { \ + for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh != NULL; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \ + _dst_hh = (UT_hash_handle*)(void*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh != NULL) { \ + _last_elt_hh->next = _elt; \ } \ + if ((dst) == NULL) { \ + DECLTYPE_ASSIGN(dst, _elt); \ + HASH_MAKE_TABLE(hh_dst, dst, _hs_oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (_hs_oomed) { \ + uthash_nonfatal_oom(_elt); \ + (dst) = NULL; \ + continue; \ + } \ + ) \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], hh_dst, _dst_hh, _hs_oomed); \ + (dst)->hh_dst.tbl->num_items++; \ + IF_HASH_NONFATAL_OOM( \ + if (_hs_oomed) { \ + HASH_ROLLBACK_BKT(hh_dst, dst, _dst_hh); \ + HASH_DELETE_HH(hh_dst, dst, _dst_hh); \ + _dst_hh->tbl = NULL; \ + uthash_nonfatal_oom(_elt); \ + continue; \ + } \ + ) \ + HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ } \ } \ } \ - HASH_FSCK(hh_dst,dst); \ + HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ } while (0) #define HASH_CLEAR(hh,head) \ do { \ - if (head) { \ + if ((head) != NULL) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ uthash_free((head)->hh.tbl->buckets, \ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ - HASH_BLOOM_FREE((head)->hh.tbl); \ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - (head)=NULL; \ + (head) = NULL; \ } \ -} while(0) +} while (0) #define HASH_OVERHEAD(hh,head) \ - (size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ - ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ - (sizeof(UT_hash_table)) + \ - (HASH_BLOOM_BYTELEN))) + (((head) != NULL) ? ( \ + (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + sizeof(UT_hash_table) + \ + (HASH_BLOOM_BYTELEN))) : 0U) #ifdef NO_DECLTYPE #define HASH_ITER(hh,head,el,tmp) \ -for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ - el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) +for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) #else #define HASH_ITER(hh,head,el,tmp) \ -for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ - el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) +for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) #endif /* obtain a count of items in the hash */ -#define HASH_COUNT(head) HASH_CNT(hh,head) -#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) typedef struct UT_hash_bucket { struct UT_hash_handle *hh_head; @@ -875,7 +1071,7 @@ typedef struct UT_hash_bucket { /* expand_mult is normally set to 0. In this situation, the max chain length * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If - * the bucket's chain exceeds this length, bucket expansion is triggered). + * the bucket's chain exceeds this length, bucket expansion is triggered). * However, setting expand_mult to a non-zero value delays bucket expansion * (that would be triggered by additions to this particular bucket) * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. @@ -883,15 +1079,15 @@ typedef struct UT_hash_bucket { * multiplier is to reduce bucket expansions, since they are expensive, in * situations where we know that a particular bucket tends to be overused. * It is better to let its chain length grow to a longer yet-still-bounded - * value, than to do an O(n) bucket expansion too often. + * value, than to do an O(n) bucket expansion too often. */ unsigned expand_mult; } UT_hash_bucket; /* random signature used only to find hash tables in external analysis */ -#define HASH_SIGNATURE 0xa0111fe1 -#define HASH_BLOOM_SIGNATURE 0xb12220f2 +#define HASH_SIGNATURE 0xa0111fe1u +#define HASH_BLOOM_SIGNATURE 0xb12220f2u typedef struct UT_hash_table { UT_hash_bucket *buckets; @@ -909,7 +1105,7 @@ typedef struct UT_hash_table { * hash distribution; reaching them in a chain traversal takes >ideal steps */ unsigned nonideal_items; - /* ineffective expands occur when a bucket doubling was performed, but + /* ineffective expands occur when a bucket doubling was performed, but * afterward, more than half the items in the hash had nonideal chain * positions. If this happens on two consecutive expansions we inhibit any * further expansion, as it's not helping; this happens when the hash @@ -921,7 +1117,7 @@ typedef struct UT_hash_table { #ifdef HASH_BLOOM uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ uint8_t *bloom_bv; - char bloom_nbits; + uint8_t bloom_nbits; #endif } UT_hash_table; @@ -932,7 +1128,7 @@ typedef struct UT_hash_handle { void *next; /* next element in app order */ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ struct UT_hash_handle *hh_next; /* next hh in bucket order */ - void *key; /* ptr to enclosing struct's key */ + const void *key; /* ptr to enclosing struct's key */ unsigned keylen; /* enclosing struct's key len */ unsigned hashv; /* result of hash-fcn(key) */ } UT_hash_handle; diff --git a/src/util/uthash/src/utlist.h b/src/util/uthash/src/utlist.h index 8d845dc..6230a67 100644 --- a/src/util/uthash/src/utlist.h +++ b/src/util/uthash/src/utlist.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2007-2013, Troy D. Hanson http://troydhanson.github.com/uthash/ +Copyright (c) 2007-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without @@ -24,11 +24,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef UTLIST_H #define UTLIST_H -#define UTLIST_VERSION 1.9.8 +#define UTLIST_VERSION 2.3.0 #include -/* +/* * This file contains macros to manipulate singly and doubly-linked lists. * * 1. LL_ macros: singly-linked lists. @@ -38,7 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * To use singly-linked lists, your structure must have a "next" pointer. * To use doubly-linked lists, your structure must "prev" and "next" pointers. * Either way, the pointer to the head of the list must be initialized to NULL. - * + * * ----------------.EXAMPLE ------------------------- * struct item { * int id; @@ -61,41 +61,44 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* These macros use decltype or the earlier __typeof GNU extension. As decltype is only available in newer compilers (VS2010 or gcc 4.3+ - when compiling c++ code), this code uses whatever method is needed + when compiling c++ source) this code uses whatever method is needed or, for VS2008 where neither is available, uses casting workarounds. */ -#ifdef _MSC_VER /* MS compiler */ +#if !defined(LDECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ #if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ #define LDECLTYPE(x) decltype(x) -#else /* VS2008 or older (or VS2010 in C mode) */ +#else /* VS2008 or older (or VS2010 in C mode) */ #define NO_DECLTYPE -#define LDECLTYPE(x) char* #endif -#elif defined(__ICCARM__) +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) #define NO_DECLTYPE -#define LDECLTYPE(x) char* -#else /* GNU, Sun and other compilers */ +#else /* GNU, Sun and other compilers */ #define LDECLTYPE(x) __typeof(x) #endif +#endif /* for VS2008 we use some workarounds to get around the lack of decltype, * namely, we always reassign our tmp variable to the list head if we need * to dereference its prev/next pointers, and save/restore the real head.*/ #ifdef NO_DECLTYPE -#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } -#define _NEXT(elt,list,next) ((char*)((list)->next)) -#define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } -/* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */ -#define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } -#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } -#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } -#else -#define _SV(elt,list) -#define _NEXT(elt,list,next) ((elt)->next) -#define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to) -/* #define _PREV(elt,list,prev) ((elt)->prev) */ -#define _PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) -#define _RS(list) -#define _CASTASGN(a,b) (a)=(b) +#define IF_NO_DECLTYPE(x) x +#define LDECLTYPE(x) char* +#define UTLIST_SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } +#define UTLIST_NEXT(elt,list,next) ((char*)((list)->next)) +#define UTLIST_NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } +/* #define UTLIST_PREV(elt,list,prev) ((char*)((list)->prev)) */ +#define UTLIST_PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } +#define UTLIST_RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } +#define UTLIST_CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } +#else +#define IF_NO_DECLTYPE(x) +#define UTLIST_SV(elt,list) +#define UTLIST_NEXT(elt,list,next) ((elt)->next) +#define UTLIST_NEXTASGN(elt,list,to,next) ((elt)->next)=(to) +/* #define UTLIST_PREV(elt,list,prev) ((elt)->prev) */ +#define UTLIST_PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) +#define UTLIST_RS(list) +#define UTLIST_CASTASGN(a,b) (a)=(b) #endif /****************************************************************************** @@ -111,13 +114,14 @@ do { LDECLTYPE(list) _ls_q; \ LDECLTYPE(list) _ls_e; \ LDECLTYPE(list) _ls_tail; \ + IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ if (list) { \ _ls_insize = 1; \ _ls_looping = 1; \ while (_ls_looping) { \ - _CASTASGN(_ls_p,list); \ - list = NULL; \ + UTLIST_CASTASGN(_ls_p,list); \ + (list) = NULL; \ _ls_tail = NULL; \ _ls_nmerges = 0; \ while (_ls_p) { \ @@ -126,35 +130,35 @@ do { _ls_psize = 0; \ for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ _ls_psize++; \ - _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ + UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ if (!_ls_q) break; \ } \ _ls_qsize = _ls_insize; \ while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ if (_ls_psize == 0) { \ - _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ - _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ } else if (_ls_qsize == 0 || !_ls_q) { \ - _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ - _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ } else if (cmp(_ls_p,_ls_q) <= 0) { \ - _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ - _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ } else { \ - _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ - _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ } \ if (_ls_tail) { \ - _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ } else { \ - _CASTASGN(list,_ls_e); \ + UTLIST_CASTASGN(list,_ls_e); \ } \ _ls_tail = _ls_e; \ } \ _ls_p = _ls_q; \ } \ if (_ls_tail) { \ - _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ } \ if (_ls_nmerges <= 1) { \ _ls_looping=0; \ @@ -174,13 +178,14 @@ do { LDECLTYPE(list) _ls_q; \ LDECLTYPE(list) _ls_e; \ LDECLTYPE(list) _ls_tail; \ + IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ if (list) { \ _ls_insize = 1; \ _ls_looping = 1; \ while (_ls_looping) { \ - _CASTASGN(_ls_p,list); \ - list = NULL; \ + UTLIST_CASTASGN(_ls_p,list); \ + (list) = NULL; \ _ls_tail = NULL; \ _ls_nmerges = 0; \ while (_ls_p) { \ @@ -189,36 +194,36 @@ do { _ls_psize = 0; \ for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ _ls_psize++; \ - _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ + UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ if (!_ls_q) break; \ } \ _ls_qsize = _ls_insize; \ - while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) { \ if (_ls_psize == 0) { \ - _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ - _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ - } else if (_ls_qsize == 0 || !_ls_q) { \ - _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ - _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } else if ((_ls_qsize == 0) || (!_ls_q)) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ } else if (cmp(_ls_p,_ls_q) <= 0) { \ - _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ - _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ } else { \ - _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ - _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ } \ if (_ls_tail) { \ - _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ } else { \ - _CASTASGN(list,_ls_e); \ + UTLIST_CASTASGN(list,_ls_e); \ } \ - _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ + UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ _ls_tail = _ls_e; \ } \ _ls_p = _ls_q; \ } \ - _CASTASGN(list->prev, _ls_tail); \ - _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ + UTLIST_CASTASGN((list)->prev, _ls_tail); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ if (_ls_nmerges <= 1) { \ _ls_looping=0; \ } \ @@ -243,9 +248,9 @@ do { _ls_insize = 1; \ _ls_looping = 1; \ while (_ls_looping) { \ - _CASTASGN(_ls_p,list); \ - _CASTASGN(_ls_oldhead,list); \ - list = NULL; \ + UTLIST_CASTASGN(_ls_p,list); \ + UTLIST_CASTASGN(_ls_oldhead,list); \ + (list) = NULL; \ _ls_tail = NULL; \ _ls_nmerges = 0; \ while (_ls_p) { \ @@ -254,47 +259,47 @@ do { _ls_psize = 0; \ for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ _ls_psize++; \ - _SV(_ls_q,list); \ - if (_NEXT(_ls_q,list,next) == _ls_oldhead) { \ + UTLIST_SV(_ls_q,list); \ + if (UTLIST_NEXT(_ls_q,list,next) == _ls_oldhead) { \ _ls_q = NULL; \ } else { \ - _ls_q = _NEXT(_ls_q,list,next); \ + _ls_q = UTLIST_NEXT(_ls_q,list,next); \ } \ - _RS(list); \ + UTLIST_RS(list); \ if (!_ls_q) break; \ } \ _ls_qsize = _ls_insize; \ while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ if (_ls_psize == 0) { \ - _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ - _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ } else if (_ls_qsize == 0 || !_ls_q) { \ - _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ - _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ } else if (cmp(_ls_p,_ls_q) <= 0) { \ - _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ - _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ } else { \ - _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ - _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ } \ if (_ls_tail) { \ - _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ } else { \ - _CASTASGN(list,_ls_e); \ + UTLIST_CASTASGN(list,_ls_e); \ } \ - _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ + UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ _ls_tail = _ls_e; \ } \ _ls_p = _ls_q; \ } \ - _CASTASGN(list->prev,_ls_tail); \ - _CASTASGN(_tmp,list); \ - _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp,next); _RS(list); \ + UTLIST_CASTASGN((list)->prev,_ls_tail); \ + UTLIST_CASTASGN(_tmp,list); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_tmp,next); UTLIST_RS(list); \ if (_ls_nmerges <= 1) { \ _ls_looping=0; \ } \ @@ -311,8 +316,8 @@ do { #define LL_PREPEND2(head,add,next) \ do { \ - (add)->next = head; \ - head = add; \ + (add)->next = (head); \ + (head) = (add); \ } while (0) #define LL_CONCAT(head1,head2) \ @@ -322,7 +327,7 @@ do { do { \ LDECLTYPE(head1) _tmp; \ if (head1) { \ - _tmp = head1; \ + _tmp = (head1); \ while (_tmp->next) { _tmp = _tmp->next; } \ _tmp->next=(head2); \ } else { \ @@ -338,7 +343,7 @@ do { LDECLTYPE(head) _tmp; \ (add)->next=NULL; \ if (head) { \ - _tmp = head; \ + _tmp = (head); \ while (_tmp->next) { _tmp = _tmp->next; } \ _tmp->next=(add); \ } else { \ @@ -346,6 +351,37 @@ do { } \ } while (0) +#define LL_INSERT_INORDER(head,add,cmp) \ + LL_INSERT_INORDER2(head,add,cmp,next) + +#define LL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + LL_LOWER_BOUND2(head, _tmp, add, cmp, next); \ + LL_APPEND_ELEM2(head, _tmp, add, next); \ + } else { \ + (head) = (add); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define LL_LOWER_BOUND(head,elt,like,cmp) \ + LL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define LL_LOWER_BOUND2(head,elt,like,cmp,next) \ + do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ + if (cmp((elt)->next, like) >= 0) { \ + break; \ + } \ + } \ + } \ + } while (0) + #define LL_DELETE(head,del) \ LL_DELETE2(head,del,next) @@ -355,21 +391,140 @@ do { if ((head) == (del)) { \ (head)=(head)->next; \ } else { \ - _tmp = head; \ + _tmp = (head); \ while (_tmp->next && (_tmp->next != (del))) { \ _tmp = _tmp->next; \ } \ if (_tmp->next) { \ - _tmp->next = ((del)->next); \ + _tmp->next = (del)->next; \ } \ } \ } while (0) -/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ -#define LL_APPEND_VS2008(head,add) \ - LL_APPEND2_VS2008(head,add,next) +#define LL_COUNT(head,el,counter) \ + LL_COUNT2(head,el,counter,next) \ -#define LL_APPEND2_VS2008(head,add,next) \ +#define LL_COUNT2(head,el,counter,next) \ +do { \ + (counter) = 0; \ + LL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) + +#define LL_FOREACH(head,el) \ + LL_FOREACH2(head,el,next) + +#define LL_FOREACH2(head,el,next) \ + for ((el) = (head); el; (el) = (el)->next) + +#define LL_FOREACH_SAFE(head,el,tmp) \ + LL_FOREACH_SAFE2(head,el,tmp,next) + +#define LL_FOREACH_SAFE2(head,el,tmp,next) \ + for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) + +#define LL_SEARCH_SCALAR(head,out,field,val) \ + LL_SEARCH_SCALAR2(head,out,field,val,next) + +#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while (0) + +#define LL_SEARCH(head,out,elt,cmp) \ + LL_SEARCH2(head,out,elt,cmp,next) + +#define LL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while (0) + +#define LL_REPLACE_ELEM2(head, el, add, next) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) + +#define LL_REPLACE_ELEM(head, el, add) \ + LL_REPLACE_ELEM2(head, el, add, next) + +#define LL_PREPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + LDECLTYPE(head) _tmp; \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ + } else { \ + LL_APPEND2(head, add, next); \ + } \ +} while (0) \ + +#define LL_PREPEND_ELEM(head, el, add) \ + LL_PREPEND_ELEM2(head, el, add, next) + +#define LL_APPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (el)->next = (add); \ + } else { \ + LL_PREPEND2(head, add, next); \ + } \ +} while (0) \ + +#define LL_APPEND_ELEM(head, el, add) \ + LL_APPEND_ELEM2(head, el, add, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef LL_CONCAT2 +#define LL_CONCAT2(head1,head2,next) \ +do { \ + char *_tmp; \ + if (head1) { \ + _tmp = (char*)(head1); \ + while ((head1)->next) { (head1) = (head1)->next; } \ + (head1)->next = (head2); \ + UTLIST_RS(head1); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#undef LL_APPEND2 +#define LL_APPEND2(head,add,next) \ do { \ if (head) { \ (add)->next = head; /* use add->next as a temp variable */ \ @@ -381,113 +536,84 @@ do { (add)->next=NULL; \ } while (0) -#define LL_DELETE_VS2008(head,del) \ - LL_DELETE2_VS2008(head,del,next) +#undef LL_INSERT_INORDER2 +#define LL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, add)) >= 0) { \ + (add)->next = (head); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next != NULL && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->next = (head)->next; \ + (head)->next = (add); \ + UTLIST_RS(head); \ + } \ +} while (0) -#define LL_DELETE2_VS2008(head,del,next) \ +#undef LL_DELETE2 +#define LL_DELETE2(head,del,next) \ do { \ if ((head) == (del)) { \ (head)=(head)->next; \ } else { \ char *_tmp = (char*)(head); \ while ((head)->next && ((head)->next != (del))) { \ - head = (head)->next; \ + (head) = (head)->next; \ } \ if ((head)->next) { \ (head)->next = ((del)->next); \ } \ - { \ - char **_head_alias = (char**)&(head); \ - *_head_alias = _tmp; \ - } \ + UTLIST_RS(head); \ } \ } while (0) -#ifdef NO_DECLTYPE -#undef LL_APPEND -#define LL_APPEND LL_APPEND_VS2008 -#undef LL_DELETE -#define LL_DELETE LL_DELETE_VS2008 -#undef LL_DELETE2 -#define LL_DELETE2 LL_DELETE2_VS2008 -#undef LL_APPEND2 -#define LL_APPEND2 LL_APPEND2_VS2008 -#undef LL_CONCAT /* no LL_CONCAT_VS2008 */ -#undef DL_CONCAT /* no DL_CONCAT_VS2008 */ -#endif -/* end VS2008 replacements */ -#define LL_FOREACH(head,el) \ - LL_FOREACH2(head,el,next) - -#define LL_FOREACH2(head,el,next) \ - for(el=head;el;el=(el)->next) - -#define LL_FOREACH_SAFE(head,el,tmp) \ - LL_FOREACH_SAFE2(head,el,tmp,next) - -#define LL_FOREACH_SAFE2(head,el,tmp,next) \ - for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) - -#define LL_SEARCH_SCALAR(head,out,field,val) \ - LL_SEARCH_SCALAR2(head,out,field,val,next) - -#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ +#undef LL_REPLACE_ELEM2 +#define LL_REPLACE_ELEM2(head, el, add, next) \ do { \ - LL_FOREACH2(head,out,next) { \ - if ((out)->field == (val)) break; \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->next = head; \ + while ((add)->next->next && ((add)->next->next != (el))) { \ + (add)->next = (add)->next->next; \ } \ -} while(0) - -#define LL_SEARCH(head,out,elt,cmp) \ - LL_SEARCH2(head,out,elt,cmp,next) - -#define LL_SEARCH2(head,out,elt,cmp,next) \ -do { \ - LL_FOREACH2(head,out,next) { \ - if ((cmp(out,elt))==0) break; \ + if ((add)->next->next) { \ + (add)->next->next = (add); \ } \ -} while(0) - -#define LL_REPLACE_ELEM(head, el, add) \ -do { \ - LDECLTYPE(head) _tmp; \ - assert(head != NULL); \ - assert(el != NULL); \ - assert(add != NULL); \ - (add)->next = (el)->next; \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - _tmp = head; \ - while (_tmp->next && (_tmp->next != (el))) { \ - _tmp = _tmp->next; \ } \ - if (_tmp->next) { \ - _tmp->next = (add); \ - } \ - } \ + (add)->next = (el)->next; \ } while (0) -#define LL_PREPEND_ELEM(head, el, add) \ +#undef LL_PREPEND_ELEM2 +#define LL_PREPEND_ELEM2(head, el, add, next) \ do { \ - LDECLTYPE(head) _tmp; \ - assert(head != NULL); \ - assert(el != NULL); \ - assert(add != NULL); \ - (add)->next = (el); \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - _tmp = head; \ - while (_tmp->next && (_tmp->next != (el))) { \ - _tmp = _tmp->next; \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->next = (head); \ + while ((add)->next->next && ((add)->next->next != (el))) { \ + (add)->next = (add)->next->next; \ + } \ + if ((add)->next->next) { \ + (add)->next->next = (add); \ + } \ + } \ + (add)->next = (el); \ + } else { \ + LL_APPEND2(head, add, next); \ } \ - if (_tmp->next) { \ - _tmp->next = (add); \ - } \ - } \ } while (0) \ +#endif /* NO_DECLTYPE */ /****************************************************************************** * doubly linked list macros (non-circular) * @@ -497,7 +623,7 @@ do { #define DL_PREPEND2(head,add,prev,next) \ do { \ - (add)->next = head; \ + (add)->next = (head); \ if (head) { \ (add)->prev = (head)->prev; \ (head)->prev = (add); \ @@ -522,7 +648,39 @@ do { (head)->prev = (head); \ (head)->next = NULL; \ } \ -} while (0) +} while (0) + +#define DL_INSERT_INORDER(head,add,cmp) \ + DL_INSERT_INORDER2(head,add,cmp,prev,next) + +#define DL_INSERT_INORDER2(head,add,cmp,prev,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + DL_LOWER_BOUND2(head, _tmp, add, cmp, next); \ + DL_APPEND_ELEM2(head, _tmp, add, prev, next); \ + } else { \ + (head) = (add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_LOWER_BOUND(head,elt,like,cmp) \ + DL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define DL_LOWER_BOUND2(head,elt,like,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ + if ((cmp((elt)->next, like)) >= 0) { \ + break; \ + } \ + } \ + } \ +} while (0) #define DL_CONCAT(head1,head2) \ DL_CONCAT2(head1,head2,prev,next) @@ -532,21 +690,22 @@ do { LDECLTYPE(head1) _tmp; \ if (head2) { \ if (head1) { \ - _tmp = (head2)->prev; \ + UTLIST_CASTASGN(_tmp, (head2)->prev); \ (head2)->prev = (head1)->prev; \ (head1)->prev->next = (head2); \ - (head1)->prev = _tmp; \ + UTLIST_CASTASGN((head1)->prev, _tmp); \ } else { \ (head1)=(head2); \ } \ } \ -} while (0) +} while (0) #define DL_DELETE(head,del) \ DL_DELETE2(head,del,prev,next) #define DL_DELETE2(head,del,prev,next) \ do { \ + assert((head) != NULL); \ assert((del)->prev != NULL); \ if ((del)->prev == (del)) { \ (head)=NULL; \ @@ -561,21 +720,29 @@ do { (head)->prev = (del)->prev; \ } \ } \ -} while (0) +} while (0) +#define DL_COUNT(head,el,counter) \ + DL_COUNT2(head,el,counter,next) \ + +#define DL_COUNT2(head,el,counter,next) \ +do { \ + (counter) = 0; \ + DL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) #define DL_FOREACH(head,el) \ DL_FOREACH2(head,el,next) #define DL_FOREACH2(head,el,next) \ - for(el=head;el;el=(el)->next) + for ((el) = (head); el; (el) = (el)->next) /* this version is safe for deleting the elements during iteration */ #define DL_FOREACH_SAFE(head,el,tmp) \ DL_FOREACH_SAFE2(head,el,tmp,next) #define DL_FOREACH_SAFE2(head,el,tmp,next) \ - for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) /* these are identical to their singly-linked list counterparts */ #define DL_SEARCH_SCALAR LL_SEARCH_SCALAR @@ -583,11 +750,11 @@ do { #define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 #define DL_SEARCH2 LL_SEARCH2 -#define DL_REPLACE_ELEM(head, el, add) \ +#define DL_REPLACE_ELEM2(head, el, add, prev, next) \ do { \ - assert(head != NULL); \ - assert(el != NULL); \ - assert(add != NULL); \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ if ((head) == (el)) { \ (head) = (add); \ (add)->next = (el)->next; \ @@ -609,25 +776,104 @@ do { } \ } while (0) -#define DL_PREPEND_ELEM(head, el, add) \ +#define DL_REPLACE_ELEM(head, el, add) \ + DL_REPLACE_ELEM2(head, el, add, prev, next) + +#define DL_PREPEND_ELEM2(head, el, add, prev, next) \ do { \ - assert(head != NULL); \ - assert(el != NULL); \ - assert(add != NULL); \ - (add)->next = (el); \ - (add)->prev = (el)->prev; \ - (el)->prev = (add); \ - if ((head) == (el)) { \ - (head) = (add); \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->prev->next = (add); \ + } \ } else { \ - (add)->prev->next = (add); \ + DL_APPEND2(head, add, prev, next); \ } \ } while (0) \ +#define DL_PREPEND_ELEM(head, el, add) \ + DL_PREPEND_ELEM2(head, el, add, prev, next) + +#define DL_APPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (add)->prev = (el); \ + (el)->next = (add); \ + if ((add)->next) { \ + (add)->next->prev = (add); \ + } else { \ + (head)->prev = (add); \ + } \ + } else { \ + DL_PREPEND2(head, add, prev, next); \ + } \ +} while (0) \ + +#define DL_APPEND_ELEM(head, el, add) \ + DL_APPEND_ELEM2(head, el, add, prev, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef DL_INSERT_INORDER2 +#define DL_INSERT_INORDER2(head,add,cmp,prev,next) \ +do { \ + if ((head) == NULL) { \ + (add)->prev = (add); \ + (add)->next = NULL; \ + (head) = (add); \ + } else if ((cmp(head, add)) >= 0) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->prev = (head); \ + (add)->next = (head)->next; \ + (head)->next = (add); \ + UTLIST_RS(head); \ + if ((add)->next) { \ + (add)->next->prev = (add); \ + } else { \ + (head)->prev = (add); \ + } \ + } \ +} while (0) +#endif /* NO_DECLTYPE */ /****************************************************************************** * circular doubly linked list macros * *****************************************************************************/ +#define CDL_APPEND(head,add) \ + CDL_APPEND2(head,add,prev,next) + +#define CDL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + (head) = (add); \ + } \ +} while (0) + #define CDL_PREPEND(head,add) \ CDL_PREPEND2(head,add,prev,next) @@ -642,7 +888,39 @@ do { (add)->prev = (add); \ (add)->next = (add); \ } \ -(head)=(add); \ + (head) = (add); \ +} while (0) + +#define CDL_INSERT_INORDER(head,add,cmp) \ + CDL_INSERT_INORDER2(head,add,cmp,prev,next) + +#define CDL_INSERT_INORDER2(head,add,cmp,prev,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + CDL_LOWER_BOUND2(head, _tmp, add, cmp, next); \ + CDL_APPEND_ELEM2(head, _tmp, add, prev, next); \ + } else { \ + (head) = (add); \ + (head)->next = (head); \ + (head)->prev = (head); \ + } \ +} while (0) + +#define CDL_LOWER_BOUND(head,elt,like,cmp) \ + CDL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define CDL_LOWER_BOUND2(head,elt,like,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != (head); (elt) = (elt)->next) { \ + if ((cmp((elt)->next, like)) >= 0) { \ + break; \ + } \ + } \ + } \ } while (0) #define CDL_DELETE(head,del) \ @@ -650,28 +928,37 @@ do { #define CDL_DELETE2(head,del,prev,next) \ do { \ - if ( ((head)==(del)) && ((head)->next == (head))) { \ - (head) = 0L; \ + if (((head)==(del)) && ((head)->next == (head))) { \ + (head) = NULL; \ } else { \ (del)->next->prev = (del)->prev; \ (del)->prev->next = (del)->next; \ if ((del) == (head)) (head)=(del)->next; \ } \ -} while (0) +} while (0) + +#define CDL_COUNT(head,el,counter) \ + CDL_COUNT2(head,el,counter,next) \ + +#define CDL_COUNT2(head, el, counter,next) \ +do { \ + (counter) = 0; \ + CDL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) #define CDL_FOREACH(head,el) \ CDL_FOREACH2(head,el,next) #define CDL_FOREACH2(head,el,next) \ - for(el=head;el;el=((el)->next==head ? 0L : (el)->next)) + for ((el)=(head);el;(el)=(((el)->next==(head)) ? NULL : (el)->next)) #define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) #define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ - for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ - (el) && ((tmp2)=(el)->next, 1); \ - ((el) = (((el)==(tmp1)) ? 0L : (tmp2)))) + for ((el) = (head), (tmp1) = (head) ? (head)->prev : NULL; \ + (el) && ((tmp2) = (el)->next, 1); \ + (el) = ((el) == (tmp1) ? NULL : (tmp2))) #define CDL_SEARCH_SCALAR(head,out,field,val) \ CDL_SEARCH_SCALAR2(head,out,field,val,next) @@ -681,7 +968,7 @@ do { CDL_FOREACH2(head,out,next) { \ if ((out)->field == (val)) break; \ } \ -} while(0) +} while (0) #define CDL_SEARCH(head,out,elt,cmp) \ CDL_SEARCH2(head,out,elt,cmp,next) @@ -691,13 +978,13 @@ do { CDL_FOREACH2(head,out,next) { \ if ((cmp(out,elt))==0) break; \ } \ -} while(0) +} while (0) -#define CDL_REPLACE_ELEM(head, el, add) \ +#define CDL_REPLACE_ELEM2(head, el, add, prev, next) \ do { \ - assert(head != NULL); \ - assert(el != NULL); \ - assert(add != NULL); \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ if ((el)->next == (el)) { \ (add)->next = (add); \ (add)->prev = (add); \ @@ -713,19 +1000,74 @@ do { } \ } while (0) -#define CDL_PREPEND_ELEM(head, el, add) \ +#define CDL_REPLACE_ELEM(head, el, add) \ + CDL_REPLACE_ELEM2(head, el, add, prev, next) + +#define CDL_PREPEND_ELEM2(head, el, add, prev, next) \ do { \ - assert(head != NULL); \ - assert(el != NULL); \ - assert(add != NULL); \ - (add)->next = (el); \ - (add)->prev = (el)->prev; \ - (el)->prev = (add); \ - (add)->prev->next = (add); \ - if ((head) == (el)) { \ - (head) = (add); \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } else { \ + CDL_APPEND2(head, add, prev, next); \ + } \ +} while (0) + +#define CDL_PREPEND_ELEM(head, el, add) \ + CDL_PREPEND_ELEM2(head, el, add, prev, next) + +#define CDL_APPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (add)->prev = (el); \ + (el)->next = (add); \ + (add)->next->prev = (add); \ + } else { \ + CDL_PREPEND2(head, add, prev, next); \ } \ -} while (0) \ +} while (0) + +#define CDL_APPEND_ELEM(head, el, add) \ + CDL_APPEND_ELEM2(head, el, add, prev, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef CDL_INSERT_INORDER2 +#define CDL_INSERT_INORDER2(head,add,cmp,prev,next) \ +do { \ + if ((head) == NULL) { \ + (add)->prev = (add); \ + (add)->next = (add); \ + (head) = (add); \ + } else if ((cmp(head, add)) >= 0) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (add)->prev->next = (add); \ + (head)->prev = (add); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((char*)(head)->next != _tmp && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->prev = (head); \ + (add)->next = (head)->next; \ + (add)->next->prev = (add); \ + (head)->next = (add); \ + UTLIST_RS(head); \ + } \ +} while (0) +#endif /* NO_DECLTYPE */ #endif /* UTLIST_H */ - diff --git a/src/util/uthash/src/utringbuffer.h b/src/util/uthash/src/utringbuffer.h new file mode 100644 index 0000000..cf48131 --- /dev/null +++ b/src/util/uthash/src/utringbuffer.h @@ -0,0 +1,108 @@ +/* +Copyright (c) 2015-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* a ring-buffer implementation using macros + */ +#ifndef UTRINGBUFFER_H +#define UTRINGBUFFER_H + +#define UTRINGBUFFER_VERSION 2.3.0 + +#include +#include +#include "utarray.h" // for "UT_icd" + +typedef struct { + unsigned i; /* index of next available slot; wraps at n */ + unsigned n; /* capacity */ + unsigned char f; /* full */ + UT_icd icd; /* initializer, copy and destructor functions */ + char *d; /* n slots of size icd->sz */ +} UT_ringbuffer; + +#define utringbuffer_init(a, _n, _icd) do { \ + memset(a, 0, sizeof(UT_ringbuffer)); \ + (a)->icd = *(_icd); \ + (a)->n = (_n); \ + if ((a)->n) { (a)->d = (char*)malloc((a)->n * (_icd)->sz); } \ +} while(0) + +#define utringbuffer_clear(a) do { \ + if ((a)->icd.dtor) { \ + if ((a)->f) { \ + unsigned _ut_i; \ + for (_ut_i = 0; _ut_i < (a)->n; ++_ut_i) { \ + (a)->icd.dtor(utringbuffer_eltptr(a, _ut_i)); \ + } \ + } else { \ + unsigned _ut_i; \ + for (_ut_i = 0; _ut_i < (a)->i; ++_ut_i) { \ + (a)->icd.dtor(utringbuffer_eltptr(a, _ut_i)); \ + } \ + } \ + } \ + (a)->i = 0; \ + (a)->f = 0; \ +} while(0) + +#define utringbuffer_done(a) do { \ + utringbuffer_clear(a); \ + free((a)->d); (a)->d = NULL; \ + (a)->n = 0; \ +} while(0) + +#define utringbuffer_new(a,n,_icd) do { \ + a = (UT_ringbuffer*)malloc(sizeof(UT_ringbuffer)); \ + utringbuffer_init(a, n, _icd); \ +} while(0) + +#define utringbuffer_free(a) do { \ + utringbuffer_done(a); \ + free(a); \ +} while(0) + +#define utringbuffer_push_back(a,p) do { \ + if ((a)->icd.dtor && (a)->f) { (a)->icd.dtor(_utringbuffer_internalptr(a,(a)->i)); } \ + if ((a)->icd.copy) { (a)->icd.copy( _utringbuffer_internalptr(a,(a)->i), p); } \ + else { memcpy(_utringbuffer_internalptr(a,(a)->i), p, (a)->icd.sz); }; \ + if (++(a)->i == (a)->n) { (a)->i = 0; (a)->f = 1; } \ +} while(0) + +#define utringbuffer_len(a) ((a)->f ? (a)->n : (a)->i) +#define utringbuffer_empty(a) ((a)->i == 0 && !(a)->f) +#define utringbuffer_full(a) ((a)->f != 0) + +#define _utringbuffer_real_idx(a,j) ((a)->f ? ((j) + (a)->i) % (a)->n : (j)) +#define _utringbuffer_internalptr(a,j) ((void*)((a)->d + ((a)->icd.sz * (j)))) +#define utringbuffer_eltptr(a,j) ((0 <= (j) && (j) < utringbuffer_len(a)) ? _utringbuffer_internalptr(a,_utringbuffer_real_idx(a,j)) : NULL) + +#define _utringbuffer_fake_idx(a,j) ((a)->f ? ((j) + (a)->n - (a)->i) % (a)->n : (j)) +#define _utringbuffer_internalidx(a,e) (((char*)(e) >= (a)->d) ? (((char*)(e) - (a)->d)/(a)->icd.sz) : -1) +#define utringbuffer_eltidx(a,e) _utringbuffer_fake_idx(a, _utringbuffer_internalidx(a,e)) + +#define utringbuffer_front(a) utringbuffer_eltptr(a,0) +#define utringbuffer_next(a,e) ((e)==NULL ? utringbuffer_front(a) : utringbuffer_eltptr(a, utringbuffer_eltidx(a,e)+1)) +#define utringbuffer_prev(a,e) ((e)==NULL ? utringbuffer_back(a) : utringbuffer_eltptr(a, utringbuffer_eltidx(a,e)-1)) +#define utringbuffer_back(a) (utringbuffer_empty(a) ? NULL : utringbuffer_eltptr(a, utringbuffer_len(a) - 1)) + +#endif /* UTRINGBUFFER_H */ diff --git a/src/util/uthash/src/utstack.h b/src/util/uthash/src/utstack.h new file mode 100644 index 0000000..2dbfec8 --- /dev/null +++ b/src/util/uthash/src/utstack.h @@ -0,0 +1,88 @@ +/* +Copyright (c) 2018-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTSTACK_H +#define UTSTACK_H + +#define UTSTACK_VERSION 2.3.0 + +/* + * This file contains macros to manipulate a singly-linked list as a stack. + * + * To use utstack, your structure must have a "next" pointer. + * + * ----------------.EXAMPLE ------------------------- + * struct item { + * int id; + * struct item *next; + * } + * + * struct item *stack = NULL: + * + * int main() { + * int count; + * struct item *tmp; + * struct item *item = malloc(sizeof *item); + * item->id = 42; + * STACK_COUNT(stack, tmp, count); assert(count == 0); + * STACK_PUSH(stack, item); + * STACK_COUNT(stack, tmp, count); assert(count == 1); + * STACK_POP(stack, item); + * free(item); + * STACK_COUNT(stack, tmp, count); assert(count == 0); + * } + * -------------------------------------------------- + */ + +#define STACK_TOP(head) (head) + +#define STACK_EMPTY(head) (!(head)) + +#define STACK_PUSH(head,add) \ + STACK_PUSH2(head,add,next) + +#define STACK_PUSH2(head,add,next) \ +do { \ + (add)->next = (head); \ + (head) = (add); \ +} while (0) + +#define STACK_POP(head,result) \ + STACK_POP2(head,result,next) + +#define STACK_POP2(head,result,next) \ +do { \ + (result) = (head); \ + (head) = (head)->next; \ +} while (0) + +#define STACK_COUNT(head,el,counter) \ + STACK_COUNT2(head,el,counter,next) \ + +#define STACK_COUNT2(head,el,counter,next) \ +do { \ + (counter) = 0; \ + for ((el) = (head); el; (el) = (el)->next) { ++(counter); } \ +} while (0) + +#endif /* UTSTACK_H */ diff --git a/src/util/uthash/src/utstring.h b/src/util/uthash/src/utstring.h index 5ad3c4a..009b4c8 100644 --- a/src/util/uthash/src/utstring.h +++ b/src/util/uthash/src/utstring.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2013, Troy D. Hanson http://troydhanson.github.com/uthash/ +Copyright (c) 2008-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without @@ -21,36 +21,49 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* a dynamic string implementation using macros +/* a dynamic string implementation using macros */ #ifndef UTSTRING_H #define UTSTRING_H -#define UTSTRING_VERSION 1.9.8 - -#ifdef __GNUC__ -#define _UNUSED_ __attribute__ ((__unused__)) -#else -#define _UNUSED_ -#endif +#define UTSTRING_VERSION 2.3.0 #include #include +#include #include -#define oom() exit(-1) + +#ifdef __GNUC__ +#define UTSTRING_UNUSED __attribute__((__unused__)) +#else +#define UTSTRING_UNUSED +#endif + +#ifdef oom +#error "The name of macro 'oom' has been changed to 'utstring_oom'. Please update your code." +#define utstring_oom() oom() +#endif + +#ifndef utstring_oom +#define utstring_oom() exit(-1) +#endif typedef struct { - char *d; - size_t n; /* allocd size */ + char *d; /* pointer to allocated buffer */ + size_t n; /* allocated capacity */ size_t i; /* index of first unused byte */ } UT_string; #define utstring_reserve(s,amt) \ do { \ if (((s)->n - (s)->i) < (size_t)(amt)) { \ - (s)->d = (char*)realloc((s)->d, (s)->n + amt); \ - if ((s)->d == NULL) oom(); \ - (s)->n += amt; \ + char *utstring_tmp = (char*)realloc( \ + (s)->d, (s)->n + (amt)); \ + if (!utstring_tmp) { \ + utstring_oom(); \ + } \ + (s)->d = utstring_tmp; \ + (s)->n += (amt); \ } \ } while(0) @@ -58,7 +71,7 @@ do { \ do { \ (s)->n = 0; (s)->i = 0; (s)->d = NULL; \ utstring_reserve(s,100); \ - (s)->d[0] = '\0'; \ + (s)->d[0] = '\0'; \ } while(0) #define utstring_done(s) \ @@ -75,9 +88,11 @@ do { \ #define utstring_new(s) \ do { \ - s = (UT_string*)calloc(sizeof(UT_string),1); \ - if (!s) oom(); \ - utstring_init(s); \ + (s) = (UT_string*)malloc(sizeof(UT_string)); \ + if (!(s)) { \ + utstring_oom(); \ + } \ + utstring_init(s); \ } while(0) #define utstring_renew(s) \ @@ -97,10 +112,10 @@ do { \ #define utstring_bincpy(s,b,l) \ do { \ - utstring_reserve((s),(l)+1); \ + utstring_reserve((s),(l)+1); \ if (l) memcpy(&(s)->d[(s)->i], b, l); \ - (s)->i += l; \ - (s)->d[(s)->i]='\0'; \ + (s)->i += (l); \ + (s)->d[(s)->i]='\0'; \ } while(0) #define utstring_concat(dst,src) \ @@ -111,14 +126,14 @@ do { \ (dst)->d[(dst)->i]='\0'; \ } while(0) -#define utstring_len(s) ((unsigned)((s)->i)) +#define utstring_len(s) ((s)->i) #define utstring_body(s) ((s)->d) -_UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) { +UTSTRING_UNUSED static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) { int n; va_list cp; - while (1) { + for (;;) { #ifdef _WIN32 cp = ap; #else @@ -127,7 +142,7 @@ _UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list a n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp); va_end(cp); - if ((n > -1) && (n < (int)(s->n-s->i))) { + if ((n > -1) && ((size_t) n < (s->n-s->i))) { s->i += n; return; } @@ -142,7 +157,7 @@ _UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list a static void utstring_printf(UT_string *s, const char *fmt, ...) __attribute__ (( format( printf, 2, 3) )); #endif -_UNUSED_ static void utstring_printf(UT_string *s, const char *fmt, ...) { +UTSTRING_UNUSED static void utstring_printf(UT_string *s, const char *fmt, ...) { va_list ap; va_start(ap,fmt); utstring_printf_va(s,fmt,ap); @@ -153,9 +168,9 @@ _UNUSED_ static void utstring_printf(UT_string *s, const char *fmt, ...) { * begin substring search functions * ******************************************************************************/ /* Build KMP table from left to right. */ -_UNUSED_ static void _utstring_BuildTable( - const char *P_Needle, - size_t P_NeedleLen, +UTSTRING_UNUSED static void _utstring_BuildTable( + const char *P_Needle, + size_t P_NeedleLen, long *P_KMP_Table) { long i, j; @@ -163,7 +178,7 @@ _UNUSED_ static void _utstring_BuildTable( i = 0; j = i - 1; P_KMP_Table[i] = j; - while (i < P_NeedleLen) + while (i < (long) P_NeedleLen) { while ( (j > -1) && (P_Needle[i] != P_Needle[j]) ) { @@ -171,7 +186,7 @@ _UNUSED_ static void _utstring_BuildTable( } i++; j++; - if (i < P_NeedleLen) + if (i < (long) P_NeedleLen) { if (P_Needle[i] == P_Needle[j]) { @@ -193,9 +208,9 @@ _UNUSED_ static void _utstring_BuildTable( /* Build KMP table from right to left. */ -_UNUSED_ static void _utstring_BuildTableR( - const char *P_Needle, - size_t P_NeedleLen, +UTSTRING_UNUSED static void _utstring_BuildTableR( + const char *P_Needle, + size_t P_NeedleLen, long *P_KMP_Table) { long i, j; @@ -205,7 +220,7 @@ _UNUSED_ static void _utstring_BuildTableR( P_KMP_Table[i + 1] = j; while (i >= 0) { - while ( (j < P_NeedleLen) && (P_Needle[i] != P_Needle[j]) ) + while ( (j < (long) P_NeedleLen) && (P_Needle[i] != P_Needle[j]) ) { j = P_KMP_Table[j + 1]; } @@ -233,11 +248,11 @@ _UNUSED_ static void _utstring_BuildTableR( /* Search data from left to right. ( Multiple search mode. ) */ -_UNUSED_ static long _utstring_find( - const char *P_Haystack, - size_t P_HaystackLen, - const char *P_Needle, - size_t P_NeedleLen, +UTSTRING_UNUSED static long _utstring_find( + const char *P_Haystack, + size_t P_HaystackLen, + const char *P_Needle, + size_t P_NeedleLen, long *P_KMP_Table) { long i, j; @@ -266,11 +281,11 @@ _UNUSED_ static long _utstring_find( /* Search data from right to left. ( Multiple search mode. ) */ -_UNUSED_ static long _utstring_findR( - const char *P_Haystack, - size_t P_HaystackLen, - const char *P_Needle, - size_t P_NeedleLen, +UTSTRING_UNUSED static long _utstring_findR( + const char *P_Haystack, + size_t P_HaystackLen, + const char *P_Needle, + size_t P_NeedleLen, long *P_KMP_Table) { long i, j; @@ -300,10 +315,10 @@ _UNUSED_ static long _utstring_findR( /* Search data from left to right. ( One time search mode. ) */ -_UNUSED_ static long utstring_find( - UT_string *s, +UTSTRING_UNUSED static long utstring_find( + UT_string *s, long P_StartPosition, /* Start from 0. -1 means last position. */ - const char *P_Needle, + const char *P_Needle, size_t P_NeedleLen) { long V_StartPosition; @@ -320,17 +335,17 @@ _UNUSED_ static long utstring_find( V_StartPosition = P_StartPosition; } V_HaystackLen = s->i - V_StartPosition; - if ( (V_HaystackLen >= P_NeedleLen) && (P_NeedleLen > 0) ) + if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) ) { V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1)); if (V_KMP_Table != NULL) { _utstring_BuildTable(P_Needle, P_NeedleLen, V_KMP_Table); - V_FindPosition = _utstring_find(s->d + V_StartPosition, - V_HaystackLen, - P_Needle, - P_NeedleLen, + V_FindPosition = _utstring_find(s->d + V_StartPosition, + V_HaystackLen, + P_Needle, + P_NeedleLen, V_KMP_Table); if (V_FindPosition >= 0) { @@ -346,10 +361,10 @@ _UNUSED_ static long utstring_find( /* Search data from right to left. ( One time search mode. ) */ -_UNUSED_ static long utstring_findR( - UT_string *s, +UTSTRING_UNUSED static long utstring_findR( + UT_string *s, long P_StartPosition, /* Start from 0. -1 means last position. */ - const char *P_Needle, + const char *P_Needle, size_t P_NeedleLen) { long V_StartPosition; @@ -366,17 +381,17 @@ _UNUSED_ static long utstring_findR( V_StartPosition = P_StartPosition; } V_HaystackLen = V_StartPosition + 1; - if ( (V_HaystackLen >= P_NeedleLen) && (P_NeedleLen > 0) ) + if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) ) { V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1)); if (V_KMP_Table != NULL) { _utstring_BuildTableR(P_Needle, P_NeedleLen, V_KMP_Table); - V_FindPosition = _utstring_findR(s->d, - V_HaystackLen, - P_Needle, - P_NeedleLen, + V_FindPosition = _utstring_findR(s->d, + V_HaystackLen, + P_Needle, + P_NeedleLen, V_KMP_Table); free(V_KMP_Table); diff --git a/src/util/uthash/tests/README b/src/util/uthash/tests/README deleted file mode 100644 index 7b03924..0000000 --- a/src/util/uthash/tests/README +++ /dev/null @@ -1,116 +0,0 @@ -Automated tests for uthash -============================================================================== -Run "make" in this directory to build the tests and run them. - -test1: make 10-item hash, iterate and print each one -test2: make 10-item hash, lookup items with even keys, print -test3: make 10-item hash, delete items with even keys, print others -test4: 10 structs have dual hash handles, separate keys -test5: 10 structs have dual hash handles, lookup evens by alt key -test6: test alt malloc macros -test7: test alt malloc macros with 1000 structs so bucket expansion occurs -test8: test num_items counter in UT_hash_handle -test9: test "find" after bucket expansion -test10: dual-hash handle test, bucket expansion on one and not the other -test11: read dat file of names into hash, sort them and print -test12: create hash with string keys, add 10 items, lookup each item -test13: make 10-item hash, delete items with even keys, reverse print others -test14: read dat file of names into hash, read file again and lookup each one -test15: build string-keyed hash of 3 items, lookup one item (c.f. test40.c) -test16: hash on aggregate key, iterate, lookup, using generalized macros -test17: sort, add more items, sort again -test18: test pathological HASH_DEL(a,a) scenario (single head,deletee variable) -test19: sort two hash tables with shared elements using HASH_SRT -test20: test a 5-byte "binary" key -test21: test a structure key (userguide) -test22: test multi-field key using flexible array member (userguide utf32) -test23: test whether delete in iteration works -test24: make 10-item hash and confirm item count (HASH_COUNT) -test25: CDL / DL / LL tests -test26: test the linked list sort macros in utlist.h -test27: LL_APPEND, SORT -test28: CDL / DL / LL tests -test29: DL_APPEND, SORT -test30: CDL_PREPEND, SORT -test31: CDL_PREPEND, SORT -test32: DL_PREPEND -test33: LL_PREPEND -test34: CDL_PREPEND -test35: CDL_PREPEND -test36: HASH_SELECT -test37: HASH_CLEAR -test38: find-or-add test on integer keys in short loop -test39: HASH_ADD_KEYPTR then HASH_FIND using array element as key pointer -test40: HASH_ADD_KEYPTR on string keys; pointer equivalent to test15.c -test41: test LL_FOREACH_SAFE,DL_FOREACH_SAFE,CDL_FOREACH_SAFE -test42: test LL_SEARCH, LL_SEARCH_SCALAR, and DL and CDL counterparts -test43: test utarray with intpair objects -test44: test utarray with int objects -test45: test utarray with int objects -test46: test utarray with char* objects -test47: test utstring -test48: test utarray of int -test49: test utarray of str -test50: test utarray of long -test51: test utarray of intpair -test52: test utarray of intchar -test53: test utstring -test54: test utstring -test55: test utstring -test56: test uthash, utlist and utstring together for #define conflicts etc -test57: test uthash HASH_ADD_PTR and HASH_FIND_PTR -test58: test HASH_ITER macro -test59: sample of multi-level hash -test60: sample of multi-level hash that also does HASH_DEL and free -test61: test utarray_find -test62: test macros used in safe unaligned reads on non-Intel type platforms -test63: LL_CONCAT test -test64: DL_CONCAT test -test65: LRU cache example courtesy of jehiah.cz with modifications -test66: test example where output variable to HASH_FIND needs extra parens -test67: test utarray_prev -test68: test DL_REPLACE_ELEM (Zoltán Lajos Kis) -test69: test DL_PREPEND_ELEM (Zoltán Lajos Kis) -test70: test LL_REPLACE_ELEM (Zoltán Lajos Kis) -test71: test LL_PREPEND_ELEM (Zoltán Lajos Kis) -test72: test CDL_REPLACE_ELEM (Zoltán Lajos Kis) -test73: test CDL_PREPEND_ELEM (Zoltán Lajos Kis) -test74: test utstring with utstring_find (Joe Wei) -test75: test utstring with utstring_findR (Joe Wei) -test76: test utstring with _utstring_find (Joe Wei) -test77: test utstring with _utstring_findR (Joe Wei) -test78: test utlist "2" family with flexible Prev/Next naming eg. DL_DELETE2 -test79: test HASH_REPLACE -test80: test utarray_insert past end of array -test81: test utarray_insert past end of array -test82: test utarray_inserta past end of array -test83: test HASH_OVERHEAD -test84: test HASH_OVERHEAD on hash with bloom filter - - -Other Make targets -================================================================================ -pedantic: makes the tests with extra CFLAGS for pedantic compiling -cplusplus: compiles all the C tests using the C++ compiler to test compatibility -debug: makes the tests with debugging symbols and no optimization -example: builds the 'example' program from the user guide -================================================================================ - -Other files -================================================================================ -keystats: key statistics analyzer. See the User Guide (http://uthash.sf.net) -emit_keys: reads a data file of unique strings, emits as keys w/HASH_EMIT_KEYS=1 -all_funcs: a script which executes the test suite with every hash function -win32tests:builds and runs the test suite under Microsoft Visual Studio - -LINUX-ONLY ----------- -hashscan: tool to examine a running process and get info on its hash tables -test_sleep:used as a subject for inspection by hashscan - -Manual performance testing -================================================================================ - # test performance characteristics on keys that are English dictionary words - emit_keys /usr/share/dict/words > words.keys - ./keystats words.keys - diff --git a/src/util/uthash/tests/all_funcs b/src/util/uthash/tests/all_funcs deleted file mode 100755 index 18df8a1..0000000 --- a/src/util/uthash/tests/all_funcs +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -function proceed { - read -p "proceed ? [n] " response - if [ "$response" != "y" ]; then exit -1; fi -} - -make clean tests_only EXTRA_CFLAGS='-DHASH_FUNCTION=HASH_BER'; proceed -make clean tests_only EXTRA_CFLAGS='-DHASH_FUNCTION=HASH_SAX'; proceed -make clean tests_only EXTRA_CFLAGS='-DHASH_FUNCTION=HASH_FNV'; proceed -make clean tests_only EXTRA_CFLAGS='-DHASH_FUNCTION=HASH_OAT'; proceed -make clean tests_only EXTRA_CFLAGS='-DHASH_FUNCTION=HASH_JEN'; proceed -make clean tests_only EXTRA_CFLAGS='-DHASH_FUNCTION=HASH_MUR'; proceed -make clean tests_only EXTRA_CFLAGS='-DHASH_FUNCTION=HASH_SFH'; diff --git a/src/util/uthash/tests/bloom_perf.c b/src/util/uthash/tests/bloom_perf.c deleted file mode 100644 index 58b3002..0000000 --- a/src/util/uthash/tests/bloom_perf.c +++ /dev/null @@ -1,64 +0,0 @@ -#include /* malloc */ -#include /* gettimeofday */ -#include /* perror */ -#include /* printf */ -#include "uthash.h" - -#define BUFLEN 20 -#if 0 -#undef uthash_expand_fyi -#define uthash_expand_fyi(tbl) printf("expanding to %d buckets\n", tbl->num_buckets) -#endif - -typedef struct name_rec { - char boy_name[BUFLEN]; - UT_hash_handle hh; -} name_rec; - -int main(int argc,char *argv[]) { - name_rec *name, *names=NULL; - char linebuf[BUFLEN]; - FILE *file; - int i=0,j,nloops=3,loopnum=0,miss; - struct timeval tv1,tv2; - long elapsed_usec; - if (argc > 1) nloops = atoi(argv[1]); - - if ( (file = fopen( "test14.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - i++; - if ( (name = (name_rec*)malloc(sizeof(name_rec))) == NULL) exit(-1); - strncpy(name->boy_name,linebuf,BUFLEN); - HASH_ADD_STR(names,boy_name,name); - } - - again: - if (fseek(file,0,SEEK_SET) == -1) { - fprintf(stderr,"fseek failed: %s\n", strerror(errno)); - } - j=0; - - if (gettimeofday(&tv1,NULL) == -1) perror("gettimeofday: "); - while (fgets(linebuf,BUFLEN,file) != NULL) { - /* if we do 10 loops, the first has a 0% miss rate, - * the second has a 10% miss rate, etc */ - miss = ((rand()*1.0/RAND_MAX) < (loopnum*1.0/nloops)) ? 1 : 0; - /* generate a miss if we want one */ - if (miss) { linebuf[0]++; if (linebuf[1] != '\0') linebuf[1]++; } - HASH_FIND_STR(names,linebuf,name); - if (name) j++; - } - if (gettimeofday(&tv2,NULL) == -1) perror("gettimeofday: "); - elapsed_usec = ((tv2.tv_sec - tv1.tv_sec) * 1000000) + (tv2.tv_usec - tv1.tv_usec); - printf("lookup on %d of %d (%.2f%%) names succeeded (%.2f usec)\n", j, i, - j*100.0/i, (double)(elapsed_usec)); - if (++loopnum < nloops) goto again; - fclose(file); - - return 0; -} - diff --git a/src/util/uthash/tests/bloom_perf.sh b/src/util/uthash/tests/bloom_perf.sh deleted file mode 100755 index 0a04f23..0000000 --- a/src/util/uthash/tests/bloom_perf.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -BITS="16" - -cc -I../src -O3 -Wall -m64 bloom_perf.c -o bloom_perf.none -for bits in $BITS -do -cc -I../src -DHASH_BLOOM=$bits -O3 -Wall -m64 bloom_perf.c -o bloom_perf.$bits -done - -for bits in none $BITS -do -echo -echo "using $bits-bit filter:" -./bloom_perf.$bits 10 -done - diff --git a/src/util/uthash/tests/do_tests b/src/util/uthash/tests/do_tests deleted file mode 100755 index 574403f..0000000 --- a/src/util/uthash/tests/do_tests +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -my @tests; -for (glob "test*[0-9]") { - push @tests, $_ if -e "$_.ans"; -} - -my $num_failed=0; - -for my $test (@tests) { - `./$test > $test.out`; - `diff $test.out $test.ans`; - print "$test failed\n" if $?; - $num_failed++ if $?; -} - -print scalar @tests . " tests conducted, $num_failed failed.\n"; -exit $num_failed; diff --git a/src/util/uthash/tests/do_tests.cygwin b/src/util/uthash/tests/do_tests.cygwin deleted file mode 100755 index 0c01ebe..0000000 --- a/src/util/uthash/tests/do_tests.cygwin +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -my @tests; -for (glob "test*[0-9].exe") { - push @tests, "$_" if -e substr($_, 0, - 4).".ans"; -} - -my $num_failed=0; - -for my $test (@tests) { - `./$test > $test.out`; - my $ansfile = substr($test, 0, - 4).".ans"; - `diff $test.out $ansfile`; - print "$test failed\n" if $?; - $num_failed++ if $?; -} - -print scalar @tests . " tests conducted, $num_failed failed.\n"; -exit $num_failed; diff --git a/src/util/uthash/tests/do_tests.mingw b/src/util/uthash/tests/do_tests.mingw deleted file mode 100644 index 1820334..0000000 --- a/src/util/uthash/tests/do_tests.mingw +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -echo "MinGW test script starting" - -for f in test*.exe -do - t=`echo $f | sed s/.exe//` - `$f > $t.out` - diff -qb "$t.out" "$t.ans" - if [ $? -eq 1 ] - then - echo "$f failed" - else - true # can't have empty else - #echo "$f passed" - fi -done - -echo -echo "All tests complete" diff --git a/src/util/uthash/tests/do_tests_win32.cmd b/src/util/uthash/tests/do_tests_win32.cmd deleted file mode 100644 index be89301..0000000 --- a/src/util/uthash/tests/do_tests_win32.cmd +++ /dev/null @@ -1,16 +0,0 @@ -:: this compiles and runs the test suite under Visual Studio 2008 -::@echo off -call "C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat" > vc.out -::call "C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat" > vc.out -set "COMPILE=cl.exe /I ..\src /EHsc /nologo" -echo compiling... -%COMPILE% tdiff.cpp > compile.out -::for %%f in (test*.c) do %COMPILE% /Tp %%f >> compile.out -for %%f in (test*.c) do %COMPILE% /Tc %%f >> compile.out -echo running tests... -for %%f in (test*.exe) do %%f > %%~nf.out -echo scanning for failures... -for %%f in (test*.out) do tdiff %%f %%~nf.ans -echo tests completed -::for %%f in (test*.out test*.obj test*.exe vc.out compile.out tdiff.obj tdiff.exe) do del %%f -pause diff --git a/src/util/uthash/tests/emit_keys.c b/src/util/uthash/tests/emit_keys.c deleted file mode 100644 index 8a0c0cd..0000000 --- a/src/util/uthash/tests/emit_keys.c +++ /dev/null @@ -1,44 +0,0 @@ -#include /* malloc */ -#include /* perror */ -#include /* printf */ -#include /* write */ - -/* this define must precede uthash.h */ -#define HASH_EMIT_KEYS 1 -#include "uthash.h" - -#define BUFLEN 30 - -typedef struct name_rec { - char boy_name[BUFLEN]; - UT_hash_handle hh; -} name_rec; - -int main(int argc,char *argv[]) { - name_rec *name, *names=NULL; - char linebuf[BUFLEN]; - FILE *file; - int i=0; - - if (argc != 2) { - fprintf(stderr,"usage: %s file\n", argv[0]); - exit(-1); - } - - if ( (file = fopen( argv[1], "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (name_rec*)malloc(sizeof(name_rec))) == NULL) exit(-1); - strncpy(name->boy_name,linebuf,BUFLEN); - HASH_ADD_STR(names,boy_name,name); - i++; - } - - fprintf(stderr,"%d keys emitted.\n", i); - fclose(file); - return 0; -} - diff --git a/src/util/uthash/tests/example.c b/src/util/uthash/tests/example.c deleted file mode 100644 index d0dca0c..0000000 --- a/src/util/uthash/tests/example.c +++ /dev/null @@ -1,135 +0,0 @@ -#include /* gets */ -#include /* atoi, malloc */ -#include /* strcpy */ -#include "uthash.h" - -struct my_struct { - int id; /* key */ - char name[10]; - UT_hash_handle hh; /* makes this structure hashable */ -}; - -struct my_struct *users = NULL; - -void add_user(int user_id, char *name) { - struct my_struct *s; - - HASH_FIND_INT(users, &user_id, s); /* id already in the hash? */ - if (s==NULL) { - s = (struct my_struct*)malloc(sizeof(struct my_struct)); - s->id = user_id; - HASH_ADD_INT( users, id, s ); /* id: name of key field */ - } - strcpy(s->name, name); -} - -struct my_struct *find_user(int user_id) { - struct my_struct *s; - - HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */ - return s; -} - -void delete_user(struct my_struct *user) { - HASH_DEL( users, user); /* user: pointer to deletee */ - free(user); -} - -void delete_all() { - struct my_struct *current_user, *tmp; - - HASH_ITER(hh, users, current_user, tmp) { - HASH_DEL(users,current_user); /* delete it (users advances to next) */ - free(current_user); /* free it */ - } -} - -void print_users() { - struct my_struct *s; - - for(s=users; s != NULL; s=(struct my_struct*)(s->hh.next)) { - printf("user id %d: name %s\n", s->id, s->name); - } -} - -int name_sort(struct my_struct *a, struct my_struct *b) { - return strcmp(a->name,b->name); -} - -int id_sort(struct my_struct *a, struct my_struct *b) { - return (a->id - b->id); -} - -void sort_by_name() { - HASH_SORT(users, name_sort); -} - -void sort_by_id() { - HASH_SORT(users, id_sort); -} - -int main(int argc, char *argv[]) { - char in[10]; - int id=1, running=1; - struct my_struct *s; - unsigned num_users; - - while (running) { - printf(" 1. add user\n"); - printf(" 2. add/rename user by id\n"); - printf(" 3. find user\n"); - printf(" 4. delete user\n"); - printf(" 5. delete all users\n"); - printf(" 6. sort items by name\n"); - printf(" 7. sort items by id\n"); - printf(" 8. print users\n"); - printf(" 9. count users\n"); - printf("10. quit\n"); - gets(in); - switch(atoi(in)) { - case 1: - printf("name?\n"); - add_user(id++, gets(in)); - break; - case 2: - printf("id?\n"); - gets(in); id = atoi(in); - printf("name?\n"); - add_user(id, gets(in)); - break; - case 3: - printf("id?\n"); - s = find_user(atoi(gets(in))); - printf("user: %s\n", s ? s->name : "unknown"); - break; - case 4: - printf("id?\n"); - s = find_user(atoi(gets(in))); - if (s) delete_user(s); - else printf("id unknown\n"); - break; - case 5: - delete_all(); - break; - case 6: - sort_by_name(); - break; - case 7: - sort_by_id(); - break; - case 8: - print_users(); - break; - case 9: - num_users=HASH_COUNT(users); - printf("there are %u users\n", num_users); - break; - case 10: - running=0; - break; - } - } - - delete_all(); /* free any structures */ - return 0; -} diff --git a/src/util/uthash/tests/hashscan.c b/src/util/uthash/tests/hashscan.c deleted file mode 100644 index ea6c5ff..0000000 --- a/src/util/uthash/tests/hashscan.c +++ /dev/null @@ -1,589 +0,0 @@ -/* -Copyright (c) 2005-2013, Troy D. Hanson http://troydhanson.github.com/uthash/ -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __FreeBSD__ -#include /* MAXPATHLEN */ -#include /* VM_PROT_* flags */ -#endif - -/* need this defined so offsetof can give us bloom offsets in UT_hash_table */ -#define HASH_BLOOM 16 -#include "uthash.h" - -#ifdef __FreeBSD__ -typedef struct { - void *start; - void *end; -} vma_t; -#else -typedef struct { - off_t start; - off_t end; - char perms[4]; /* rwxp */ - char device[5]; /* fd:01 or 00:00 */ -} vma_t; -#endif - -const uint32_t sig = HASH_SIGNATURE; -int verbose=0; -int getkeys=0; - -#define vv(...) do {if (verbose>0) printf(__VA_ARGS__);} while(0) -#define vvv(...) do {if (verbose>1) printf(__VA_ARGS__);} while(0) - -/* these id's are arbitrary, only meaningful within this file */ -#define JEN 1 -#define BER 2 -#define SFH 3 -#define SAX 4 -#define FNV 5 -#define OAT 6 -#define MUR 7 -#define NUM_HASH_FUNCS 8 /* includes id 0, the non-function */ -char *hash_fcns[] = {"???","JEN","BER","SFH","SAX","FNV","OAT","MUR"}; - -/* given a peer key/len/hashv, reverse engineer its hash function */ -int infer_hash_function(char *key, size_t keylen, uint32_t hashv) { - uint32_t obkt, ohashv, num_bkts=0x01000000; /* anything ok */ - /* BER SAX FNV OAT JEN SFH */ - HASH_JEN(key,keylen,num_bkts,ohashv,obkt); if (ohashv == hashv) return JEN; - HASH_BER(key,keylen,num_bkts,ohashv,obkt); if (ohashv == hashv) return BER; - HASH_SFH(key,keylen,num_bkts,ohashv,obkt); if (ohashv == hashv) return SFH; - HASH_SAX(key,keylen,num_bkts,ohashv,obkt); if (ohashv == hashv) return SAX; - HASH_FNV(key,keylen,num_bkts,ohashv,obkt); if (ohashv == hashv) return FNV; - HASH_OAT(key,keylen,num_bkts,ohashv,obkt); if (ohashv == hashv) return OAT; - HASH_MUR(key,keylen,num_bkts,ohashv,obkt); if (ohashv == hashv) return MUR; - obkt++; // this quiets an unused variable warning. yes, this is a ugly hack - return 0; -} - -/* read peer's memory from addr for len bytes, store into our dst */ -#ifdef __FreeBSD__ -int read_mem(void *dst, pid_t pid, void *start, size_t len) { - struct ptrace_io_desc io_desc; - int ret; - - io_desc.piod_op = PIOD_READ_D; - io_desc.piod_offs = start; - io_desc.piod_addr = dst; - io_desc.piod_len = len; - - ret = ptrace(PT_IO, pid, (void *) &io_desc, 0); - - if (ret) { - vv("read_mem: ptrace failed: %s\n", strerror(errno)); - return -1; - } else if (io_desc.piod_len != len) { - vv("read_mem: short read!\n"); - return -1; - } - - return 0; -} -#else -int read_mem(void *dst, int fd, off_t start, size_t len) { - int rc; - size_t bytes_read=0; - if (lseek(fd, start, SEEK_SET) == (off_t)-1) { - fprintf(stderr, "lseek failed: %s\n", strerror(errno)); - return -1; - } - while ( len && ((rc=read(fd, (char*)dst+bytes_read, len)) > 0)) { - len -= rc; - bytes_read += rc; - } - if (rc==-1) vv("read_mem failed (%s)\n",strerror(errno)); - if ((len != 0 && rc >= 0)) vv("INTERNAL ERROR\n"); - return (rc == -1) ? -1 : 0; -} -#endif - -/* later compensate for possible presence of bloom filter */ -char *tbl_from_sig_addr(char *sig) { - return (sig - offsetof(UT_hash_table,signature)); -} - -#define HS_BIT_TEST(v,i) (v[i/8] & (1U << (i%8))) -void found(int fd, char* peer_sig, pid_t pid) { - UT_hash_table *tbl=NULL; - UT_hash_bucket *bkts=NULL; - UT_hash_handle hh; - size_t i, bloom_len, bloom_bitlen, bloom_on_bits=0,bloom_off_bits=0; - char *peer_tbl, *peer_bloom_sig, *peer_bloom_nbits, *peer_bloombv_ptr, - *peer_bloombv, *peer_bkts, *peer_key, *peer_hh, *key=NULL, - *hash_fcn=NULL, sat[10]; - unsigned char *bloombv=NULL; - static int fileno=0; - char keyfile[50]; - unsigned char bloom_nbits=0; - int keyfd=-1, mode=S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, - hash_fcn_hits[NUM_HASH_FUNCS], hash_fcn_winner; - unsigned max_chain=0; - uint32_t bloomsig; - double bloom_sat=0; - snprintf(sat,sizeof(sat)," "); - for(i=0; i < NUM_HASH_FUNCS; i++) hash_fcn_hits[i]=0; - - if (getkeys) { - snprintf(keyfile, sizeof(keyfile), "/tmp/%u-%u.key", (unsigned)pid,fileno++); - if ( (keyfd = open(keyfile, O_WRONLY|O_CREAT|O_TRUNC, mode)) == -1) { - fprintf(stderr, "can't open %s: %s\n", keyfile, strerror(errno)); - exit(-1); - } - } - - vv("found signature at peer %p\n", peer_sig); - peer_tbl = tbl_from_sig_addr(peer_sig); - vvv("reading table at peer %p\n", peer_tbl); - - if ( (tbl = (UT_hash_table*)malloc(sizeof(UT_hash_table))) == NULL) { - fprintf(stderr, "out of memory\n"); - exit(-1); - } -#ifdef __FreeBSD__ - if (read_mem(tbl, pid, (void *)peer_tbl, sizeof(UT_hash_table)) != 0) { -#else - if (read_mem(tbl, fd, (off_t)peer_tbl, sizeof(UT_hash_table)) != 0) { -#endif - fprintf(stderr, "failed to read peer memory\n"); - goto done; - } - - /* got the table. how about the buckets */ - peer_bkts = (char*)tbl->buckets; - vvv("reading buckets at peer %p\n", peer_bkts); - bkts = (UT_hash_bucket*)malloc(sizeof(UT_hash_bucket)*tbl->num_buckets); - if (bkts == NULL) { - fprintf(stderr, "out of memory\n"); - exit(-1); - } -#ifdef __FreeBSD__ - if (read_mem(bkts, pid, (void *)peer_bkts, sizeof(UT_hash_bucket)*tbl->num_buckets) != 0) { -#else - if (read_mem(bkts, fd, (off_t)peer_bkts, sizeof(UT_hash_bucket)*tbl->num_buckets) != 0) { -#endif - fprintf(stderr, "failed to read peer memory\n"); - goto done; - } - - vvv("scanning %u peer buckets\n", tbl->num_buckets); - for(i=0; i < tbl->num_buckets; i++) { - vvv("bucket %u has %u items\n", (unsigned)i, (unsigned)(bkts[i].count)); - if (bkts[i].count > max_chain) max_chain = bkts[i].count; - if (bkts[i].expand_mult) vvv(" bucket %u has expand_mult %u\n", (unsigned)i, (unsigned)(bkts[i].expand_mult)); - - vvv("scanning bucket %u chain:\n", (unsigned)i); - peer_hh = (char*)bkts[i].hh_head; - while(peer_hh) { -#ifdef __FreeBSD__ - if (read_mem(&hh, pid, (void *)peer_hh, sizeof(hh)) != 0) { -#else - if (read_mem(&hh, fd, (off_t)peer_hh, sizeof(hh)) != 0) { -#endif - fprintf(stderr, "failed to read peer memory\n"); - goto done; - } - if ((char*)hh.tbl != peer_tbl) goto done; - peer_hh = (char*)hh.hh_next; - peer_key = (char*)(hh.key); - /* malloc space to read the key, and read it */ - if ( (key = (char*)malloc(sizeof(hh.keylen))) == NULL) { - fprintf(stderr, "out of memory\n"); - exit(-1); - } -#ifdef __FreeBSD__ - if (read_mem(key, pid, (void*)peer_key, hh.keylen) != 0) { -#else - if (read_mem(key, fd, (off_t)peer_key, hh.keylen) != 0) { -#endif - fprintf(stderr, "failed to read peer memory\n"); - goto done; - } - hash_fcn_hits[infer_hash_function(key,hh.keylen,hh.hashv)]++; - /* write the key if requested */ - if (getkeys) { - write(keyfd, &hh.keylen, sizeof(unsigned)); - write(keyfd, key, hh.keylen); - } - free(key); key=NULL; - } - } - - /* does it have a bloom filter? */ - peer_bloom_sig = peer_tbl + offsetof(UT_hash_table, bloom_sig); - peer_bloombv_ptr = peer_tbl + offsetof(UT_hash_table, bloom_bv); - peer_bloom_nbits = peer_tbl + offsetof(UT_hash_table, bloom_nbits); - vvv("looking for bloom signature at peer %p\n", peer_bloom_sig); -#ifdef __FreeBSD__ - if ((read_mem(&bloomsig, pid, (void *)peer_bloom_sig, sizeof(uint32_t)) == 0) && - (bloomsig == HASH_BLOOM_SIGNATURE)) { -#else - if ((read_mem(&bloomsig, fd, (off_t)peer_bloom_sig, sizeof(uint32_t)) == 0) && - (bloomsig == HASH_BLOOM_SIGNATURE)) { -#endif - vvv("bloom signature (%x) found\n",bloomsig); - /* bloom found. get at bv, nbits */ -#ifdef __FreeBSD__ - if (read_mem(&bloom_nbits, pid, (void *)peer_bloom_nbits, sizeof(char)) == 0) { -#else - if (read_mem(&bloom_nbits, fd, (off_t)peer_bloom_nbits, sizeof(char)) == 0) { -#endif - /* scan bloom filter, calculate saturation */ - bloom_bitlen = (1ULL << bloom_nbits); - bloom_len = (bloom_bitlen / 8) + ((bloom_bitlen % 8) ? 1 : 0); - vvv("bloom bitlen is %u, bloom_bytelen is %u\n", (unsigned)bloom_bitlen, (unsigned)bloom_len); - if ( (bloombv = (unsigned char*)malloc(bloom_len)) == NULL) { - fprintf(stderr, "out of memory\n"); - exit(-1); - } - /* read the address of the bitvector in the peer, then read the bv itself */ -#ifdef __FreeBSD__ - if ((read_mem(&peer_bloombv, pid, (void *)peer_bloombv_ptr, sizeof(void*)) == 0) && - (read_mem(bloombv, pid, (void *)peer_bloombv, bloom_len) == 0)) { -#else - if ((read_mem(&peer_bloombv, fd, (off_t)peer_bloombv_ptr, sizeof(void*)) == 0) && - (read_mem(bloombv, fd, (off_t)peer_bloombv, bloom_len) == 0)) { -#endif - /* calculate saturation */ - vvv("read peer bloom bitvector from %p (%u bytes)\n", peer_bloombv, (unsigned)bloom_len); - for(i=0; i < bloom_bitlen; i++) { - if (HS_BIT_TEST(bloombv,(unsigned)i)) { - /* vvv("bit %u set\n",(unsigned)i); */ - bloom_on_bits++; - } else bloom_off_bits++; - } - vvv("there were %u on_bits among %u total bits\n", (unsigned)bloom_on_bits, (unsigned)bloom_bitlen); - bloom_sat = bloom_on_bits * 100.0 / bloom_bitlen; - snprintf(sat,sizeof(sat),"%2u %5.0f%%", bloom_nbits, bloom_sat); - } - } - } - - /* choose apparent hash function */ - hash_fcn_winner=0; - for(i=0;i hash_fcn_hits[hash_fcn_winner]) hash_fcn_winner=i; - } - hash_fcn = hash_fcns[hash_fcn_winner]; - -/* -Address items ideal buckets mxch/<10 fl bloom/sat fcn keys saved to ------------------- -------- ----- -------- -------- -- --------- --- ------------- -0x0123456789abcdef 10000000 98% 32000000 10 100% ok BER /tmp/9110-0.key -0x0123456789abcdef 10000000 100% 32000000 9 90% NX 27/0.010% BER /tmp/9110-1.key -*/ - printf("Address ideal items buckets mc fl bloom/sat fcn keys saved to\n"); - printf("------------------ ----- -------- -------- -- -- --------- --- -------------\n"); - printf("%-18p %4.0f%% %8u %8u %2u %s %s %s %s\n", - (void*)peer_tbl, - (tbl->num_items - tbl->nonideal_items) * 100.0 / tbl->num_items, - tbl->num_items, - tbl->num_buckets, - max_chain, - tbl->noexpand ? "NX" : "ok", - sat, - hash_fcn, - (getkeys ? keyfile : "")); - -#if 0 - printf("read peer tbl:\n"); - printf("num_buckets: %u\n", tbl->num_buckets); - printf("num_items: %u\n", tbl->num_items); - printf("nonideal_items: %u (%.2f%%)\n", tbl->nonideal_items, - tbl->nonideal_items*100.0/tbl->num_items); - printf("expand: %s\n", tbl->noexpand ? "inhibited": "normal"); - if (getkeys) printf("keys written to %s\n", keyfile); -#endif - - done: - if (bkts) free(bkts); - if (tbl) free(tbl); - if (key) free(key); - if (keyfd != -1) close(keyfd); - if (bloombv) free(bloombv); -} - - -#ifdef __FreeBSD__ -void sigscan(pid_t pid, void *start, void *end, uint32_t sig) { - struct ptrace_io_desc io_desc; - int page_size = getpagesize(); - char *buf; - char *pos; - - /* make sure page_size is a multiple of the signature size, code below assumes this */ - assert(page_size % sizeof(sig) == 0); - - buf = malloc(page_size); - - if (buf == NULL) { - fprintf(stderr, "malloc failed in sigscan()\n"); - return; - } - - io_desc.piod_op = PIOD_READ_D; - io_desc.piod_offs = start; - io_desc.piod_addr = buf; - io_desc.piod_len = page_size; - - /* read in one page after another and search sig */ - while(!ptrace(PT_IO, pid, (void *) &io_desc, 0)) { - if (io_desc.piod_len != page_size) { - fprintf(stderr, "PT_IO returned less than page size in sigscan()\n"); - return; - } - - /* iterate over the the page using the signature size and look for the sig */ - for (pos = buf; pos < (buf + page_size); pos += sizeof(sig)) { - if (*(uint32_t *) pos == sig) { - found(pid, (char *) io_desc.piod_offs + (pos - buf), pid); - } - } - - /* - * 'end' is inclusive (the address of the last valid byte), so if the current offset - * plus a page is beyond 'end', we're already done. since all vm map entries consist - * of entire pages and 'end' is inclusive, current offset plus one page should point - * exactly one byte beyond 'end'. this is assert()ed below to be on the safe side. - */ - if (io_desc.piod_offs + page_size > end) { - assert(io_desc.piod_offs + page_size == (end + 1)); - break; - } - - /* advance to the next page */ - io_desc.piod_offs += page_size; - } -} -#else -void sigscan(int fd, off_t start, off_t end, uint32_t sig, pid_t pid) { - int rlen; - uint32_t u; - off_t at=0; - - if (lseek(fd, start, SEEK_SET) == (off_t)-1) { - fprintf(stderr, "lseek failed: %s\n", strerror(errno)); - return; - } - - while ( (rlen = read(fd,&u,sizeof(u))) == sizeof(u)) { - if (!memcmp(&u,&sig,sizeof(u))) found(fd, (char*)(start+at),pid); - at += sizeof(u); - if ((off_t)(at + sizeof(u)) > end-start) break; - } - - if (rlen == -1) { - //fprintf(stderr,"read failed: %s\n", strerror(errno)); - //exit(-1); - } -} -#endif - - -#ifdef __FreeBSD__ -int scan(pid_t pid) { - vma_t *vmas=NULL, vma; - unsigned i, num_vmas = 0; - int ret; - struct ptrace_vm_entry vm_entry; - char path[MAXPATHLEN]; - - vv("attaching to peer\n"); - if (ptrace(PT_ATTACH,pid,NULL,0) == -1) { - fprintf(stderr,"failed to attach to %u: %s\n", (unsigned)pid, strerror(errno)); - exit(EXIT_FAILURE); - } - vv("waiting for peer to suspend temporarily\n"); - if (waitpid(pid,NULL,0) != pid) { - fprintf(stderr,"failed to wait for pid %u: %s\n",(unsigned)pid, strerror(errno)); - goto die; - } - - /* read memory map using ptrace */ - vv("listing peer virtual memory areas\n"); - vm_entry.pve_entry = 0; - vm_entry.pve_path = path; /* not used but required to make vm_entry.pve_pathlen work */ - while(1) { - /* set pve_pathlen every turn, it gets overwritten by ptrace */ - vm_entry.pve_pathlen = MAXPATHLEN; - errno = 0; - - ret = ptrace(PT_VM_ENTRY, pid, (void *) &vm_entry, 0); - - if (ret) { - if (errno == ENOENT) { - /* we've reached the last entry */ - break; - } - fprintf(stderr, "fetching vm map entry failed: %s (%i)\n", strerror(errno), errno); - goto die; - } - - vvv("vmmap entry: start: %p, end: %p", (void *) vm_entry.pve_start, (void *) vm_entry.pve_end); - - /* skip unreadable or vnode-backed entries */ - if (!(vm_entry.pve_prot & VM_PROT_READ) || vm_entry.pve_pathlen > 0) { - vvv(" -> skipped (not readable or vnode-backed)\n"); - vm_entry.pve_path[0] = 0; - continue; - } - - /* useful entry, add to list */ - vvv(" -> will be scanned\n"); - vma.start = (void *)vm_entry.pve_start; - vma.end = (void *)vm_entry.pve_end; - vmas = (vma_t *) realloc(vmas, (num_vmas + 1) * sizeof(vma_t)); - vmas[num_vmas++] = vma; - } - - vv("peer has %u virtual memory areas\n", num_vmas); - - /* look for the hash signature */ - vv("scanning peer memory for hash table signatures\n"); - for(i=0;i\n", prog); - exit(-1); -} - -int main(int argc, char *argv[]) { - pid_t pid; - int opt; - - while ( (opt = getopt(argc, argv, "kv")) != -1) { - switch (opt) { - case 'v': - verbose++; - break; - case 'k': - getkeys++; - break; - default: - usage(argv[0]); - break; - } - } - - if (optind < argc) pid=atoi(argv[optind++]); - else usage(argv[0]); - - return scan(pid); -} diff --git a/src/util/uthash/tests/keystat.c b/src/util/uthash/tests/keystat.c deleted file mode 100644 index bf1d6ff..0000000 --- a/src/util/uthash/tests/keystat.c +++ /dev/null @@ -1,219 +0,0 @@ -#include /* for 'open' */ -#include /* for 'open' */ -#include /* for 'open' */ -#include /* for 'malloc' */ -#include /* for 'printf' */ -#include /* for 'read' */ -#include /* for 'sterror' */ -#include /* for 'gettimeofday' */ -#include "uthash.h" - -#undef uthash_noexpand_fyi -#define uthash_noexpand_fyi(t) die() -#define UNALIGNED_KEYS 0 - -void die() { - fprintf(stderr,"expansion inhibited\n"); - exit(-1); -} - -/* Windows doesn't have gettimeofday. While Cygwin and some - * versions of MinGW supply one, it is very coarse. This substitute - * gives much more accurate elapsed times under Windows. */ -#if (( defined __CYGWIN__ ) || ( defined __MINGW32__ )) -#include -void win_gettimeofday(struct timeval* p, void* tz /* IGNORED */) { - LARGE_INTEGER q; - static long long freq; - static long long cyg_timer; - QueryPerformanceFrequency(&q); - freq = q.QuadPart; - QueryPerformanceCounter(&q); - cyg_timer = q.QuadPart; - p->tv_sec = (long)(cyg_timer / freq); - p->tv_usec = (long)(((cyg_timer % freq) * 1000000) / freq); -} -#define gettimeofday win_gettimeofday -#define MODE (O_RDONLY|O_BINARY) -#else -#define MODE (O_RDONLY) -#endif - -#ifndef timersub -#define timersub(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ - } while (0) -#endif - -typedef struct stat_key { - char *key; - unsigned len; - UT_hash_handle hh, hh2; -} stat_key; - -#define CHAIN_0 0 -#define CHAIN_5 1 -#define CHAIN_10 2 -#define CHAIN_20 3 -#define CHAIN_100 4 -#define CHAIN_MAX 5 -void hash_chain_len_histogram(UT_hash_table *tbl) { - unsigned i, bkt_hist[CHAIN_MAX+1]; - double pct = 100.0/tbl->num_buckets; - memset(bkt_hist,0,sizeof(bkt_hist)); - for(i=0; i < tbl->num_buckets; i++) { - unsigned count = tbl->buckets[i].count; - if (count == 0) bkt_hist[CHAIN_0]++; - else if (count < 5) bkt_hist[CHAIN_5]++; - else if (count < 10) bkt_hist[CHAIN_10]++; - else if (count < 20) bkt_hist[CHAIN_20]++; - else if (count < 100) bkt_hist[CHAIN_100]++; - else bkt_hist[CHAIN_MAX]++; - } - fprintf(stderr, "Buckets with 0 items: %.1f%%\n", bkt_hist[CHAIN_0 ]*pct); - fprintf(stderr, "Buckets with < 5 items: %.1f%%\n", bkt_hist[CHAIN_5 ]*pct); - fprintf(stderr, "Buckets with < 10 items: %.1f%%\n", bkt_hist[CHAIN_10]*pct); - fprintf(stderr, "Buckets with < 20 items: %.1f%%\n", bkt_hist[CHAIN_20]*pct); - fprintf(stderr, "Buckets with < 100 items: %.1f%%\n", bkt_hist[CHAIN_100]*pct); - fprintf(stderr, "Buckets with > 100 items: %.1f%%\n", bkt_hist[CHAIN_MAX]*pct); -} - -int main(int argc, char *argv[]) { - int dups=0, rc, fd, done=0, err=0, want, i=0, padding=0, v=1, percent=100; - unsigned keylen, max_keylen=0, verbose=0; - const char *filename = "/dev/stdin"; - char *dst; - stat_key *keyt, *keytmp, *keys=NULL, *keys2=NULL; - struct timeval start_tm, end_tm, elapsed_tm, elapsed_tm2, elapsed_tm3; - - if ((argc >= 3) && !strcmp(argv[1],"-p")) {percent = atoi(argv[2]); v = 3;} - if ((argc >= v) && !strcmp(argv[v],"-v")) {verbose=1; v++;} - if (argc >= v) filename=argv[v]; - fd=open(filename,MODE); - - if ( fd == -1 ) { - fprintf(stderr,"open failed %s: %s\n", filename, strerror(errno)); - return -1; - } - - for(i=0; !done; i++) { - - want = sizeof(int); - dst = (char*)&keylen; - readmore1: - rc = read(fd,dst,want); - if (rc != want) { - if (rc == 0) done=1; - else if (rc == -1) { - fprintf(stderr,"read failed: %s\n", strerror(errno)); - err=1; - } - else if (rc > 0) { want -= rc; dst += rc; goto readmore1; } - } - - if (done || err) break; - if (keylen > max_keylen) max_keylen=keylen; - - if ( (keyt = (stat_key*)malloc(sizeof(stat_key))) == NULL) { - fprintf(stderr,"out of memory\n"); - exit(-1); - } - - /* read key */ -#ifdef UNALIGNED_KEYS - padding = i%8; -#endif - if ( (keyt->key = (char*)malloc(padding+keylen)) == NULL) { - fprintf(stderr,"out of memory\n"); - exit(-1); - } - keyt->key += padding; /* forcibly alter the alignment of key */ - keyt->len = keylen; - - want = keylen; - dst = keyt->key; - readmore2: - rc = read(fd,dst,want); - if (rc != want) { - if (rc == -1) { - fprintf(stderr,"read failed: %s\n", strerror(errno)); - err=1; - } else if (rc == 0) { - fprintf(stderr,"incomplete file\n"); - err=1; - } else if (rc >= 0) { want -= rc; dst += rc; goto readmore2; } - } - if (err) break; - /* if percent was set to something less than 100%, skip some keys*/ - if (((rand()*1.0) / RAND_MAX) > ((percent*1.0)/100)) { - free(keyt->key-padding); - free(keyt); - continue; - } - - /* eliminate dups */ - HASH_FIND(hh,keys,keyt->key,keylen,keytmp); - if (keytmp) { - dups++; - free(keyt->key - padding); - free(keyt); - } else { - HASH_ADD_KEYPTR(hh,keys,keyt->key,keylen,keyt); - } - } - - if (verbose) { - unsigned key_count = HASH_COUNT(keys); - fprintf(stderr,"max key length: %u\n", max_keylen); - fprintf(stderr,"number unique keys: %u\n", key_count); - fprintf(stderr,"keystats memory: %u\n", - (unsigned)((sizeof(stat_key)+max_keylen)*key_count)); - hash_chain_len_histogram(keys->hh.tbl); - } - - /* add all keys to a new hash, so we can measure add time w/o malloc */ - gettimeofday(&start_tm,NULL); - for(keyt = keys; keyt != NULL; keyt=(stat_key*)keyt->hh.next) { - HASH_ADD_KEYPTR(hh2,keys2,keyt->key,keyt->len,keyt); - } - gettimeofday(&end_tm,NULL); - timersub(&end_tm, &start_tm, &elapsed_tm); - - /* now look up all keys in the new hash, again measuring elapsed time */ - gettimeofday(&start_tm,NULL); - for(keyt = keys; keyt != NULL; keyt=(stat_key*)keyt->hh.next) { - HASH_FIND(hh2,keys2,keyt->key,keyt->len,keytmp); - if (!keytmp) fprintf(stderr,"internal error, key not found\n"); - } - gettimeofday(&end_tm,NULL); - timersub(&end_tm, &start_tm, &elapsed_tm2); - - /* now delete all items in the new hash, measuring elapsed time */ - gettimeofday(&start_tm,NULL); - while (keys2) { - keytmp = keys2; - HASH_DELETE(hh2,keys2,keytmp); - } - gettimeofday(&end_tm,NULL); - timersub(&end_tm, &start_tm, &elapsed_tm3); - - if (!err) { - printf("%.3f,%d,%d,%d,%s,%ld,%ld,%ld\n", - 1-(1.0*keys->hh.tbl->nonideal_items/keys->hh.tbl->num_items), - keys->hh.tbl->num_items, - keys->hh.tbl->num_buckets, - dups, - (keys->hh.tbl->noexpand ? "nx" : "ok"), - (elapsed_tm.tv_sec * 1000000) + elapsed_tm.tv_usec, - (elapsed_tm2.tv_sec * 1000000) + elapsed_tm2.tv_usec, - (elapsed_tm3.tv_sec * 1000000) + elapsed_tm3.tv_usec ); - } - return 0; -} - diff --git a/src/util/uthash/tests/keystats b/src/util/uthash/tests/keystats deleted file mode 100755 index ea217b0..0000000 --- a/src/util/uthash/tests/keystats +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/perl - -use strict; - -use FindBin; - -sub usage { - print "usage: keystats [-v] keyfile\n"; - print "usage: keystats [-p [-v]] keyfile\n"; - exit -1; -} - -usage if ((@ARGV == 0) or ($ARGV[0] eq '-h')); - -my @exes = glob "$FindBin::Bin/keystat.???"; -my %stats; -for my $exe (@exes) { - $stats{$exe} = `$exe @ARGV`; - delete $stats{$exe} if ($? != 0); # omit hash functions that fail to produce stats (nx) -} - -print( "fcn ideal% #items #buckets dup% fl add_usec find_usec del-all usec\n"); -printf("--- ------ ---------- ---------- ----- -- ---------- ---------- ------------\n"); -for my $exe (sort statsort keys %stats) { - my ($ideal,$items,$bkts,$dups,$ok,$add,$find,$del) = split /,/, $stats{$exe}; - - # convert 0-1 values to percentages - $dups = $items ? (100.0 * $dups / $items) : 0.0; - $ideal = 100.0 * $ideal; - - printf("%3s %5.1f%% %10d %10d %4.0f%% %2s %10d %10d %12d\n", substr($exe,-3,3), - $ideal,$items,$bkts,$dups,$ok,$add,$find,$del); -} - -# sort on hash_q (desc) then by find_usec (asc) -sub statsort { - my @a_stats = split /,/, $stats{$a}; - my @b_stats = split /,/, $stats{$b}; - return ($b_stats[0] <=> $a_stats[0]) || ($a_stats[-1] <=> $b_stats[-1]); -} diff --git a/src/util/uthash/tests/lru_cache/cache.c b/src/util/uthash/tests/lru_cache/cache.c deleted file mode 100644 index 632c558..0000000 --- a/src/util/uthash/tests/lru_cache/cache.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * ===================================================================================== - * - * Filename: cache.c - * - * Description: A simple cache - * - * Version: 1.0 - * Created: 04/11/2013 02:31:02 PM - * Revision: none - * Compiler: gcc - * - * Author: Oliver Lorenz (ol), olli@olorenz.org - * Company: https://olorenz.org - * License: This is licensed under the same terms as uthash itself - * - * ===================================================================================== - */ - -#include -#include -#include -#include "cache.h" -#include "uthash.h" - -/** - * A cache entry - */ -struct foo_cache_entry { - char *key; /**cache_lock), NULL)) != 0) - goto err_out; - - new->max_entries = capacity; - new->entries = NULL; - new->free_cb = free_cb; - *dst = new; - return 0; - -err_out: - if (new) - free(new); - return rv; -} - -/** Frees an allocated cache object - - @param cache - The cache object to free - - @param keep_data - Whether to free contained data or just delete references to it - - @return EINVAL if cache is NULL, 0 otherwise -*/ -int foo_cache_delete(struct foo_cache *cache, int keep_data) -{ - struct foo_cache_entry *entry, *tmp; - int rv; - - if (!cache) - return EINVAL; - - rv = pthread_rwlock_wrlock(&(cache->cache_lock)); - if (rv) - return rv; - - if (keep_data) { - HASH_CLEAR(hh, cache->entries); - } else { - HASH_ITER(hh, cache->entries, entry, tmp) { - HASH_DEL(cache->entries, entry); - if (cache->free_cb) - cache->free_cb(entry->data); - free(entry); - } - } - (void)pthread_rwlock_unlock(&(cache->cache_lock)); - (void)pthread_rwlock_destroy(&(cache->cache_lock)); - free(cache); - cache = NULL; - return 0; -} - -/** Checks if a given key is in the cache - - @param cache - The cache object - - @param key - The key to look-up - - @param result - Where to store the result if key is found. - - A warning: Even though result is just a pointer, - you have to call this function with a **ptr, - otherwise this will blow up in your face. - - @return EINVAL if cache is NULL, 0 otherwise -*/ -int foo_cache_lookup(struct foo_cache *cache, char *key, void *result) -{ - int rv; - struct foo_cache_entry *tmp = NULL; - char **dirty_hack = result; - - if (!cache || !key || !result) - return EINVAL; - - rv = pthread_rwlock_wrlock(&(cache->cache_lock)); - if (rv) - return rv; - - HASH_FIND_STR(cache->entries, key, tmp); - if (tmp) { - size_t key_len = strnlen(tmp->key, KEY_MAX_LENGTH); - HASH_DELETE(hh, cache->entries, tmp); - HASH_ADD_KEYPTR(hh, cache->entries, tmp->key, key_len, tmp); - *dirty_hack = tmp->data; - } else { - *dirty_hack = result = NULL; - } - rv = pthread_rwlock_unlock(&(cache->cache_lock)); - return rv; -} - -/** Inserts a given pair into the cache - - @param cache - The cache object - - @param key - The key that identifies - - @param data - Data associated with - - @return EINVAL if cache is NULL, ENOMEM if malloc fails, 0 otherwise -*/ -int foo_cache_insert(struct foo_cache *cache, char *key, void *data) -{ - struct foo_cache_entry *entry = NULL; - struct foo_cache_entry *tmp_entry = NULL; - size_t key_len = 0; - int rv; - - if (!cache || !data) - return EINVAL; - - if ((entry = malloc(sizeof(*entry))) == NULL) - return ENOMEM; - - if ((rv = pthread_rwlock_wrlock(&(cache->cache_lock))) != 0) - goto err_out; - - entry->key = key; - entry->data = data; - key_len = strnlen(entry->key, KEY_MAX_LENGTH); - HASH_ADD_KEYPTR(hh, cache->entries, entry->key, key_len, entry); - - if (HASH_COUNT(cache->entries) >= cache->max_entries) { - HASH_ITER(hh, cache->entries, entry, tmp_entry) { - HASH_DELETE(hh, cache->entries, entry); - if (cache->free_cb) - cache->free_cb(entry->data); - else - free(entry->data); - /* free(key->key) if data has been copied */ - free(entry); - break; - } - } - - rv = pthread_rwlock_unlock(&(cache->cache_lock)); - return rv; - -err_out: - if (entry) - free(entry); - (void)pthread_rwlock_unlock(&(cache->cache_lock)); - return rv; - -} diff --git a/src/util/uthash/tests/lru_cache/cache.h b/src/util/uthash/tests/lru_cache/cache.h deleted file mode 100644 index 350576d..0000000 --- a/src/util/uthash/tests/lru_cache/cache.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * ===================================================================================== - * - * Filename: cache.h - * - * Description: A simple cache - * - * Version: 1.0 - * Created: 04/11/2013 02:30:46 PM - * Revision: none - * Compiler: gcc - * - * Author: Oliver Lorenz (ol), olli@olorenz.org - * Company: https://olorenz.org - * License: This is licensed under the same terms as uthash itself - * - * ===================================================================================== - */ - -#ifndef _CACHE_ -#define _CACHE_ - -struct foo_cache; - -extern int foo_cache_create(struct foo_cache **dst, const size_t capacity, - void (*free_cb) (void *element)); -extern int foo_cache_delete(struct foo_cache *cache, int keep_data); -extern int foo_cache_lookup(struct foo_cache *cache, char *key, void *result); -extern int foo_cache_insert(struct foo_cache *cache, char *key, void *data); - -#endif diff --git a/src/util/uthash/tests/lru_cache/main.c b/src/util/uthash/tests/lru_cache/main.c deleted file mode 100644 index 95c8f3c..0000000 --- a/src/util/uthash/tests/lru_cache/main.c +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "cache.h" - -#define MAX_RANDOM_ENTRIES 32 - -struct key_record { - char *key; - char *value; -}; - -int generate_random_entry(struct key_record **entry); -int generate_random_string(char **dst, const size_t len); -void free_random_entry(void *entry); - -void *producer(void *arg) -{ - struct foo_cache *cache = arg; - int i; - - for (i = 0; i < MAX_RANDOM_ENTRIES; i++) { - struct key_record *entry = NULL; - if (generate_random_entry(&entry)) { - fprintf(stderr, "generate_random_entry() failed\n"); - continue; - } -#if defined(DEBUG) - printf("Random Entry:\n"); - printf(" key: %s\n", entry->key); - printf(" Key: %s\n", entry->value); -#else - printf("inserted %s (%d)\n", entry->key, - (int)strlen(entry->key)); -#endif - if (foo_cache_insert(cache, entry->key, entry)) { - fprintf(stderr, "foo_cache_insert() failed\n"); - continue; - } - } - - pthread_exit(NULL); -} - -void *consumer(void *arg) -{ - struct foo_cache *cache = arg; - struct key_record *result = NULL; - char *buffer = malloc(64); - char key[33]; - int stop = 0; - - if (!buffer) - goto out; - - /* give producer time to populate the cache */ - sleep(2); - printf("\n\n"); - - do { - memset(key, 0, 64); - result = NULL; - - printf("Enter key for lookup: "); - fgets(buffer, sizeof(key), stdin); - sscanf(buffer, "%s\n", key); - /* read '\n' from stdin */ - getchar(); - - if (strncmp(key, "exit", 4) == 0) { - stop = 1; - continue; - } - - printf("Got key %s (%d)\n", key, (int)strlen(key)); - - if (foo_cache_lookup(cache, key, &result)) { - fprintf(stderr, "Could not retrieve key %s\n", key); - continue; - } - - if (!result) { - printf("MISS\n"); - continue; - } - - printf("HIT\n"); - printf("key: %s\n", result->key); - printf("key : %s\n", result->value); - } while (!stop); - -out: - if (buffer) - free(buffer); - pthread_exit(NULL); -} - -int main(void) -{ - int rv; - struct foo_cache *cache = NULL; - pthread_t workers[2]; - - rv = foo_cache_create(&cache, MAX_RANDOM_ENTRIES / 2, - free_random_entry); - if (rv) { - fprintf(stderr, "Could not create cache\n"); - exit(1); - } - - (void)pthread_create(&workers[0], NULL, producer, (void *)cache); - (void)pthread_create(&workers[1], NULL, consumer, (void *)cache); - - pthread_join(workers[0], NULL); - pthread_join(workers[1], NULL); - - (void)foo_cache_delete(cache, 0); - return 0; -} - -int generate_random_entry(struct key_record **entry) -{ - struct key_record *new = NULL; - char *key = NULL; - char *value = NULL; - int rv; - - if (!entry) - return EINVAL; - - rv = generate_random_string(&key, 33); - if (rv) - return rv; - - rv = generate_random_string(&value, 129); - if (rv) - return rv; - - if ((new = malloc(sizeof(*new))) == NULL) { - free(key); - free(value); - return ENOMEM; - } - - new->key = key; - new->value = value; - - *entry = new; - return 0; -} - -int generate_random_string(char **dst, const size_t len) -{ - static const char alphanum[] = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - size_t i; - char *s; - - if (!dst || len == 0) - return EINVAL; - - if ((s = malloc(len)) == NULL) - return ENOMEM; - - for (i = 0; i < len - 1; i++) { - s[i] = alphanum[rand() % (sizeof(alphanum) - 1)]; - } - - s[len - 1] = '\0'; - *dst = s; - return 0; -} - -void free_random_entry(void *entry) -{ -#if defined(DEBUG) - fprintf(stderr, "In %s: entry @ %p\n", __func__, entry); -#endif - struct key_record *record = entry; - if (!record) - return; - if (record->key) - free(record->key); - if (record->value) - free(record->value); - free(record); - record = NULL; -} diff --git a/src/util/uthash/tests/mexpand b/src/util/uthash/tests/mexpand deleted file mode 100755 index e1562d9..0000000 --- a/src/util/uthash/tests/mexpand +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# utility to macro-expand a test program -CC=gcc -#CPPFLAGS=-DHASH_DEBUG=1 -#CC=g++ -CPPFLAGS="-m64 -O3" -CFLAGS="-O3 -m64 -pedantic -Wall" - -${CC} ${CPPFLAGS} -E -I../src $1 | egrep -v '^#' > /tmp/$1 -indent /tmp/$1 -${CC} ${CFLAGS} -o /tmp/$1.$$ /tmp/$1 -rm -f /tmp/$1.$$ - -read -p "open /tmp/$1 ? [n] " response -if [ "$response" = "y" ] -then - vi /tmp/$1 -fi - - diff --git a/src/util/uthash/tests/simkeys.pl b/src/util/uthash/tests/simkeys.pl deleted file mode 100755 index acc5583..0000000 --- a/src/util/uthash/tests/simkeys.pl +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/perl - -# This program generates a simkey10.dat (100, 1000, etc) each -# containing 100 random keys of length 10 (100, 1000, etc). -# These files can then be fed into keystats to observe that -# the time to add or find the keys is directly proportional to -# keylength n [in other words, O(n)]. -# -# The conclusion is that really long keys (e.g. 100k) are not -# efficient. TDH 23Jan07 - -use strict; -use warnings; - - -#for my $len (10,100,1000,10000,100000,1000000) { -for my $len (100) { - open OUTFILE, ">simkeys$len.dat" or die "can't open: $!\n"; - # we'll do 100 keys of $len - print "keylen $len\n"; - for my $i (0..99) { - my $key = pack "I", $len; - $key .= pack "C", (int(rand(256))) for (1..$len); - print OUTFILE $key; - } - close OUTFILE; -} - diff --git a/src/util/uthash/tests/sleep_test.c b/src/util/uthash/tests/sleep_test.c deleted file mode 100644 index ccc50c9..0000000 --- a/src/util/uthash/tests/sleep_test.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ -#include /* getpid */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *users=NULL; - - /* create elements */ - for(i=0;i<10000;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - printf("pid: %u\n", (unsigned)getpid()); - /* printf("sig: %p\n", &users->hh.tbl->signature); */ - /* printf("bbv: %p\n", &users->hh.tbl->bloom_bv); */ - sleep(60*10); - return 0; -} diff --git a/src/util/uthash/tests/tdiff.cpp b/src/util/uthash/tests/tdiff.cpp deleted file mode 100644 index 4be14fe..0000000 --- a/src/util/uthash/tests/tdiff.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Windows does not have unix diff so this is a simple replacement -#include -#include -using namespace std; -int main(int argc, char *argv[] ) { - int rc=-1; - if (argc != 3) { - cout << "usage: " << argv[0] << " file1 file2\n"; - return -1; - } - char *file1 = argv[1]; - char *file2 = argv[2]; - ifstream is1(file1, ios::in); - ifstream is2(file2, ios::in); - if (is1.fail()) {cerr << "failed to open " << file1 << "\n"; goto done;} - if (is2.fail()) {cerr << "failed to open " << file2 << "\n"; goto done;} - char d1[256], d2[256]; - do { - is1.read(d1,sizeof(d1)); - is2.read(d2,sizeof(d2)); - if ((is1.gcount() != is2.gcount()) || memcmp(d1,d2,is1.gcount())) { - cout << file1 << " and " << file2 << " differ\n"; - goto done; - } - } while (!is1.eof() && !is2.eof()); - - rc=0; - - done: - is1.close(); - is2.close(); - return rc; -} - diff --git a/src/util/uthash/tests/test1.ans b/src/util/uthash/tests/test1.ans deleted file mode 100644 index 0b08c48..0000000 --- a/src/util/uthash/tests/test1.ans +++ /dev/null @@ -1,10 +0,0 @@ -user 0, cookie 0 -user 1, cookie 1 -user 2, cookie 4 -user 3, cookie 9 -user 4, cookie 16 -user 5, cookie 25 -user 6, cookie 36 -user 7, cookie 49 -user 8, cookie 64 -user 9, cookie 81 diff --git a/src/util/uthash/tests/test1.c b/src/util/uthash/tests/test1.c deleted file mode 100644 index afae6d6..0000000 --- a/src/util/uthash/tests/test1.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *users=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - for(user=users; user != NULL; user=(example_user_t*)(user->hh.next)) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - return 0; -} diff --git a/src/util/uthash/tests/test10.ans b/src/util/uthash/tests/test10.ans deleted file mode 100644 index b1a27a8..0000000 --- a/src/util/uthash/tests/test10.ans +++ /dev/null @@ -1,4 +0,0 @@ -9 found in hh -9 found in alth -10 not found in hh -10 found in alth diff --git a/src/util/uthash/tests/test10.c b/src/util/uthash/tests/test10.c deleted file mode 100644 index e8efc3b..0000000 --- a/src/util/uthash/tests/test10.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; - UT_hash_handle alth; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *tmp, *users=NULL, *altusers=NULL; - - /* create elements */ - for(i=0;i<1000;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - if (i<10) HASH_ADD_INT(users,id,user); - HASH_ADD(alth,altusers,id,sizeof(int),user); - } - - /* - printf("hh items: %d, alth items: %d\n", - users->hh.tbl->num_items, users->alth.tbl->num_items); - printf("hh buckets: %d, alth buckets: %d\n", - users->hh.tbl->num_buckets, users->alth.tbl->num_buckets); - */ - - i=9; - HASH_FIND_INT(users,&i,tmp); - printf("%d %s in hh\n", i, (tmp ? "found" : "not found")); - HASH_FIND(alth,altusers,&i,sizeof(int),tmp); - printf("%d %s in alth\n", i, (tmp ? "found" : "not found")); - - i=10; - HASH_FIND_INT(users,&i,tmp); - printf("%d %s in hh\n", i, (tmp ? "found" : "not found")); - HASH_FIND(alth,altusers,&i,sizeof(int),tmp); - printf("%d %s in alth\n", i, (tmp ? "found" : "not found")); - - return 0; -} diff --git a/src/util/uthash/tests/test11.ans b/src/util/uthash/tests/test11.ans deleted file mode 100644 index 2b72e98..0000000 --- a/src/util/uthash/tests/test11.ans +++ /dev/null @@ -1,51 +0,0 @@ -ADRIAN -ARNOLDO -CARROLL -CARY -CHONG -CLIFTON -CODY -COLTON -CORNELL -DAMON -DANNIE -DARIO -DONN -DOUG -DOUGLAS -FREDERICK -FRITZ -GERALD -GUS -HARVEY -IRVING -ISAIAH -JARVIS -JOHN -KENTON -LAURENCE -LESTER -LINCOLN -LOWELL -NELSON -NEVILLE -NIGEL -NORMAND -ODIS -OMAR -ORLANDO -RAYMUNDO -REX -ROLANDO -RON -SHANE -TONEY -TRINIDAD -WALTER -WARNER -WARREN -WES -WILLARD -WILLIAM -WINFRED -XAVIER diff --git a/src/util/uthash/tests/test11.c b/src/util/uthash/tests/test11.c deleted file mode 100644 index 81986c5..0000000 --- a/src/util/uthash/tests/test11.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* perror */ -#include /* printf */ - -#define BUFLEN 20 - -#if 0 -/* Print a message if the hash's no-expand flag is set. */ -#undef uthash_noexpand_fyi -#undef uthash_expand_fyi -#define uthash_noexpand_fyi(tbl) printf("noexpand set\n"); -#define uthash_expand_fyi(tbl) printf("hash expanded\n"); -#endif - -typedef struct name_rec { - char boy_name[BUFLEN]; - UT_hash_handle hh; -} name_rec; - -int namecmp(void *_a, void *_b) { - name_rec *a = (name_rec*)_a; - name_rec *b = (name_rec*)_b; - return strcmp(a->boy_name,b->boy_name); -} - -int main(int argc,char *argv[]) { - name_rec *name, *names=NULL; - char linebuf[BUFLEN]; - FILE *file; - - if ( (file = fopen( "test11.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (name_rec*)malloc(sizeof(name_rec))) == NULL) exit(-1); - strncpy(name->boy_name,linebuf,BUFLEN); - HASH_ADD_STR(names,boy_name,name); - } - - fclose(file); - HASH_SORT(names,namecmp); - for(name=names;name;name=(name_rec*)(name->hh.next)) - printf("%s",name->boy_name); - - return 0; -} - diff --git a/src/util/uthash/tests/test11.dat b/src/util/uthash/tests/test11.dat deleted file mode 100644 index bb6051b..0000000 --- a/src/util/uthash/tests/test11.dat +++ /dev/null @@ -1,51 +0,0 @@ -JOHN -WILLIAM -WALTER -DOUGLAS -GERALD -FREDERICK -WARREN -SHANE -LESTER -RON -HARVEY -ADRIAN -CODY -NELSON -CLIFTON -WILLARD -DOUG -ORLANDO -REX -OMAR -DAMON -LOWELL -IRVING -CARROLL -LAURENCE -ROLANDO -CARY -XAVIER -ISAIAH -GUS -JARVIS -WINFRED -RAYMUNDO -LINCOLN -CORNELL -NIGEL -NORMAND -FRITZ -DONN -TRINIDAD -ODIS -DANNIE -DARIO -KENTON -CHONG -NEVILLE -TONEY -WARNER -WES -COLTON -ARNOLDO diff --git a/src/util/uthash/tests/test12.ans b/src/util/uthash/tests/test12.ans deleted file mode 100644 index 727f397..0000000 --- a/src/util/uthash/tests/test12.ans +++ /dev/null @@ -1,20 +0,0 @@ -added bob (id 0) -added jack (id 1) -added gary (id 2) -added ty (id 3) -added bo (id 4) -added phil (id 5) -added art (id 6) -added gil (id 7) -added buck (id 8) -added ted (id 9) -found bob (id 0) -found jack (id 1) -found gary (id 2) -found ty (id 3) -found bo (id 4) -found phil (id 5) -found art (id 6) -found gil (id 7) -found buck (id 8) -found ted (id 9) diff --git a/src/util/uthash/tests/test12.c b/src/util/uthash/tests/test12.c deleted file mode 100644 index dfed3f4..0000000 --- a/src/util/uthash/tests/test12.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "uthash.h" -#include -#include /* malloc */ - -typedef struct person_t { - char first_name[10]; - int id; - UT_hash_handle hh; -} person_t; - -int main(int argc, char*argv[]) { - person_t *people=NULL, *person; - const char **name; - const char * names[] = { "bob", "jack", "gary", "ty", "bo", "phil", "art", - "gil", "buck", "ted", NULL }; - int id=0; - - for(name=names; *name; name++) { - if ( (person = (person_t*)malloc(sizeof(person_t))) == NULL) exit(-1); - strncpy(person->first_name, *name,10); - person->id = id++; - HASH_ADD_STR(people,first_name,person); - printf("added %s (id %d)\n", person->first_name, person->id); - } - - for(name=names; *name; name++) { - HASH_FIND_STR(people,*name,person); - if (person) - printf("found %s (id %d)\n", person->first_name, person->id); - else - printf("failed to find %s\n", *name); - } - return 0; -} diff --git a/src/util/uthash/tests/test13.ans b/src/util/uthash/tests/test13.ans deleted file mode 100644 index baf3ff2..0000000 --- a/src/util/uthash/tests/test13.ans +++ /dev/null @@ -1,5 +0,0 @@ -id 9, following prev... -id 7, following prev... -id 5, following prev... -id 3, following prev... -id 1, following prev... diff --git a/src/util/uthash/tests/test13.c b/src/util/uthash/tests/test13.c deleted file mode 100644 index ed624a8..0000000 --- a/src/util/uthash/tests/test13.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *tmp, *users=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - /* delete each even ID */ - for(i=0;i<10;i+=2) { - HASH_FIND_INT(users,&i,tmp); - if (tmp) { - HASH_DEL(users,tmp); - free(tmp); - } else printf("user id %d not found\n", i); - } - - i=9; - HASH_FIND_INT(users,&i,tmp); - if (tmp) { - while(tmp) { - printf("id %d, following prev...\n", tmp->id); - tmp = (example_user_t*)tmp->hh.prev; - } - } else printf("user id %d not found\n", i); - - return 0; -} diff --git a/src/util/uthash/tests/test14.ans b/src/util/uthash/tests/test14.ans deleted file mode 100644 index 77aeaeb..0000000 --- a/src/util/uthash/tests/test14.ans +++ /dev/null @@ -1 +0,0 @@ -lookup on 1219 of 1219 names succeeded diff --git a/src/util/uthash/tests/test14.c b/src/util/uthash/tests/test14.c deleted file mode 100644 index c31f42a..0000000 --- a/src/util/uthash/tests/test14.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* perror */ -#include /* printf */ - -#define BUFLEN 20 -#if 0 -#undef uthash_expand_fyi -#define uthash_expand_fyi(tbl) printf("expanding to %d buckets\n", tbl->num_buckets) -#endif - -typedef struct name_rec { - char boy_name[BUFLEN]; - UT_hash_handle hh; -} name_rec; - -int main(int argc,char *argv[]) { - name_rec *name, *names=NULL; - char linebuf[BUFLEN]; - FILE *file; - int i=0,j=0; - - if ( (file = fopen( "test14.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - i++; - if ( (name = (name_rec*)malloc(sizeof(name_rec))) == NULL) exit(-1); - strncpy(name->boy_name,linebuf,BUFLEN); - HASH_ADD_STR(names,boy_name,name); - } - - fseek(file,0,SEEK_SET); - - while (fgets(linebuf,BUFLEN,file) != NULL) { - HASH_FIND_STR(names,linebuf,name); - if (!name) printf("failed to find: %s", linebuf); - else j++; - } - fclose(file); - printf("lookup on %d of %d names succeeded\n", j, i); - return 0; -} - diff --git a/src/util/uthash/tests/test14.dat b/src/util/uthash/tests/test14.dat deleted file mode 100644 index ea0b4ea..0000000 --- a/src/util/uthash/tests/test14.dat +++ /dev/null @@ -1,1219 +0,0 @@ -JAMES -JOHN -ROBERT -MICHAEL -WILLIAM -DAVID -RICHARD -CHARLES -JOSEPH -THOMAS -CHRISTOPHER -DANIEL -PAUL -MARK -DONALD -GEORGE -KENNETH -STEVEN -EDWARD -BRIAN -RONALD -ANTHONY -KEVIN -JASON -MATTHEW -GARY -TIMOTHY -JOSE -LARRY -JEFFREY -FRANK -SCOTT -ERIC -STEPHEN -ANDREW -RAYMOND -GREGORY -JOSHUA -JERRY -DENNIS -WALTER -PATRICK -PETER -HAROLD -DOUGLAS -HENRY -CARL -ARTHUR -RYAN -ROGER -JOE -JUAN -JACK -ALBERT -JONATHAN -JUSTIN -TERRY -GERALD -KEITH -SAMUEL -WILLIE -RALPH -LAWRENCE -NICHOLAS -ROY -BENJAMIN -BRUCE -BRANDON -ADAM -HARRY -FRED -WAYNE -BILLY -STEVE -LOUIS -JEREMY -AARON -RANDY -HOWARD -EUGENE -CARLOS -RUSSELL -BOBBY -VICTOR -MARTIN -ERNEST -PHILLIP -TODD -JESSE -CRAIG -ALAN -SHAWN -CLARENCE -SEAN -PHILIP -CHRIS -JOHNNY -EARL -JIMMY -ANTONIO -DANNY -BRYAN -TONY -LUIS -MIKE -STANLEY -LEONARD -NATHAN -DALE -MANUEL -RODNEY -CURTIS -NORMAN -ALLEN -MARVIN -VINCENT -GLENN -JEFFERY -TRAVIS -JEFF -CHAD -JACOB -LEE -MELVIN -ALFRED -KYLE -FRANCIS -BRADLEY -JESUS -HERBERT -FREDERICK -RAY -JOEL -EDWIN -DON -EDDIE -RICKY -TROY -RANDALL -BARRY -ALEXANDER -BERNARD -MARIO -LEROY -FRANCISCO -MARCUS -MICHEAL -THEODORE -CLIFFORD -MIGUEL -OSCAR -JAY -JIM -TOM -CALVIN -ALEX -JON -RONNIE -BILL -LLOYD -TOMMY -LEON -DEREK -WARREN -DARRELL -JEROME -FLOYD -LEO -ALVIN -TIM -WESLEY -GORDON -DEAN -GREG -JORGE -DUSTIN -PEDRO -DERRICK -DAN -LEWIS -ZACHARY -COREY -HERMAN -MAURICE -VERNON -ROBERTO -CLYDE -GLEN -HECTOR -SHANE -RICARDO -SAM -RICK -LESTER -BRENT -RAMON -CHARLIE -TYLER -GILBERT -GENE -MARC -REGINALD -RUBEN -BRETT -ANGEL -NATHANIEL -RAFAEL -LESLIE -EDGAR -MILTON -RAUL -BEN -CHESTER -CECIL -DUANE -FRANKLIN -ANDRE -ELMER -BRAD -GABRIEL -RON -MITCHELL -ROLAND -ARNOLD -HARVEY -JARED -ADRIAN -KARL -CORY -CLAUDE -ERIK -DARRYL -JAMIE -NEIL -JESSIE -CHRISTIAN -JAVIER -FERNANDO -CLINTON -TED -MATHEW -TYRONE -DARREN -LONNIE -LANCE -CODY -JULIO -KELLY -KURT -ALLAN -NELSON -GUY -CLAYTON -HUGH -MAX -DWAYNE -DWIGHT -ARMANDO -FELIX -JIMMIE -EVERETT -JORDAN -IAN -WALLACE -KEN -BOB -JAIME -CASEY -ALFREDO -ALBERTO -DAVE -IVAN -JOHNNIE -SIDNEY -BYRON -JULIAN -ISAAC -MORRIS -CLIFTON -WILLARD -DARYL -ROSS -VIRGIL -ANDY -MARSHALL -SALVADOR -PERRY -KIRK -SERGIO -MARION -TRACY -SETH -KENT -TERRANCE -RENE -EDUARDO -TERRENCE -ENRIQUE -FREDDIE -WADE -AUSTIN -STUART -FREDRICK -ARTURO -ALEJANDRO -JACKIE -JOEY -NICK -LUTHER -WENDELL -JEREMIAH -EVAN -JULIUS -DANA -DONNIE -OTIS -SHANNON -TREVOR -OLIVER -LUKE -HOMER -GERARD -DOUG -KENNY -HUBERT -ANGELO -SHAUN -LYLE -MATT -LYNN -ALFONSO -ORLANDO -REX -CARLTON -ERNESTO -CAMERON -NEAL -PABLO -LORENZO -OMAR -WILBUR -BLAKE -GRANT -HORACE -RODERICK -KERRY -ABRAHAM -WILLIS -RICKEY -JEAN -IRA -ANDRES -CESAR -JOHNATHAN -MALCOLM -RUDOLPH -DAMON -KELVIN -RUDY -PRESTON -ALTON -ARCHIE -MARCO -WM -PETE -RANDOLPH -GARRY -GEOFFREY -JONATHON -FELIPE -BENNIE -GERARDO -ED -DOMINIC -ROBIN -LOREN -DELBERT -COLIN -GUILLERMO -EARNEST -LUCAS -BENNY -NOEL -SPENCER -RODOLFO -MYRON -EDMUND -GARRETT -SALVATORE -CEDRIC -LOWELL -GREGG -SHERMAN -WILSON -DEVIN -SYLVESTER -KIM -ROOSEVELT -ISRAEL -JERMAINE -FORREST -WILBERT -LELAND -SIMON -GUADALUPE -CLARK -IRVING -CARROLL -BRYANT -OWEN -RUFUS -WOODROW -SAMMY -KRISTOPHER -MACK -LEVI -MARCOS -GUSTAVO -JAKE -LIONEL -MARTY -TAYLOR -ELLIS -DALLAS -GILBERTO -CLINT -NICOLAS -LAURENCE -ISMAEL -ORVILLE -DREW -JODY -ERVIN -DEWEY -AL -WILFRED -JOSH -HUGO -IGNACIO -CALEB -TOMAS -SHELDON -ERICK -FRANKIE -STEWART -DOYLE -DARREL -ROGELIO -TERENCE -SANTIAGO -ALONZO -ELIAS -BERT -ELBERT -RAMIRO -CONRAD -PAT -NOAH -GRADY -PHIL -CORNELIUS -LAMAR -ROLANDO -CLAY -PERCY -DEXTER -BRADFORD -MERLE -DARIN -AMOS -TERRELL -MOSES -IRVIN -SAUL -ROMAN -DARNELL -RANDAL -TOMMIE -TIMMY -DARRIN -WINSTON -BRENDAN -TOBY -VAN -ABEL -DOMINICK -BOYD -COURTNEY -JAN -EMILIO -ELIJAH -CARY -DOMINGO -SANTOS -AUBREY -EMMETT -MARLON -EMANUEL -JERALD -EDMOND -EMIL -DEWAYNE -WILL -OTTO -TEDDY -REYNALDO -BRET -MORGAN -JESS -TRENT -HUMBERTO -EMMANUEL -STEPHAN -LOUIE -VICENTE -LAMONT -STACY -GARLAND -MILES -MICAH -EFRAIN -BILLIE -LOGAN -HEATH -RODGER -HARLEY -DEMETRIUS -ETHAN -ELDON -ROCKY -PIERRE -JUNIOR -FREDDY -ELI -BRYCE -ANTOINE -ROBBIE -KENDALL -ROYCE -STERLING -MICKEY -CHASE -GROVER -ELTON -CLEVELAND -DYLAN -CHUCK -DAMIAN -REUBEN -STAN -AUGUST -LEONARDO -JASPER -RUSSEL -ERWIN -BENITO -HANS -MONTE -BLAINE -ERNIE -CURT -QUENTIN -AGUSTIN -MURRAY -JAMAL -DEVON -ADOLFO -HARRISON -TYSON -BURTON -BRADY -ELLIOTT -WILFREDO -BART -JARROD -VANCE -DENIS -DAMIEN -JOAQUIN -HARLAN -DESMOND -ELLIOT -DARWIN -ASHLEY -GREGORIO -BUDDY -XAVIER -KERMIT -ROSCOE -ESTEBAN -ANTON -SOLOMON -SCOTTY -NORBERT -ELVIN -WILLIAMS -NOLAN -CAREY -ROD -QUINTON -HAL -BRAIN -ROB -ELWOOD -KENDRICK -DARIUS -MOISES -SON -MARLIN -FIDEL -THADDEUS -CLIFF -MARCEL -ALI -JACKSON -RAPHAEL -BRYON -ARMAND -ALVARO -JEFFRY -DANE -JOESPH -THURMAN -NED -SAMMIE -RUSTY -MICHEL -MONTY -RORY -FABIAN -REGGIE -MASON -GRAHAM -KRIS -ISAIAH -VAUGHN -GUS -AVERY -LOYD -DIEGO -ALEXIS -ADOLPH -NORRIS -MILLARD -ROCCO -GONZALO -DERICK -RODRIGO -GERRY -STACEY -CARMEN -WILEY -RIGOBERTO -ALPHONSO -TY -SHELBY -RICKIE -NOE -VERN -BOBBIE -REED -JEFFERSON -ELVIS -BERNARDO -MAURICIO -HIRAM -DONOVAN -BASIL -RILEY -OLLIE -NICKOLAS -MAYNARD -SCOT -VINCE -QUINCY -EDDY -SEBASTIAN -FEDERICO -ULYSSES -HERIBERTO -DONNELL -COLE -DENNY -DAVIS -GAVIN -EMERY -WARD -ROMEO -JAYSON -DION -DANTE -CLEMENT -COY -ODELL -MAXWELL -JARVIS -BRUNO -ISSAC -MARY -DUDLEY -BROCK -SANFORD -COLBY -CARMELO -BARNEY -NESTOR -HOLLIS -STEFAN -DONNY -ART -LINWOOD -BEAU -WELDON -GALEN -ISIDRO -TRUMAN -DELMAR -JOHNATHON -SILAS -FREDERIC -DICK -KIRBY -IRWIN -CRUZ -MERLIN -MERRILL -CHARLEY -MARCELINO -LANE -HARRIS -CLEO -CARLO -TRENTON -KURTIS -HUNTER -AURELIO -WINFRED -VITO -COLLIN -DENVER -CARTER -LEONEL -EMORY -PASQUALE -MOHAMMAD -MARIANO -DANIAL -BLAIR -LANDON -DIRK -BRANDEN -ADAN -NUMBERS -CLAIR -BUFORD -GERMAN -BERNIE -WILMER -JOAN -EMERSON -ZACHERY -FLETCHER -JACQUES -ERROL -DALTON -MONROE -JOSUE -DOMINIQUE -EDWARDO -BOOKER -WILFORD -SONNY -SHELTON -CARSON -THERON -RAYMUNDO -DAREN -TRISTAN -HOUSTON -ROBBY -LINCOLN -JAME -GENARO -GALE -BENNETT -OCTAVIO -CORNELL -LAVERNE -HUNG -ARRON -ANTONY -HERSCHEL -ALVA -GIOVANNI -GARTH -CYRUS -CYRIL -RONNY -STEVIE -LON -FREEMAN -ERIN -DUNCAN -KENNITH -CARMINE -AUGUSTINE -YOUNG -ERICH -CHADWICK -WILBURN -RUSS -REID -MYLES -ANDERSON -MORTON -JONAS -FOREST -MITCHEL -MERVIN -ZANE -RICH -JAMEL -LAZARO -ALPHONSE -RANDELL -MAJOR -JOHNIE -JARRETT -BROOKS -ARIEL -ABDUL -DUSTY -LUCIANO -LINDSEY -TRACEY -SEYMOUR -SCOTTIE -EUGENIO -MOHAMMED -SANDY -VALENTIN -CHANCE -ARNULFO -LUCIEN -FERDINAND -THAD -EZRA -SYDNEY -ALDO -RUBIN -ROYAL -MITCH -EARLE -ABE -WYATT -MARQUIS -LANNY -KAREEM -JAMAR -BORIS -ISIAH -EMILE -ELMO -ARON -LEOPOLDO -EVERETTE -JOSEF -GAIL -ELOY -DORIAN -RODRICK -REINALDO -LUCIO -JERROD -WESTON -HERSHEL -BARTON -PARKER -LEMUEL -LAVERN -BURT -JULES -GIL -ELISEO -AHMAD -NIGEL -EFREN -ANTWAN -ALDEN -MARGARITO -COLEMAN -REFUGIO -DINO -OSVALDO -LES -DEANDRE -NORMAND -KIETH -IVORY -ANDREA -TREY -NORBERTO -NAPOLEON -JEROLD -FRITZ -ROSENDO -MILFORD -SANG -DEON -CHRISTOPER -ALFONZO -LYMAN -JOSIAH -BRANT -WILTON -RICO -JAMAAL -DEWITT -CAROL -BRENTON -YONG -OLIN -FOSTER -FAUSTINO -CLAUDIO -JUDSON -GINO -EDGARDO -BERRY -ALEC -TANNER -JARRED -DONN -TRINIDAD -TAD -SHIRLEY -PRINCE -PORFIRIO -ODIS -MARIA -LENARD -CHAUNCEY -CHANG -TOD -MEL -MARCELO -KORY -AUGUSTUS -KEVEN -HILARIO -BUD -SAL -ROSARIO -ORVAL -MAURO -DANNIE -ZACHARIAH -OLEN -ANIBAL -MILO -JED -FRANCES -THANH -DILLON -AMADO -NEWTON -CONNIE -LENNY -TORY -RICHIE -LUPE -HORACIO -BRICE -MOHAMED -DELMER -DARIO -REYES -DEE -MAC -JONAH -JERROLD -ROBT -HANK -SUNG -RUPERT -ROLLAND -KENTON -DAMION -CHI -ANTONE -WALDO -FREDRIC -BRADLY -QUINN -KIP -BURL -WALKER -TYREE -JEFFEREY -AHMED -WILLY -STANFORD -OREN -NOBLE -MOSHE -MIKEL -ENOCH -BRENDON -QUINTIN -JAMISON -FLORENCIO -DARRICK -TOBIAS -MINH -HASSAN -GIUSEPPE -DEMARCUS -CLETUS -TYRELL -LYNDON -KEENAN -WERNER -THEO -GERALDO -LOU -COLUMBUS -CHET -BERTRAM -MARKUS -HUEY -HILTON -DWAIN -DONTE -TYRON -OMER -ISAIAS -HIPOLITO -FERMIN -CHUNG -ADALBERTO -VALENTINE -JAMEY -BO -BARRETT -WHITNEY -TEODORO -MCKINLEY -MAXIMO -GARFIELD -SOL -RALEIGH -LAWERENCE -ABRAM -RASHAD -KING -EMMITT -DARON -CHONG -SAMUAL -PARIS -OTHA -MIQUEL -LACY -EUSEBIO -DONG -DOMENIC -DARRON -BUSTER -ANTONIA -WILBER -RENATO -JC -HOYT -HAYWOOD -EZEKIEL -CHAS -FLORENTINO -ELROY -CLEMENTE -ARDEN -NEVILLE -KELLEY -EDISON -DESHAWN -CARROL -SHAYNE -NATHANIAL -JORDON -DANILO -CLAUD -VAL -SHERWOOD -RAYMON -RAYFORD -CRISTOBAL -AMBROSE -TITUS -HYMAN -FELTON -EZEQUIEL -ERASMO -STANTON -LONNY -LEN -IKE -MILAN -LINO -JAROD -HERB -ANDREAS -WALTON -RHETT -PALMER -JUDE -DOUGLASS -CORDELL -OSWALDO -ELLSWORTH -VIRGILIO -TONEY -NATHANAEL -DEL -BRITT -BENEDICT -MOSE -HONG -LEIGH -JOHNSON -ISREAL -GAYLE -GARRET -FAUSTO -ASA -ARLEN -ZACK -WARNER -MODESTO -FRANCESCO -MANUAL -JAE -GAYLORD -GASTON -FILIBERTO -DEANGELO -MICHALE -GRANVILLE -WES -MALIK -ZACKARY -TUAN -NICKY -ELDRIDGE -CRISTOPHER -CORTEZ -ANTIONE -MALCOM -LONG -KOREY -JOSPEH -COLTON -WAYLON -VON -HOSEA -SHAD -SANTO -RUDOLF -ROLF -REY -RENALDO -MARCELLUS -LUCIUS -LESLEY -KRISTOFER -BOYCE -BENTON -MAN -KASEY -JEWELL -HAYDEN -HARLAND -ARNOLDO -RUEBEN -LEANDRO -KRAIG -JERRELL -JEROMY -HOBERT -CEDRICK -ARLIE -WINFORD -WALLY -PATRICIA -LUIGI -KENETH -JACINTO -GRAIG -FRANKLYN -EDMUNDO -SID -PORTER -LEIF -LAUREN -JERAMY -ELISHA -BUCK -WILLIAN -VINCENZO -SHON -MICHAL -LYNWOOD -LINDSAY -JEWEL -JERE -HAI -ELDEN -DORSEY -DARELL -BRODERICK -ALONSO diff --git a/src/util/uthash/tests/test15.ans b/src/util/uthash/tests/test15.ans deleted file mode 100644 index ad69a94..0000000 --- a/src/util/uthash/tests/test15.ans +++ /dev/null @@ -1 +0,0 @@ -betty's id is 2 diff --git a/src/util/uthash/tests/test15.c b/src/util/uthash/tests/test15.c deleted file mode 100644 index 93a69f3..0000000 --- a/src/util/uthash/tests/test15.c +++ /dev/null @@ -1,34 +0,0 @@ -#include /* strcpy */ -#include /* malloc */ -#include /* printf */ -#include "uthash.h" - -struct my_struct { - char name[10]; /* key */ - int id; - UT_hash_handle hh; /* makes this structure hashable */ -}; - - -int main(int argc, char *argv[]) { - const char **n, *names[] = { "joe", "bob", "betty", NULL }; - struct my_struct *s, *tmp, *users = NULL; - int i=0; - - for (n = names; *n != NULL; n++) { - s = (struct my_struct*)malloc(sizeof(struct my_struct)); - strncpy(s->name, *n,10); - s->id = i++; - HASH_ADD_STR( users, name, s ); - } - - HASH_FIND_STR( users, "betty", s); - if (s) printf("betty's id is %d\n", s->id); - - /* free the hash table contents */ - HASH_ITER(hh, users, s, tmp) { - HASH_DEL(users, s); - free(s); - } - return 0; -} diff --git a/src/util/uthash/tests/test16.ans b/src/util/uthash/tests/test16.ans deleted file mode 100644 index 1b4d7e1..0000000 --- a/src/util/uthash/tests/test16.ans +++ /dev/null @@ -1 +0,0 @@ -found: user 5, unix time 157680000 diff --git a/src/util/uthash/tests/test16.c b/src/util/uthash/tests/test16.c deleted file mode 100644 index 59b14f4..0000000 --- a/src/util/uthash/tests/test16.c +++ /dev/null @@ -1,46 +0,0 @@ -#include /* malloc */ -#include /* offsetof */ -#include /* printf */ -#include /* memset */ -#include "uthash.h" - -struct inner { - int a; - int b; -}; - -struct my_event { - struct inner is; /* key is aggregate of this field */ - char event_code; /* and this field. */ - int user_id; - UT_hash_handle hh; /* makes this structure hashable */ -}; - - -int main(int argc, char *argv[]) { - struct my_event *e, ev, *events = NULL; - unsigned i, keylen; - - keylen = offsetof(struct my_event, event_code) + sizeof(char) - - offsetof(struct my_event, is); - - for(i = 0; i < 10; i++) { - e = (struct my_event*)malloc(sizeof(struct my_event)); - memset(e,0,sizeof(struct my_event)); - e->is.a = i * (60*60*24*365); /* i years (sec)*/ - e->is.b = 0; - e->event_code = 'a'+(i%2); /* meaningless */ - e->user_id = i; - - HASH_ADD( hh, events, is, keylen, e); - } - - /* look for one specific event */ - memset(&ev,0,sizeof(struct my_event)); - ev.is.a = 5 * (60*60*24*365); - ev.is.b = 0; - ev.event_code = 'b'; - HASH_FIND( hh, events, &ev.is, keylen , e); - if (e) printf("found: user %d, unix time %d\n", e->user_id, e->is.a); - return 0; -} diff --git a/src/util/uthash/tests/test17.ans b/src/util/uthash/tests/test17.ans deleted file mode 100644 index 92ae3ef..0000000 --- a/src/util/uthash/tests/test17.ans +++ /dev/null @@ -1,134 +0,0 @@ -user 9, cookie 81 -user 8, cookie 64 -user 7, cookie 49 -user 6, cookie 36 -user 5, cookie 25 -user 4, cookie 16 -user 3, cookie 9 -user 2, cookie 4 -user 1, cookie 1 -user 0, cookie 0 -sorting -called for a:9, b:8 -called for a:7, b:6 -called for a:5, b:4 -called for a:3, b:2 -called for a:1, b:0 -called for a:8, b:6 -called for a:8, b:7 -called for a:4, b:2 -called for a:4, b:3 -called for a:6, b:2 -called for a:6, b:3 -called for a:6, b:4 -called for a:6, b:5 -called for a:2, b:0 -called for a:2, b:1 -user 0, cookie 0 -user 1, cookie 1 -user 2, cookie 4 -user 3, cookie 9 -user 4, cookie 16 -user 5, cookie 25 -user 6, cookie 36 -user 7, cookie 49 -user 8, cookie 64 -user 9, cookie 81 -adding 10-20 -user 0, cookie 0 -user 1, cookie 1 -user 2, cookie 4 -user 3, cookie 9 -user 4, cookie 16 -user 5, cookie 25 -user 6, cookie 36 -user 7, cookie 49 -user 8, cookie 64 -user 9, cookie 81 -user 20, cookie 400 -user 19, cookie 361 -user 18, cookie 324 -user 17, cookie 289 -user 16, cookie 256 -user 15, cookie 225 -user 14, cookie 196 -user 13, cookie 169 -user 12, cookie 144 -user 11, cookie 121 -user 10, cookie 100 -sorting -called for a:0, b:1 -called for a:2, b:3 -called for a:4, b:5 -called for a:6, b:7 -called for a:8, b:9 -called for a:20, b:19 -called for a:18, b:17 -called for a:16, b:15 -called for a:14, b:13 -called for a:12, b:11 -called for a:0, b:2 -called for a:1, b:2 -called for a:4, b:6 -called for a:5, b:6 -called for a:8, b:19 -called for a:9, b:19 -called for a:17, b:15 -called for a:17, b:16 -called for a:13, b:11 -called for a:13, b:12 -called for a:0, b:4 -called for a:1, b:4 -called for a:2, b:4 -called for a:3, b:4 -called for a:8, b:15 -called for a:9, b:15 -called for a:19, b:15 -called for a:19, b:16 -called for a:19, b:17 -called for a:19, b:18 -called for a:11, b:10 -called for a:0, b:8 -called for a:1, b:8 -called for a:2, b:8 -called for a:3, b:8 -called for a:4, b:8 -called for a:5, b:8 -called for a:6, b:8 -called for a:7, b:8 -called for a:0, b:10 -called for a:1, b:10 -called for a:2, b:10 -called for a:3, b:10 -called for a:4, b:10 -called for a:5, b:10 -called for a:6, b:10 -called for a:7, b:10 -called for a:8, b:10 -called for a:9, b:10 -called for a:15, b:10 -called for a:15, b:11 -called for a:15, b:12 -called for a:15, b:13 -called for a:15, b:14 -user 0, cookie 0 -user 1, cookie 1 -user 2, cookie 4 -user 3, cookie 9 -user 4, cookie 16 -user 5, cookie 25 -user 6, cookie 36 -user 7, cookie 49 -user 8, cookie 64 -user 9, cookie 81 -user 10, cookie 100 -user 11, cookie 121 -user 12, cookie 144 -user 13, cookie 169 -user 14, cookie 196 -user 15, cookie 225 -user 16, cookie 256 -user 17, cookie 289 -user 18, cookie 324 -user 19, cookie 361 -user 20, cookie 400 diff --git a/src/util/uthash/tests/test17.c b/src/util/uthash/tests/test17.c deleted file mode 100644 index 4684e45..0000000 --- a/src/util/uthash/tests/test17.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int rev(void *_a, void *_b) { - example_user_t *a = (example_user_t*)_a; - example_user_t *b = (example_user_t*)_b; - printf("called for a:%d, b:%d\n",a->id, b->id); - return (a->id - b->id); -} - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *users=NULL; - - /* create elements */ - for(i=9;i>=0;i--) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - for(user=users; user != NULL; user=(example_user_t*)user->hh.next) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - printf("sorting\n"); - HASH_SORT(users,rev); - for(user=users; user != NULL; user=(example_user_t*)user->hh.next) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - - printf("adding 10-20\n"); - for(i=20;i>=10;i--) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - for(user=users; user != NULL; user=(example_user_t*)user->hh.next) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - printf("sorting\n"); - HASH_SORT(users,rev); - for(user=users; user != NULL; user=(example_user_t*)user->hh.next) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - return 0; -} diff --git a/src/util/uthash/tests/test18.ans b/src/util/uthash/tests/test18.ans deleted file mode 100644 index db48dcf..0000000 --- a/src/util/uthash/tests/test18.ans +++ /dev/null @@ -1,20 +0,0 @@ -user 0, cookie 0 -user 1, cookie 1 -user 2, cookie 4 -user 3, cookie 9 -user 4, cookie 16 -user 5, cookie 25 -user 6, cookie 36 -user 7, cookie 49 -user 8, cookie 64 -user 9, cookie 81 -deleting id 0 -deleting id 1 -deleting id 2 -deleting id 3 -deleting id 4 -deleting id 5 -deleting id 6 -deleting id 7 -deleting id 8 -deleting id 9 diff --git a/src/util/uthash/tests/test18.c b/src/util/uthash/tests/test18.c deleted file mode 100644 index 80c4cf6..0000000 --- a/src/util/uthash/tests/test18.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *users=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - for(user=users; user != NULL; user=(example_user_t*)user->hh.next) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - - /* delete them all, pathologically */ - while(users) { - printf("deleting id %i\n", users->id); - HASH_DEL(users,users); /* single head/deletee var! */ - } - return 0; -} diff --git a/src/util/uthash/tests/test19.ans b/src/util/uthash/tests/test19.ans deleted file mode 100644 index 588d0d9..0000000 --- a/src/util/uthash/tests/test19.ans +++ /dev/null @@ -1,1012 +0,0 @@ -sorting users ascending -user 0 -user 1 -user 2 -user 3 -user 4 -user 5 -user 6 -user 7 -user 8 -user 9 -sorting altusers descending -altuser 999 -altuser 998 -altuser 997 -altuser 996 -altuser 995 -altuser 994 -altuser 993 -altuser 992 -altuser 991 -altuser 990 -altuser 989 -altuser 988 -altuser 987 -altuser 986 -altuser 985 -altuser 984 -altuser 983 -altuser 982 -altuser 981 -altuser 980 -altuser 979 -altuser 978 -altuser 977 -altuser 976 -altuser 975 -altuser 974 -altuser 973 -altuser 972 -altuser 971 -altuser 970 -altuser 969 -altuser 968 -altuser 967 -altuser 966 -altuser 965 -altuser 964 -altuser 963 -altuser 962 -altuser 961 -altuser 960 -altuser 959 -altuser 958 -altuser 957 -altuser 956 -altuser 955 -altuser 954 -altuser 953 -altuser 952 -altuser 951 -altuser 950 -altuser 949 -altuser 948 -altuser 947 -altuser 946 -altuser 945 -altuser 944 -altuser 943 -altuser 942 -altuser 941 -altuser 940 -altuser 939 -altuser 938 -altuser 937 -altuser 936 -altuser 935 -altuser 934 -altuser 933 -altuser 932 -altuser 931 -altuser 930 -altuser 929 -altuser 928 -altuser 927 -altuser 926 -altuser 925 -altuser 924 -altuser 923 -altuser 922 -altuser 921 -altuser 920 -altuser 919 -altuser 918 -altuser 917 -altuser 916 -altuser 915 -altuser 914 -altuser 913 -altuser 912 -altuser 911 -altuser 910 -altuser 909 -altuser 908 -altuser 907 -altuser 906 -altuser 905 -altuser 904 -altuser 903 -altuser 902 -altuser 901 -altuser 900 -altuser 899 -altuser 898 -altuser 897 -altuser 896 -altuser 895 -altuser 894 -altuser 893 -altuser 892 -altuser 891 -altuser 890 -altuser 889 -altuser 888 -altuser 887 -altuser 886 -altuser 885 -altuser 884 -altuser 883 -altuser 882 -altuser 881 -altuser 880 -altuser 879 -altuser 878 -altuser 877 -altuser 876 -altuser 875 -altuser 874 -altuser 873 -altuser 872 -altuser 871 -altuser 870 -altuser 869 -altuser 868 -altuser 867 -altuser 866 -altuser 865 -altuser 864 -altuser 863 -altuser 862 -altuser 861 -altuser 860 -altuser 859 -altuser 858 -altuser 857 -altuser 856 -altuser 855 -altuser 854 -altuser 853 -altuser 852 -altuser 851 -altuser 850 -altuser 849 -altuser 848 -altuser 847 -altuser 846 -altuser 845 -altuser 844 -altuser 843 -altuser 842 -altuser 841 -altuser 840 -altuser 839 -altuser 838 -altuser 837 -altuser 836 -altuser 835 -altuser 834 -altuser 833 -altuser 832 -altuser 831 -altuser 830 -altuser 829 -altuser 828 -altuser 827 -altuser 826 -altuser 825 -altuser 824 -altuser 823 -altuser 822 -altuser 821 -altuser 820 -altuser 819 -altuser 818 -altuser 817 -altuser 816 -altuser 815 -altuser 814 -altuser 813 -altuser 812 -altuser 811 -altuser 810 -altuser 809 -altuser 808 -altuser 807 -altuser 806 -altuser 805 -altuser 804 -altuser 803 -altuser 802 -altuser 801 -altuser 800 -altuser 799 -altuser 798 -altuser 797 -altuser 796 -altuser 795 -altuser 794 -altuser 793 -altuser 792 -altuser 791 -altuser 790 -altuser 789 -altuser 788 -altuser 787 -altuser 786 -altuser 785 -altuser 784 -altuser 783 -altuser 782 -altuser 781 -altuser 780 -altuser 779 -altuser 778 -altuser 777 -altuser 776 -altuser 775 -altuser 774 -altuser 773 -altuser 772 -altuser 771 -altuser 770 -altuser 769 -altuser 768 -altuser 767 -altuser 766 -altuser 765 -altuser 764 -altuser 763 -altuser 762 -altuser 761 -altuser 760 -altuser 759 -altuser 758 -altuser 757 -altuser 756 -altuser 755 -altuser 754 -altuser 753 -altuser 752 -altuser 751 -altuser 750 -altuser 749 -altuser 748 -altuser 747 -altuser 746 -altuser 745 -altuser 744 -altuser 743 -altuser 742 -altuser 741 -altuser 740 -altuser 739 -altuser 738 -altuser 737 -altuser 736 -altuser 735 -altuser 734 -altuser 733 -altuser 732 -altuser 731 -altuser 730 -altuser 729 -altuser 728 -altuser 727 -altuser 726 -altuser 725 -altuser 724 -altuser 723 -altuser 722 -altuser 721 -altuser 720 -altuser 719 -altuser 718 -altuser 717 -altuser 716 -altuser 715 -altuser 714 -altuser 713 -altuser 712 -altuser 711 -altuser 710 -altuser 709 -altuser 708 -altuser 707 -altuser 706 -altuser 705 -altuser 704 -altuser 703 -altuser 702 -altuser 701 -altuser 700 -altuser 699 -altuser 698 -altuser 697 -altuser 696 -altuser 695 -altuser 694 -altuser 693 -altuser 692 -altuser 691 -altuser 690 -altuser 689 -altuser 688 -altuser 687 -altuser 686 -altuser 685 -altuser 684 -altuser 683 -altuser 682 -altuser 681 -altuser 680 -altuser 679 -altuser 678 -altuser 677 -altuser 676 -altuser 675 -altuser 674 -altuser 673 -altuser 672 -altuser 671 -altuser 670 -altuser 669 -altuser 668 -altuser 667 -altuser 666 -altuser 665 -altuser 664 -altuser 663 -altuser 662 -altuser 661 -altuser 660 -altuser 659 -altuser 658 -altuser 657 -altuser 656 -altuser 655 -altuser 654 -altuser 653 -altuser 652 -altuser 651 -altuser 650 -altuser 649 -altuser 648 -altuser 647 -altuser 646 -altuser 645 -altuser 644 -altuser 643 -altuser 642 -altuser 641 -altuser 640 -altuser 639 -altuser 638 -altuser 637 -altuser 636 -altuser 635 -altuser 634 -altuser 633 -altuser 632 -altuser 631 -altuser 630 -altuser 629 -altuser 628 -altuser 627 -altuser 626 -altuser 625 -altuser 624 -altuser 623 -altuser 622 -altuser 621 -altuser 620 -altuser 619 -altuser 618 -altuser 617 -altuser 616 -altuser 615 -altuser 614 -altuser 613 -altuser 612 -altuser 611 -altuser 610 -altuser 609 -altuser 608 -altuser 607 -altuser 606 -altuser 605 -altuser 604 -altuser 603 -altuser 602 -altuser 601 -altuser 600 -altuser 599 -altuser 598 -altuser 597 -altuser 596 -altuser 595 -altuser 594 -altuser 593 -altuser 592 -altuser 591 -altuser 590 -altuser 589 -altuser 588 -altuser 587 -altuser 586 -altuser 585 -altuser 584 -altuser 583 -altuser 582 -altuser 581 -altuser 580 -altuser 579 -altuser 578 -altuser 577 -altuser 576 -altuser 575 -altuser 574 -altuser 573 -altuser 572 -altuser 571 -altuser 570 -altuser 569 -altuser 568 -altuser 567 -altuser 566 -altuser 565 -altuser 564 -altuser 563 -altuser 562 -altuser 561 -altuser 560 -altuser 559 -altuser 558 -altuser 557 -altuser 556 -altuser 555 -altuser 554 -altuser 553 -altuser 552 -altuser 551 -altuser 550 -altuser 549 -altuser 548 -altuser 547 -altuser 546 -altuser 545 -altuser 544 -altuser 543 -altuser 542 -altuser 541 -altuser 540 -altuser 539 -altuser 538 -altuser 537 -altuser 536 -altuser 535 -altuser 534 -altuser 533 -altuser 532 -altuser 531 -altuser 530 -altuser 529 -altuser 528 -altuser 527 -altuser 526 -altuser 525 -altuser 524 -altuser 523 -altuser 522 -altuser 521 -altuser 520 -altuser 519 -altuser 518 -altuser 517 -altuser 516 -altuser 515 -altuser 514 -altuser 513 -altuser 512 -altuser 511 -altuser 510 -altuser 509 -altuser 508 -altuser 507 -altuser 506 -altuser 505 -altuser 504 -altuser 503 -altuser 502 -altuser 501 -altuser 500 -altuser 499 -altuser 498 -altuser 497 -altuser 496 -altuser 495 -altuser 494 -altuser 493 -altuser 492 -altuser 491 -altuser 490 -altuser 489 -altuser 488 -altuser 487 -altuser 486 -altuser 485 -altuser 484 -altuser 483 -altuser 482 -altuser 481 -altuser 480 -altuser 479 -altuser 478 -altuser 477 -altuser 476 -altuser 475 -altuser 474 -altuser 473 -altuser 472 -altuser 471 -altuser 470 -altuser 469 -altuser 468 -altuser 467 -altuser 466 -altuser 465 -altuser 464 -altuser 463 -altuser 462 -altuser 461 -altuser 460 -altuser 459 -altuser 458 -altuser 457 -altuser 456 -altuser 455 -altuser 454 -altuser 453 -altuser 452 -altuser 451 -altuser 450 -altuser 449 -altuser 448 -altuser 447 -altuser 446 -altuser 445 -altuser 444 -altuser 443 -altuser 442 -altuser 441 -altuser 440 -altuser 439 -altuser 438 -altuser 437 -altuser 436 -altuser 435 -altuser 434 -altuser 433 -altuser 432 -altuser 431 -altuser 430 -altuser 429 -altuser 428 -altuser 427 -altuser 426 -altuser 425 -altuser 424 -altuser 423 -altuser 422 -altuser 421 -altuser 420 -altuser 419 -altuser 418 -altuser 417 -altuser 416 -altuser 415 -altuser 414 -altuser 413 -altuser 412 -altuser 411 -altuser 410 -altuser 409 -altuser 408 -altuser 407 -altuser 406 -altuser 405 -altuser 404 -altuser 403 -altuser 402 -altuser 401 -altuser 400 -altuser 399 -altuser 398 -altuser 397 -altuser 396 -altuser 395 -altuser 394 -altuser 393 -altuser 392 -altuser 391 -altuser 390 -altuser 389 -altuser 388 -altuser 387 -altuser 386 -altuser 385 -altuser 384 -altuser 383 -altuser 382 -altuser 381 -altuser 380 -altuser 379 -altuser 378 -altuser 377 -altuser 376 -altuser 375 -altuser 374 -altuser 373 -altuser 372 -altuser 371 -altuser 370 -altuser 369 -altuser 368 -altuser 367 -altuser 366 -altuser 365 -altuser 364 -altuser 363 -altuser 362 -altuser 361 -altuser 360 -altuser 359 -altuser 358 -altuser 357 -altuser 356 -altuser 355 -altuser 354 -altuser 353 -altuser 352 -altuser 351 -altuser 350 -altuser 349 -altuser 348 -altuser 347 -altuser 346 -altuser 345 -altuser 344 -altuser 343 -altuser 342 -altuser 341 -altuser 340 -altuser 339 -altuser 338 -altuser 337 -altuser 336 -altuser 335 -altuser 334 -altuser 333 -altuser 332 -altuser 331 -altuser 330 -altuser 329 -altuser 328 -altuser 327 -altuser 326 -altuser 325 -altuser 324 -altuser 323 -altuser 322 -altuser 321 -altuser 320 -altuser 319 -altuser 318 -altuser 317 -altuser 316 -altuser 315 -altuser 314 -altuser 313 -altuser 312 -altuser 311 -altuser 310 -altuser 309 -altuser 308 -altuser 307 -altuser 306 -altuser 305 -altuser 304 -altuser 303 -altuser 302 -altuser 301 -altuser 300 -altuser 299 -altuser 298 -altuser 297 -altuser 296 -altuser 295 -altuser 294 -altuser 293 -altuser 292 -altuser 291 -altuser 290 -altuser 289 -altuser 288 -altuser 287 -altuser 286 -altuser 285 -altuser 284 -altuser 283 -altuser 282 -altuser 281 -altuser 280 -altuser 279 -altuser 278 -altuser 277 -altuser 276 -altuser 275 -altuser 274 -altuser 273 -altuser 272 -altuser 271 -altuser 270 -altuser 269 -altuser 268 -altuser 267 -altuser 266 -altuser 265 -altuser 264 -altuser 263 -altuser 262 -altuser 261 -altuser 260 -altuser 259 -altuser 258 -altuser 257 -altuser 256 -altuser 255 -altuser 254 -altuser 253 -altuser 252 -altuser 251 -altuser 250 -altuser 249 -altuser 248 -altuser 247 -altuser 246 -altuser 245 -altuser 244 -altuser 243 -altuser 242 -altuser 241 -altuser 240 -altuser 239 -altuser 238 -altuser 237 -altuser 236 -altuser 235 -altuser 234 -altuser 233 -altuser 232 -altuser 231 -altuser 230 -altuser 229 -altuser 228 -altuser 227 -altuser 226 -altuser 225 -altuser 224 -altuser 223 -altuser 222 -altuser 221 -altuser 220 -altuser 219 -altuser 218 -altuser 217 -altuser 216 -altuser 215 -altuser 214 -altuser 213 -altuser 212 -altuser 211 -altuser 210 -altuser 209 -altuser 208 -altuser 207 -altuser 206 -altuser 205 -altuser 204 -altuser 203 -altuser 202 -altuser 201 -altuser 200 -altuser 199 -altuser 198 -altuser 197 -altuser 196 -altuser 195 -altuser 194 -altuser 193 -altuser 192 -altuser 191 -altuser 190 -altuser 189 -altuser 188 -altuser 187 -altuser 186 -altuser 185 -altuser 184 -altuser 183 -altuser 182 -altuser 181 -altuser 180 -altuser 179 -altuser 178 -altuser 177 -altuser 176 -altuser 175 -altuser 174 -altuser 173 -altuser 172 -altuser 171 -altuser 170 -altuser 169 -altuser 168 -altuser 167 -altuser 166 -altuser 165 -altuser 164 -altuser 163 -altuser 162 -altuser 161 -altuser 160 -altuser 159 -altuser 158 -altuser 157 -altuser 156 -altuser 155 -altuser 154 -altuser 153 -altuser 152 -altuser 151 -altuser 150 -altuser 149 -altuser 148 -altuser 147 -altuser 146 -altuser 145 -altuser 144 -altuser 143 -altuser 142 -altuser 141 -altuser 140 -altuser 139 -altuser 138 -altuser 137 -altuser 136 -altuser 135 -altuser 134 -altuser 133 -altuser 132 -altuser 131 -altuser 130 -altuser 129 -altuser 128 -altuser 127 -altuser 126 -altuser 125 -altuser 124 -altuser 123 -altuser 122 -altuser 121 -altuser 120 -altuser 119 -altuser 118 -altuser 117 -altuser 116 -altuser 115 -altuser 114 -altuser 113 -altuser 112 -altuser 111 -altuser 110 -altuser 109 -altuser 108 -altuser 107 -altuser 106 -altuser 105 -altuser 104 -altuser 103 -altuser 102 -altuser 101 -altuser 100 -altuser 99 -altuser 98 -altuser 97 -altuser 96 -altuser 95 -altuser 94 -altuser 93 -altuser 92 -altuser 91 -altuser 90 -altuser 89 -altuser 88 -altuser 87 -altuser 86 -altuser 85 -altuser 84 -altuser 83 -altuser 82 -altuser 81 -altuser 80 -altuser 79 -altuser 78 -altuser 77 -altuser 76 -altuser 75 -altuser 74 -altuser 73 -altuser 72 -altuser 71 -altuser 70 -altuser 69 -altuser 68 -altuser 67 -altuser 66 -altuser 65 -altuser 64 -altuser 63 -altuser 62 -altuser 61 -altuser 60 -altuser 59 -altuser 58 -altuser 57 -altuser 56 -altuser 55 -altuser 54 -altuser 53 -altuser 52 -altuser 51 -altuser 50 -altuser 49 -altuser 48 -altuser 47 -altuser 46 -altuser 45 -altuser 44 -altuser 43 -altuser 42 -altuser 41 -altuser 40 -altuser 39 -altuser 38 -altuser 37 -altuser 36 -altuser 35 -altuser 34 -altuser 33 -altuser 32 -altuser 31 -altuser 30 -altuser 29 -altuser 28 -altuser 27 -altuser 26 -altuser 25 -altuser 24 -altuser 23 -altuser 22 -altuser 21 -altuser 20 -altuser 19 -altuser 18 -altuser 17 -altuser 16 -altuser 15 -altuser 14 -altuser 13 -altuser 12 -altuser 11 -altuser 10 -altuser 9 -altuser 8 -altuser 7 -altuser 6 -altuser 5 -altuser 4 -altuser 3 -altuser 2 -altuser 1 -altuser 0 diff --git a/src/util/uthash/tests/test19.c b/src/util/uthash/tests/test19.c deleted file mode 100644 index f0e26b6..0000000 --- a/src/util/uthash/tests/test19.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; - UT_hash_handle alth; -} example_user_t; - -int ascending_sort(void *_a, void *_b) { - example_user_t *a = (example_user_t*)_a; - example_user_t *b = (example_user_t*)_b; - if (a->id == b->id) return 0; - return (a->id < b->id) ? -1 : 1; -} - -int descending_sort(void *_a, void *_b) { - example_user_t *a = (example_user_t*)_a; - example_user_t *b = (example_user_t*)_b; - if (a->id == b->id) return 0; - return (a->id < b->id) ? 1 : -1; -} - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *users=NULL, *altusers=NULL; - - /* create elements */ - for(i=0;i<1000;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - if (i<10) HASH_ADD_INT(users,id,user); - HASH_ADD(alth,altusers,id,sizeof(int),user); - } - - printf("sorting users ascending\n"); - HASH_SRT(hh,users,ascending_sort); - for(user=users; user; user=(example_user_t*)user->hh.next) - printf("user %d\n", user->id); - - printf("sorting altusers descending\n"); - HASH_SRT(alth,altusers,descending_sort); - for(user=altusers; user; user=(example_user_t*)user->alth.next) - printf("altuser %d\n", user->id); - - /* HASH_FSCK(hh,users); */ - /* HASH_FSCK(alth,altusers); */ - return 0; -} diff --git a/src/util/uthash/tests/test2.ans b/src/util/uthash/tests/test2.ans deleted file mode 100644 index fd4e2f8..0000000 --- a/src/util/uthash/tests/test2.ans +++ /dev/null @@ -1,5 +0,0 @@ -user id 0 found, cookie 0 -user id 2 found, cookie 4 -user id 4 found, cookie 16 -user id 6 found, cookie 36 -user id 8 found, cookie 64 diff --git a/src/util/uthash/tests/test2.c b/src/util/uthash/tests/test2.c deleted file mode 100644 index 591ca79..0000000 --- a/src/util/uthash/tests/test2.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "uthash.h" -#include -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *tmp, *users=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - /* find each even ID */ - for(i=0;i<10;i+=2) { - HASH_FIND_INT(users,&i,tmp); - if (tmp) printf("user id %d found, cookie %d\n", tmp->id, tmp->cookie); - else printf("user id %d not found\n", i); - } - return 0; -} diff --git a/src/util/uthash/tests/test20.ans b/src/util/uthash/tests/test20.ans deleted file mode 100644 index 4d3bb1d..0000000 --- a/src/util/uthash/tests/test20.ans +++ /dev/null @@ -1 +0,0 @@ -found diff --git a/src/util/uthash/tests/test20.c b/src/util/uthash/tests/test20.c deleted file mode 100644 index 152df39..0000000 --- a/src/util/uthash/tests/test20.c +++ /dev/null @@ -1,28 +0,0 @@ -#include /* memcpy */ -#include /* malloc */ -#include /* printf */ -#include "uthash.h" - -struct my_struct { - char bkey[5]; /* "binary" key */ - int data; - UT_hash_handle hh; -}; - -int main(int argc, char *argv[]) { - struct my_struct *s, *t, *bins = NULL; - char binary[5] = {3,1,4,1,6}; - - /* allocate our structure. initialize to some values */ - s = (struct my_struct*)calloc(1,sizeof(struct my_struct)); - memcpy(s->bkey, binary, sizeof(binary)); - - /* add to hash table using general macro */ - HASH_ADD( hh, bins, bkey, sizeof(binary), s); - - /* look up the structure we just added */ - HASH_FIND( hh, bins, binary, sizeof(binary), t ); - - if (t) printf("found\n"); - return 0; -} diff --git a/src/util/uthash/tests/test21.ans b/src/util/uthash/tests/test21.ans deleted file mode 100644 index af89f48..0000000 --- a/src/util/uthash/tests/test21.ans +++ /dev/null @@ -1 +0,0 @@ -found a 1 diff --git a/src/util/uthash/tests/test21.c b/src/util/uthash/tests/test21.c deleted file mode 100644 index 6043554..0000000 --- a/src/util/uthash/tests/test21.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include "uthash.h" - -typedef struct { - char a; - int b; -} record_key_t; - -typedef struct { - record_key_t key; - /* ... other data ... */ - UT_hash_handle hh; -} record_t; - -int main(int argc, char *argv[]) { - record_t l, *p, *r, *tmp, *records = NULL; - - r = (record_t*)malloc( sizeof(record_t) ); - memset(r, 0, sizeof(record_t)); - r->key.a = 'a'; - r->key.b = 1; - HASH_ADD(hh, records, key, sizeof(record_key_t), r); - - memset(&l, 0, sizeof(record_t)); - l.key.a = 'a'; - l.key.b = 1; - HASH_FIND(hh, records, &l.key, sizeof(record_key_t), p); - - if (p) printf("found %c %d\n", p->key.a, p->key.b); - - HASH_ITER(hh, records, p, tmp) { - HASH_DEL(records, p); - free(p); - } - return 0; -} - diff --git a/src/util/uthash/tests/test22.ans b/src/util/uthash/tests/test22.ans deleted file mode 100644 index 2483a24..0000000 --- a/src/util/uthash/tests/test22.ans +++ /dev/null @@ -1 +0,0 @@ -found diff --git a/src/util/uthash/tests/test22.c b/src/util/uthash/tests/test22.c deleted file mode 100644 index 3435074..0000000 --- a/src/util/uthash/tests/test22.c +++ /dev/null @@ -1,59 +0,0 @@ -#include /* malloc */ -#include /* offsetof */ -#include /* printf */ -#include /* memset */ -#include "uthash.h" - -#define UTF32 1 - -typedef struct { - UT_hash_handle hh; - int len; - char encoding; /* these two fields */ - int text[]; /* comprise the key */ -} msg_t; - -typedef struct { - char encoding; - int text[]; -} lookup_key_t; - -int main(int argc, char *argv[]) { - unsigned keylen; - msg_t *msg, *tmp, *msgs = NULL; - lookup_key_t *lookup_key; - - int beijing[] = {0x5317, 0x4eac}; /* UTF-32LE for 北京 */ - - /* allocate and initialize our structure */ - msg = (msg_t*)malloc( sizeof(msg_t) + sizeof(beijing) ); - memset(msg, 0, sizeof(msg_t)+sizeof(beijing)); /* zero fill */ - msg->len = sizeof(beijing); - msg->encoding = UTF32; - memcpy(msg->text, beijing, sizeof(beijing)); - - /* calculate the key length including padding, using formula */ - keylen = offsetof(msg_t, text) /* offset of last key field */ - + sizeof(beijing) /* size of last key field */ - - offsetof(msg_t, encoding); /* offset of first key field */ - - /* add our structure to the hash table */ - HASH_ADD( hh, msgs, encoding, keylen, msg); - - /* look it up to prove that it worked :-) */ - msg=NULL; - - lookup_key = (lookup_key_t*)malloc(sizeof(*lookup_key) + sizeof(beijing)); - memset(lookup_key, 0, sizeof(*lookup_key) + sizeof(beijing)); - lookup_key->encoding = UTF32; - memcpy(lookup_key->text, beijing, sizeof(beijing)); - HASH_FIND( hh, msgs, &lookup_key->encoding, keylen, msg ); - if (msg) printf("found \n"); - free(lookup_key); - - HASH_ITER(hh, msgs, msg, tmp) { - HASH_DEL(msgs, msg); - free(msg); - } - return 0; -} diff --git a/src/util/uthash/tests/test23.ans b/src/util/uthash/tests/test23.ans deleted file mode 100644 index 79ed10a..0000000 --- a/src/util/uthash/tests/test23.ans +++ /dev/null @@ -1,6 +0,0 @@ -found 12345 -found 6789 -found 98765 -deleting 12345 -deleting 6789 -deleting 98765 diff --git a/src/util/uthash/tests/test23.c b/src/util/uthash/tests/test23.c deleted file mode 100644 index 78b633c..0000000 --- a/src/util/uthash/tests/test23.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include "uthash.h" - -typedef struct { - int key; - int data; - UT_hash_handle hh; -} item; - -int main() { - item *i, *j, *items=NULL; - int k; - - /* first item */ - k = 12345; - i = (item*)malloc(sizeof(item)); - i->key = k; i->data = 0; - HASH_ADD_INT(items,key,i); - - /* second item */ - k = 6789; - i = (item*)malloc(sizeof(item)); - i->key = k; i->data = 0; - HASH_ADD_INT(items,key,i); - - /* third item */ - k = 98765; - i = (item*)malloc(sizeof(item)); - i->key = k; i->data = 0; - HASH_ADD_INT(items,key,i); - - /* look them all up */ - k = 12345; HASH_FIND_INT(items, &k, j); if (j) printf("found %d\n",k); - k = 6789; HASH_FIND_INT(items, &k, j); if (j) printf("found %d\n",k); - k = 98765; HASH_FIND_INT(items, &k, j); if (j) printf("found %d\n",k); - - /* delete them not the way we prefer but it works */ - for(j=items; j != NULL; j=(item*)j->hh.next) { - printf("deleting %d\n", j->key); - HASH_DEL(items,j); - } - return 0; -} diff --git a/src/util/uthash/tests/test24.ans b/src/util/uthash/tests/test24.ans deleted file mode 100644 index 4a2034a..0000000 --- a/src/util/uthash/tests/test24.ans +++ /dev/null @@ -1 +0,0 @@ -hash contains 10 items diff --git a/src/util/uthash/tests/test24.c b/src/util/uthash/tests/test24.c deleted file mode 100644 index 28d3bf4..0000000 --- a/src/util/uthash/tests/test24.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *users=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - printf("hash contains %d items\n", HASH_COUNT(users)); - return 0; -} diff --git a/src/util/uthash/tests/test25.ans b/src/util/uthash/tests/test25.ans deleted file mode 100644 index 5c71cdf..0000000 --- a/src/util/uthash/tests/test25.ans +++ /dev/null @@ -1,28 +0,0 @@ -CDL macros -c b a -advancing head pointer -b a c -b a c b a c b a c b -b c a b c a b c a b -deleting b -a c -deleting (a) -c -deleting (c) - -DL macros -a b c -deleting tail c -a b -deleting head a -b -deleting head b - -LL macros -a b c -deleting tail c -a b -deleting head a -b -deleting head b - diff --git a/src/util/uthash/tests/test25.c b/src/util/uthash/tests/test25.c deleted file mode 100644 index c22be85..0000000 --- a/src/util/uthash/tests/test25.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *head = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[10], *e; - for(i=0;i<10;i++) els[i].id='a'+i; - - /* test CDL macros */ - printf("CDL macros\n"); - CDL_PREPEND(head,&els[0]); - CDL_PREPEND(head,&els[1]); - CDL_PREPEND(head,&els[2]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* point head to head->next */ - printf("advancing head pointer\n"); - head = head->next; - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* follow circular loop a few times */ - for(i=0,e=head;e && i<10;i++,e=e->next) - printf("%c ", e->id); - printf("\n"); - - /* follow circular loop backwards a few times */ - for(i=0,e=head;e && i<10;i++,e=e->prev) - printf("%c ", e->id); - printf("\n"); - - printf("deleting b\n"); - CDL_DELETE(head,&els[1]); - CDL_FOREACH(head,e) printf("%c ", e->id); - printf("\n"); - printf("deleting (a)\n"); - CDL_DELETE(head,&els[0]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - printf("deleting (c)\n"); - CDL_DELETE(head,&els[2]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* test DL macros */ - printf("DL macros\n"); - DL_APPEND(head,&els[0]); - DL_APPEND(head,&els[1]); - DL_APPEND(head,&els[2]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting tail c\n"); - DL_DELETE(head,&els[2]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting head a\n"); - DL_DELETE(head,&els[0]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting head b\n"); - DL_DELETE(head,&els[1]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* test LL macros */ - printf("LL macros\n"); - LL_APPEND(head,&els[0]); - LL_APPEND(head,&els[1]); - LL_APPEND(head,&els[2]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting tail c\n"); - LL_DELETE(head,&els[2]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting head a\n"); - LL_DELETE(head,&els[0]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting head b\n"); - LL_DELETE(head,&els[1]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test26.ans b/src/util/uthash/tests/test26.ans deleted file mode 100644 index 764b01d..0000000 --- a/src/util/uthash/tests/test26.ans +++ /dev/null @@ -1,53 +0,0 @@ -ADRIAN -ARNOLDO -CARROLL -CARY -CHONG -CLIFTON -CODY -COLTON -CORNELL -DAMON -DANNIE -DARIO -DONN -DOUG -DOUGLAS -FREDERICK -FRITZ -GERALD -GUS -HARVEY -IRVING -ISAIAH -JARVIS -JOHN -KENTON -LAURENCE -LESTER -LINCOLN -LOWELL -NELSON -NEVILLE -NIGEL -NORMAND -ODIS -OMAR -ORLANDO -RAYMUNDO -REX -ROLANDO -RON -SHANE -TONEY -TRINIDAD -WALTER -WARNER -WARREN -WES -WILLARD -WILLIAM -WINFRED -XAVIER -found WES - diff --git a/src/util/uthash/tests/test26.c b/src/util/uthash/tests/test26.c deleted file mode 100644 index 0627739..0000000 --- a/src/util/uthash/tests/test26.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include "utlist.h" - -#define BUFLEN 20 - -typedef struct el { - char bname[BUFLEN]; - struct el *next, *prev; -} el; - -int namecmp(void *_a, void *_b) { - el *a = (el*)_a; - el *b = (el*)_b; - return strcmp(a->bname,b->bname); -} - -el *head = NULL; /* important- initialize to NULL! */ - -int main(int argc, char *argv[]) { - el *name, *elt, *tmp, etmp; - - char linebuf[BUFLEN]; - FILE *file; - - if ( (file = fopen( "test11.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); - strncpy(name->bname,linebuf,BUFLEN); - DL_APPEND(head, name); - } - DL_SORT(head, namecmp); - DL_FOREACH(head,elt) printf("%s", elt->bname); - - memcpy(&etmp.bname, "WES\n", 5); - DL_SEARCH(head,elt,&etmp,namecmp); - if (elt) printf("found %s\n", elt->bname); - - /* now delete each element, use the safe iterator */ - DL_FOREACH_SAFE(head,elt,tmp) { - DL_DELETE(head,elt); - } - - fclose(file); - - return 0; -} diff --git a/src/util/uthash/tests/test27.ans b/src/util/uthash/tests/test27.ans deleted file mode 100644 index 80b476c..0000000 --- a/src/util/uthash/tests/test27.ans +++ /dev/null @@ -1,28 +0,0 @@ -CDL macros -c b a -advancing head pointer -b a c -b a c b a c b a c b -b c a b c a b c a b -deleting b -a c -deleting head (a) -c -deleting new head (c) - -DL macros -c b a -deleting c -b a -deleting a -b -deleting b - -LL macros -c b a -deleting c -b a -deleting a -b -deleting b - diff --git a/src/util/uthash/tests/test27.c b/src/util/uthash/tests/test27.c deleted file mode 100644 index 1b33e8c..0000000 --- a/src/util/uthash/tests/test27.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *head = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[10], *e; - for(i=0;i<10;i++) els[i].id='a'+i; - - /* test CDL macros */ - printf("CDL macros\n"); - CDL_PREPEND(head,&els[0]); - CDL_PREPEND(head,&els[1]); - CDL_PREPEND(head,&els[2]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* point head to head->next */ - printf("advancing head pointer\n"); - head = head->next; - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* follow circular loop a few times */ - for(i=0,e=head;e && i<10;i++,e=e->next) - printf("%c ", e->id); - printf("\n"); - - /* follow circular loop backwards a few times */ - for(i=0,e=head;e && i<10;i++,e=e->prev) - printf("%c ", e->id); - printf("\n"); - - printf("deleting b\n"); - CDL_DELETE(head,&els[1]); - CDL_FOREACH(head,e) printf("%c ", e->id); - printf("\n"); - printf("deleting head (a)\n"); - CDL_DELETE(head,&els[0]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - printf("deleting new head (c)\n"); - CDL_DELETE(head,&els[2]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* test DL macros */ - printf("DL macros\n"); - DL_PREPEND(head,&els[0]); - DL_PREPEND(head,&els[1]); - DL_PREPEND(head,&els[2]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting c\n"); - DL_DELETE(head,&els[2]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting a\n"); - DL_DELETE(head,&els[0]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting b\n"); - DL_DELETE(head,&els[1]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* test LL macros */ - printf("LL macros\n"); - LL_PREPEND(head,&els[0]); - LL_PREPEND(head,&els[1]); - LL_PREPEND(head,&els[2]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting c\n"); - LL_DELETE(head,&els[2]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting a\n"); - LL_DELETE(head,&els[0]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting b\n"); - LL_DELETE(head,&els[1]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test28.ans b/src/util/uthash/tests/test28.ans deleted file mode 100644 index eb88650..0000000 --- a/src/util/uthash/tests/test28.ans +++ /dev/null @@ -1,34 +0,0 @@ -CDL macros -d c b a -advancing head pointer -c b a d -c b a d c b a d c b -c d a b c d a b c d -deleting b -c a d -deleting (a) -c d -deleting (c) -d -deleting (d) - -DL macros -c b a d -deleting c -b a d -deleting a -b d -deleting b -d -deleting d - -LL macros -c b a d -deleting c -b a d -deleting a -b d -deleting b -d -deleting d - diff --git a/src/util/uthash/tests/test28.c b/src/util/uthash/tests/test28.c deleted file mode 100644 index 279d891..0000000 --- a/src/util/uthash/tests/test28.c +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *head = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[10], *e; - for(i=0;i<10;i++) els[i].id='a'+i; - - /* test CDL macros */ - printf("CDL macros\n"); - CDL_PREPEND(head,&els[0]); - CDL_PREPEND(head,&els[1]); - CDL_PREPEND(head,&els[2]); - CDL_PREPEND(head,&els[3]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* point head to head->next */ - printf("advancing head pointer\n"); - head = head->next; - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* follow circular loop a few times */ - for(i=0,e=head;e && i<10;i++,e=e->next) - printf("%c ", e->id); - printf("\n"); - - /* follow circular loop backwards a few times */ - for(i=0,e=head;e && i<10;i++,e=e->prev) - printf("%c ", e->id); - printf("\n"); - - printf("deleting b\n"); - CDL_DELETE(head,&els[1]); - CDL_FOREACH(head,e) printf("%c ", e->id); - printf("\n"); - printf("deleting (a)\n"); - CDL_DELETE(head,&els[0]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - printf("deleting (c)\n"); - CDL_DELETE(head,&els[2]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - printf("deleting (d)\n"); - CDL_DELETE(head,&els[3]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* test DL macros */ - printf("DL macros\n"); - DL_PREPEND(head,&els[0]); - DL_PREPEND(head,&els[1]); - DL_PREPEND(head,&els[2]); - DL_APPEND(head,&els[3]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting c\n"); - DL_DELETE(head,&els[2]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting a\n"); - DL_DELETE(head,&els[0]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting b\n"); - DL_DELETE(head,&els[1]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting d\n"); - DL_DELETE(head,&els[3]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - /* test LL macros */ - printf("LL macros\n"); - LL_PREPEND(head,&els[0]); - LL_PREPEND(head,&els[1]); - LL_PREPEND(head,&els[2]); - LL_APPEND(head,&els[3]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting c\n"); - LL_DELETE(head,&els[2]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting a\n"); - LL_DELETE(head,&els[0]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting b\n"); - LL_DELETE(head,&els[1]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - printf("deleting d\n"); - LL_DELETE(head,&els[3]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test29.ans b/src/util/uthash/tests/test29.ans deleted file mode 100644 index 6467b60..0000000 --- a/src/util/uthash/tests/test29.ans +++ /dev/null @@ -1,103 +0,0 @@ -ADRIAN -ARNOLDO -CARROLL -CARY -CHONG -CLIFTON -CODY -COLTON -CORNELL -DAMON -DANNIE -DARIO -DONN -DOUG -DOUGLAS -FREDERICK -FRITZ -GERALD -GUS -HARVEY -IRVING -ISAIAH -JARVIS -JOHN -KENTON -LAURENCE -LESTER -LINCOLN -LOWELL -NELSON -NEVILLE -NIGEL -NORMAND -ODIS -OMAR -ORLANDO -RAYMUNDO -REX -ROLANDO -RON -SHANE -TONEY -TRINIDAD -WALTER -WARNER -WARREN -WES -WILLARD -WILLIAM -WINFRED -XAVIER -deleting head ADRIAN -head->prev: XAVIER -ARNOLDO -CARROLL -CARY -CHONG -CLIFTON -CODY -COLTON -CORNELL -DAMON -DANNIE -DARIO -DONN -DOUG -DOUGLAS -FREDERICK -FRITZ -GERALD -GUS -HARVEY -IRVING -ISAIAH -JARVIS -JOHN -KENTON -LAURENCE -LESTER -LINCOLN -LOWELL -NELSON -NEVILLE -NIGEL -NORMAND -ODIS -OMAR -ORLANDO -RAYMUNDO -REX -ROLANDO -RON -SHANE -TONEY -TRINIDAD -WALTER -WARNER -WARREN -WES -WILLARD -WILLIAM -WINFRED -XAVIER diff --git a/src/util/uthash/tests/test29.c b/src/util/uthash/tests/test29.c deleted file mode 100644 index 8e54a02..0000000 --- a/src/util/uthash/tests/test29.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include "utlist.h" - -#define BUFLEN 20 - -typedef struct el { - char bname[BUFLEN]; - struct el *next, *prev; -} el; - -int namecmp(void *_a, void *_b) { - el *a = (el*)_a; - el *b = (el*)_b; - return strcmp(a->bname,b->bname); -} - -el *head = NULL; - -int main(int argc, char *argv[]) { - el *name, *tmp; - - char linebuf[BUFLEN]; - FILE *file; - - if ( (file = fopen( "test11.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); - strncpy(name->bname,linebuf,BUFLEN); - DL_APPEND(head, name); - } - DL_SORT(head, namecmp); - DL_FOREACH(head,tmp) printf("%s", tmp->bname); - - /* now delete the list head */ - printf("deleting head %shead->prev: %s", head->bname, head->prev->bname); - DL_DELETE(head,head); - DL_FOREACH(head,tmp) printf("%s", tmp->bname); - - fclose(file); - - return 0; -} diff --git a/src/util/uthash/tests/test3.ans b/src/util/uthash/tests/test3.ans deleted file mode 100644 index 56a52a3..0000000 --- a/src/util/uthash/tests/test3.ans +++ /dev/null @@ -1,5 +0,0 @@ -user 1, cookie 1 -user 3, cookie 9 -user 5, cookie 25 -user 7, cookie 49 -user 9, cookie 81 diff --git a/src/util/uthash/tests/test3.c b/src/util/uthash/tests/test3.c deleted file mode 100644 index 3f3e479..0000000 --- a/src/util/uthash/tests/test3.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *tmp, *users=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) - exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - /* delete each even ID */ - for(i=0;i<10;i+=2) { - HASH_FIND_INT(users,&i,tmp); - if (tmp) { - HASH_DEL(users,tmp); - free(tmp); - } else printf("user id %d not found\n", i); - } - - /* show the hash */ - for(user=users; user != NULL; user=(example_user_t*)(user->hh.next)) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - return 0; -} diff --git a/src/util/uthash/tests/test30.ans b/src/util/uthash/tests/test30.ans deleted file mode 100644 index 2b72e98..0000000 --- a/src/util/uthash/tests/test30.ans +++ /dev/null @@ -1,51 +0,0 @@ -ADRIAN -ARNOLDO -CARROLL -CARY -CHONG -CLIFTON -CODY -COLTON -CORNELL -DAMON -DANNIE -DARIO -DONN -DOUG -DOUGLAS -FREDERICK -FRITZ -GERALD -GUS -HARVEY -IRVING -ISAIAH -JARVIS -JOHN -KENTON -LAURENCE -LESTER -LINCOLN -LOWELL -NELSON -NEVILLE -NIGEL -NORMAND -ODIS -OMAR -ORLANDO -RAYMUNDO -REX -ROLANDO -RON -SHANE -TONEY -TRINIDAD -WALTER -WARNER -WARREN -WES -WILLARD -WILLIAM -WINFRED -XAVIER diff --git a/src/util/uthash/tests/test30.c b/src/util/uthash/tests/test30.c deleted file mode 100644 index 711c7d9..0000000 --- a/src/util/uthash/tests/test30.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include "utlist.h" - -#define BUFLEN 20 - -typedef struct el { - char bname[BUFLEN]; - struct el *next, *prev; -} el; - -int namecmp(void *_a, void *_b) { - el *a = (el*)_a; - el *b = (el*)_b; - return strcmp(a->bname,b->bname); -} - -el *head = NULL; - -int main(int argc, char *argv[]) { - el *name, *tmp; - - char linebuf[BUFLEN]; - FILE *file; - - if ( (file = fopen( "test11.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); - strncpy(name->bname,linebuf,BUFLEN); - CDL_PREPEND(head, name); - } - CDL_SORT(head, namecmp); - CDL_FOREACH(head,tmp) printf("%s", tmp->bname); - - fclose(file); - - return 0; -} diff --git a/src/util/uthash/tests/test31.ans b/src/util/uthash/tests/test31.ans deleted file mode 100644 index 2b72e98..0000000 --- a/src/util/uthash/tests/test31.ans +++ /dev/null @@ -1,51 +0,0 @@ -ADRIAN -ARNOLDO -CARROLL -CARY -CHONG -CLIFTON -CODY -COLTON -CORNELL -DAMON -DANNIE -DARIO -DONN -DOUG -DOUGLAS -FREDERICK -FRITZ -GERALD -GUS -HARVEY -IRVING -ISAIAH -JARVIS -JOHN -KENTON -LAURENCE -LESTER -LINCOLN -LOWELL -NELSON -NEVILLE -NIGEL -NORMAND -ODIS -OMAR -ORLANDO -RAYMUNDO -REX -ROLANDO -RON -SHANE -TONEY -TRINIDAD -WALTER -WARNER -WARREN -WES -WILLARD -WILLIAM -WINFRED -XAVIER diff --git a/src/util/uthash/tests/test31.c b/src/util/uthash/tests/test31.c deleted file mode 100644 index 711c7d9..0000000 --- a/src/util/uthash/tests/test31.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include "utlist.h" - -#define BUFLEN 20 - -typedef struct el { - char bname[BUFLEN]; - struct el *next, *prev; -} el; - -int namecmp(void *_a, void *_b) { - el *a = (el*)_a; - el *b = (el*)_b; - return strcmp(a->bname,b->bname); -} - -el *head = NULL; - -int main(int argc, char *argv[]) { - el *name, *tmp; - - char linebuf[BUFLEN]; - FILE *file; - - if ( (file = fopen( "test11.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); - strncpy(name->bname,linebuf,BUFLEN); - CDL_PREPEND(head, name); - } - CDL_SORT(head, namecmp); - CDL_FOREACH(head,tmp) printf("%s", tmp->bname); - - fclose(file); - - return 0; -} diff --git a/src/util/uthash/tests/test32.ans b/src/util/uthash/tests/test32.ans deleted file mode 100644 index 2a4d7f7..0000000 --- a/src/util/uthash/tests/test32.ans +++ /dev/null @@ -1,51 +0,0 @@ -ARNOLDO -COLTON -WES -WARNER -TONEY -NEVILLE -CHONG -KENTON -DARIO -DANNIE -ODIS -TRINIDAD -DONN -FRITZ -NORMAND -NIGEL -CORNELL -LINCOLN -RAYMUNDO -WINFRED -JARVIS -GUS -ISAIAH -XAVIER -CARY -ROLANDO -LAURENCE -CARROLL -IRVING -LOWELL -DAMON -OMAR -REX -ORLANDO -DOUG -WILLARD -CLIFTON -NELSON -CODY -ADRIAN -HARVEY -RON -LESTER -SHANE -WARREN -FREDERICK -GERALD -DOUGLAS -WALTER -WILLIAM -JOHN diff --git a/src/util/uthash/tests/test32.c b/src/util/uthash/tests/test32.c deleted file mode 100644 index fad2030..0000000 --- a/src/util/uthash/tests/test32.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include -#include "utlist.h" - -#define BUFLEN 20 - -typedef struct el { - char bname[BUFLEN]; - struct el *next, *prev; -} el; - -int namecmp(el *a, el *b) { - return strcmp(a->bname,b->bname); -} - -el *head = NULL; - -int main(int argc, char *argv[]) { - el *name, *tmp; - - char linebuf[BUFLEN]; - FILE *file; - - if ( (file = fopen( "test11.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); - strncpy(name->bname,linebuf,BUFLEN); - DL_PREPEND(head, name); - } - /* DL_SORT(head, namecmp); */ - DL_FOREACH(head,tmp) printf("%s", tmp->bname); - - fclose(file); - - return 0; -} diff --git a/src/util/uthash/tests/test33.ans b/src/util/uthash/tests/test33.ans deleted file mode 100644 index 2b72e98..0000000 --- a/src/util/uthash/tests/test33.ans +++ /dev/null @@ -1,51 +0,0 @@ -ADRIAN -ARNOLDO -CARROLL -CARY -CHONG -CLIFTON -CODY -COLTON -CORNELL -DAMON -DANNIE -DARIO -DONN -DOUG -DOUGLAS -FREDERICK -FRITZ -GERALD -GUS -HARVEY -IRVING -ISAIAH -JARVIS -JOHN -KENTON -LAURENCE -LESTER -LINCOLN -LOWELL -NELSON -NEVILLE -NIGEL -NORMAND -ODIS -OMAR -ORLANDO -RAYMUNDO -REX -ROLANDO -RON -SHANE -TONEY -TRINIDAD -WALTER -WARNER -WARREN -WES -WILLARD -WILLIAM -WINFRED -XAVIER diff --git a/src/util/uthash/tests/test33.c b/src/util/uthash/tests/test33.c deleted file mode 100644 index d946ec1..0000000 --- a/src/util/uthash/tests/test33.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include "utlist.h" - -#define BUFLEN 20 - -typedef struct el { - char bname[BUFLEN]; - struct el *next, *prev; -} el; - -int namecmp(void *_a, void *_b) { - el *a = (el*)_a; - el *b = (el*)_b; - return strcmp(a->bname,b->bname); -} - -el *head = NULL; - -int main(int argc, char *argv[]) { - el *name, *tmp; - - char linebuf[BUFLEN]; - FILE *file; - - if ( (file = fopen( "test11.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); - strncpy(name->bname,linebuf,BUFLEN); - LL_PREPEND(head, name); - } - LL_SORT(head, namecmp); - LL_FOREACH(head,tmp) printf("%s", tmp->bname); - - fclose(file); - - return 0; -} diff --git a/src/util/uthash/tests/test34.ans b/src/util/uthash/tests/test34.ans deleted file mode 100644 index 2a4d7f7..0000000 --- a/src/util/uthash/tests/test34.ans +++ /dev/null @@ -1,51 +0,0 @@ -ARNOLDO -COLTON -WES -WARNER -TONEY -NEVILLE -CHONG -KENTON -DARIO -DANNIE -ODIS -TRINIDAD -DONN -FRITZ -NORMAND -NIGEL -CORNELL -LINCOLN -RAYMUNDO -WINFRED -JARVIS -GUS -ISAIAH -XAVIER -CARY -ROLANDO -LAURENCE -CARROLL -IRVING -LOWELL -DAMON -OMAR -REX -ORLANDO -DOUG -WILLARD -CLIFTON -NELSON -CODY -ADRIAN -HARVEY -RON -LESTER -SHANE -WARREN -FREDERICK -GERALD -DOUGLAS -WALTER -WILLIAM -JOHN diff --git a/src/util/uthash/tests/test34.c b/src/util/uthash/tests/test34.c deleted file mode 100644 index 653cdb8..0000000 --- a/src/util/uthash/tests/test34.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include -#include "utlist.h" - -#define BUFLEN 20 - -typedef struct el { - char bname[BUFLEN]; - struct el *next, *prev; -} el; - -int namecmp(el *a, el *b) { - return strcmp(a->bname,b->bname); -} - -el *head = NULL; - -int main(int argc, char *argv[]) { - el *name, *tmp; - - char linebuf[BUFLEN]; - FILE *file; - - if ( (file = fopen( "test11.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); - strncpy(name->bname,linebuf,BUFLEN); - CDL_PREPEND(head, name); - } - /* CDL_SORT(head, namecmp); */ - CDL_FOREACH(head,tmp) printf("%s", tmp->bname); - - fclose(file); - - return 0; -} diff --git a/src/util/uthash/tests/test35.ans b/src/util/uthash/tests/test35.ans deleted file mode 100644 index b33c808..0000000 --- a/src/util/uthash/tests/test35.ans +++ /dev/null @@ -1,30 +0,0 @@ -0: aello -1: bello -2: cello -3: dello -4: eello -5: fello -6: gello -7: hello -8: iello -9: jello -found aello -right address? yes -found bello -right address? yes -found cello -right address? yes -found dello -right address? yes -found eello -right address? yes -found fello -right address? yes -found gello -right address? yes -found hello -right address? yes -found iello -right address? yes -found jello -right address? yes diff --git a/src/util/uthash/tests/test35.c b/src/util/uthash/tests/test35.c deleted file mode 100644 index 6d41e5e..0000000 --- a/src/util/uthash/tests/test35.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "uthash.h" -#include /* strcpy */ -#include /* malloc */ -#include /* printf */ - -typedef struct elt { - char *s; - UT_hash_handle hh; -} elt; - -int main(int argc,char *argv[]) { - int i; - elt *head = NULL; - elt elts[10]; - char label[6]; - for(i=0;i<10;i++) { - elts[i].s = (char*)malloc(6); - strncpy(elts[i].s, "hello",6); - elts[i].s[0] = 'a' + i; - printf("%d: %s\n", i, elts[i].s); - HASH_ADD_KEYPTR(hh, head, elts[i].s, 6, &elts[i]); - } - - /* look up each element and verify the result pointer */ - strncpy(label, "hello", 6); - for(i=0;i<10;i++) { - elt *e; - label[0] = 'a' + i; - HASH_FIND(hh,head,label,6,e); - if (e) { - printf( "found %s\n", e->s); - printf( "right address? %s\n", (e == &elts[i]) ? "yes" : "no"); - } - } - - return 0; -} diff --git a/src/util/uthash/tests/test36.ans b/src/util/uthash/tests/test36.ans deleted file mode 100644 index 3b5283b..0000000 --- a/src/util/uthash/tests/test36.ans +++ /dev/null @@ -1,15 +0,0 @@ -user 0 -user 1 -user 2 -user 3 -user 4 -user 5 -user 6 -user 7 -user 8 -user 9 -auser 0 -auser 2 -auser 4 -auser 6 -auser 8 diff --git a/src/util/uthash/tests/test36.c b/src/util/uthash/tests/test36.c deleted file mode 100644 index d91350b..0000000 --- a/src/util/uthash/tests/test36.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct { - int id; - UT_hash_handle hh; - UT_hash_handle ah; -} example_user_t; - -#define EVENS(x) (((x)->id & 1) == 0) -int evens(void *userv) { - example_user_t *user = (example_user_t*)userv; - return ((user->id & 1) ? 0 : 1); -} - -int idcmp(void *_a, void *_b) { - example_user_t *a = (example_user_t*)_a; - example_user_t *b = (example_user_t*)_b; - return (a->id - b->id); -} - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *users=NULL, *ausers=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - user = (example_user_t*)malloc(sizeof(example_user_t)); - user->id = i; - HASH_ADD_INT(users,id,user); - } - - for(user=users; user; user=(example_user_t*)(user->hh.next)) { - printf("user %d\n", user->id); - } - - /* now select some users into ausers */ - HASH_SELECT(ah,ausers,hh,users,evens); - HASH_SRT(ah,ausers,idcmp); - - for(user=ausers; user; user=(example_user_t*)(user->ah.next)) { - printf("auser %d\n", user->id); - } - return 0; -} diff --git a/src/util/uthash/tests/test37.ans b/src/util/uthash/tests/test37.ans deleted file mode 100644 index f42a945..0000000 --- a/src/util/uthash/tests/test37.ans +++ /dev/null @@ -1,20 +0,0 @@ -user 0 -user 1 -user 2 -user 3 -user 4 -user 5 -user 6 -user 7 -user 8 -user 9 -users count: 10 -auser 0 -auser 2 -auser 4 -auser 6 -auser 8 -ausers count: 5 -cleared ausers. -ausers count: 0 -users count: 10 diff --git a/src/util/uthash/tests/test37.c b/src/util/uthash/tests/test37.c deleted file mode 100644 index 7071e1c..0000000 --- a/src/util/uthash/tests/test37.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct { - int id; - UT_hash_handle hh; - UT_hash_handle ah; -} example_user_t; - -#define EVENS(x) ((((example_user_t*)(x))->id & 1) == 0) - -int idcmp(void *_a, void *_b) { - example_user_t *a = (example_user_t*)_a; - example_user_t *b = (example_user_t*)_b; - return (a->id - b->id); -} - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *users=NULL, *ausers=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - user = (example_user_t*)malloc(sizeof(example_user_t)); - user->id = i; - HASH_ADD_INT(users,id,user); - } - - for(user=users; user; user=(example_user_t*)(user->hh.next)) { - printf("user %d\n", user->id); - } - printf("users count: %u\n", HASH_CNT(hh,users)); - - /* now select some users into ausers */ - HASH_SELECT(ah,ausers,hh,users,EVENS); - HASH_SRT(ah,ausers,idcmp); - - for(user=ausers; user; user=(example_user_t*)(user->ah.next)) { - printf("auser %d\n", user->id); - } - printf("ausers count: %u\n", HASH_CNT(ah,ausers)); - HASH_CLEAR(ah,ausers); - printf("cleared ausers.\n"); - printf("ausers count: %u\n", HASH_CNT(ah,ausers)); - for(user=ausers; user; user=(example_user_t*)(user->ah.next)) { - printf("auser %d\n", user->id); - } - printf("users count: %u\n", HASH_CNT(hh,users)); - return 0; -} diff --git a/src/util/uthash/tests/test38.ans b/src/util/uthash/tests/test38.ans deleted file mode 100644 index b20e04b..0000000 --- a/src/util/uthash/tests/test38.ans +++ /dev/null @@ -1 +0,0 @@ -hash count 10 diff --git a/src/util/uthash/tests/test38.c b/src/util/uthash/tests/test38.c deleted file mode 100644 index 500d160..0000000 --- a/src/util/uthash/tests/test38.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "uthash.h" -#include -#include - -struct test_t { - int a; - UT_hash_handle hh; -}; - -struct test_t *tests=NULL, *test; - -int main(void) { - int a, b; - for (b=0; b < 3; b++) { - for (a=0; a < 10; a++) { - test = NULL; - HASH_FIND(hh, tests, &a, sizeof(a), test); - if (! test) { - test = (struct test_t*)malloc(sizeof(struct test_t)); - memset(test, 0, sizeof(struct test_t)); - test->a = a; - HASH_ADD(hh, tests, a, sizeof(a), test); - } - } - } - printf("hash count %u\n", HASH_COUNT(tests)); - return 0; -} diff --git a/src/util/uthash/tests/test39.ans b/src/util/uthash/tests/test39.ans deleted file mode 100644 index a7e7e6c..0000000 --- a/src/util/uthash/tests/test39.ans +++ /dev/null @@ -1,7 +0,0 @@ -adding key eins -adding key zwei -adding key drei -hash count is 3 -looking for key eins... found. -looking for key zwei... found. -looking for key drei... found. diff --git a/src/util/uthash/tests/test39.c b/src/util/uthash/tests/test39.c deleted file mode 100644 index b0a5310..0000000 --- a/src/util/uthash/tests/test39.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include "uthash.h" - -typedef struct { - const char *name; - UT_hash_handle hh; -} ns_t; - -ns_t *head = NULL; - -int main() { - const char *keys[] = {"eins", "zwei", "drei"}; - unsigned i; - ns_t *nsp; - - for(i=0; i < sizeof(keys)/sizeof(keys[0]); i++) { - printf("adding key %s\n", keys[i]); - nsp = (ns_t*)malloc(sizeof(ns_t)); - nsp->name = keys[i]; - HASH_ADD_KEYPTR(hh,head,nsp->name,strlen(nsp->name),nsp); - } - printf("hash count is %u\n", HASH_COUNT(head)); - - for(i=0; i < sizeof(keys)/sizeof(keys[0]); i++) { - printf("looking for key %s... ", keys[i]); - HASH_FIND(hh,head,keys[i],strlen(keys[i]),nsp); - printf("%s.\n", (nsp?"found":"not found")); - } - return 0; -} diff --git a/src/util/uthash/tests/test4.ans b/src/util/uthash/tests/test4.ans deleted file mode 100644 index 19b148f..0000000 --- a/src/util/uthash/tests/test4.ans +++ /dev/null @@ -1,10 +0,0 @@ -cookie 0, user 0 -cookie 1, user 1 -cookie 4, user 2 -cookie 9, user 3 -cookie 16, user 4 -cookie 25, user 5 -cookie 36, user 6 -cookie 49, user 7 -cookie 64, user 8 -cookie 81, user 9 diff --git a/src/util/uthash/tests/test4.c b/src/util/uthash/tests/test4.c deleted file mode 100644 index 945c9ae..0000000 --- a/src/util/uthash/tests/test4.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; - UT_hash_handle alth; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *users=NULL, *altusers=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - HASH_ADD(alth,altusers,cookie,sizeof(int),user); - } - - for(user=altusers; user != NULL; user=(example_user_t*)(user->alth.next)) { - printf("cookie %d, user %d\n", user->cookie, user->id); - } - return 0; -} diff --git a/src/util/uthash/tests/test40.ans b/src/util/uthash/tests/test40.ans deleted file mode 100644 index ad69a94..0000000 --- a/src/util/uthash/tests/test40.ans +++ /dev/null @@ -1 +0,0 @@ -betty's id is 2 diff --git a/src/util/uthash/tests/test40.c b/src/util/uthash/tests/test40.c deleted file mode 100644 index 191c2f2..0000000 --- a/src/util/uthash/tests/test40.c +++ /dev/null @@ -1,34 +0,0 @@ -#include /* strcpy */ -#include /* malloc */ -#include /* printf */ -#include "uthash.h" - -struct my_struct { - const char *name; /* key */ - int id; - UT_hash_handle hh; /* makes this structure hashable */ -}; - - -int main(int argc, char *argv[]) { - const char **n, *names[] = { "joe", "bob", "betty", NULL }; - struct my_struct *s, *tmp, *users = NULL; - int i=0; - - for (n = names; *n != NULL; n++) { - s = (struct my_struct*)malloc(sizeof(struct my_struct)); - s->name = *n; - s->id = i++; - HASH_ADD_KEYPTR( hh, users, s->name, strlen(s->name), s ); - } - - HASH_FIND_STR( users, "betty", s); - if (s) printf("betty's id is %d\n", s->id); - - /* free the hash table contents */ - HASH_ITER(hh, users, s, tmp) { - HASH_DEL(users, s); - free(s); - } - return 0; -} diff --git a/src/util/uthash/tests/test41.ans b/src/util/uthash/tests/test41.ans deleted file mode 100644 index f19e34b..0000000 --- a/src/util/uthash/tests/test41.ans +++ /dev/null @@ -1,6 +0,0 @@ -CDL macros -c b a deleting c deleting b deleting a -DL macros -a b c deleting a deleting b deleting c -LL macros -a b c deleting a deleting b deleting c diff --git a/src/util/uthash/tests/test41.c b/src/util/uthash/tests/test41.c deleted file mode 100644 index 1e35443..0000000 --- a/src/util/uthash/tests/test41.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *head = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[10], *e, *tmp, *tmp2; - for(i=0;i<10;i++) els[i].id='a'+i; - - /* test CDL macros */ - printf("CDL macros\n"); - CDL_PREPEND(head,&els[0]); - CDL_PREPEND(head,&els[1]); - CDL_PREPEND(head,&els[2]); - CDL_FOREACH(head,e) printf("%c ", e->id); - - /* point head to head->next */ - CDL_FOREACH_SAFE(head,e,tmp,tmp2) { - printf("deleting %c ", e->id); - CDL_DELETE(head,e); - } - printf("\n"); - if (head) printf("non-null head\n"); - - /* test DL macros */ - printf("DL macros\n"); - DL_APPEND(head,&els[0]); - DL_APPEND(head,&els[1]); - DL_APPEND(head,&els[2]); - DL_FOREACH(head,e) printf("%c ", e->id); - DL_FOREACH_SAFE(head,e,tmp) { - printf("deleting %c ", e->id); - DL_DELETE(head,e); - } - printf("\n"); - if (head) printf("non-null head\n"); - - /* test LL macros */ - printf("LL macros\n"); - LL_APPEND(head,&els[0]); - LL_APPEND(head,&els[1]); - LL_APPEND(head,&els[2]); - LL_FOREACH(head,e) printf("%c ", e->id); - LL_FOREACH_SAFE(head,e,tmp) { - printf("deleting %c ", e->id); - LL_DELETE(head,e); - } - printf("\n"); - if (head) printf("non-null head\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test42.ans b/src/util/uthash/tests/test42.ans deleted file mode 100644 index 581660e..0000000 --- a/src/util/uthash/tests/test42.ans +++ /dev/null @@ -1,14 +0,0 @@ -LL macros -a b c -search scalar found b -search found a - -DL macros -a b c -search scalar found b -search found a - -CDL macros -c b a -search scalar found b -search found a diff --git a/src/util/uthash/tests/test42.c b/src/util/uthash/tests/test42.c deleted file mode 100644 index b20c579..0000000 --- a/src/util/uthash/tests/test42.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *head = NULL; - -int eltcmp(el *a, el *b) {return a->id - b->id;} - -int main(int argc, char *argv[]) { - int i; - el els[10], *e, *tmp, *tmp2; - for(i=0;i<10;i++) els[i].id='a'+i; - - /* test LL macros */ - printf("LL macros\n"); - LL_APPEND(head,&els[0]); - LL_APPEND(head,&els[1]); - LL_APPEND(head,&els[2]); - LL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - LL_SEARCH_SCALAR(head, e, id, 'b'); - if (e) printf("search scalar found b\n"); - LL_SEARCH(head, e, &els[0], eltcmp); - if (e) printf("search found %c\n",e->id); - LL_FOREACH_SAFE(head,e,tmp) LL_DELETE(head,e); - - printf("\n"); - - /* test DL macros */ - printf("DL macros\n"); - DL_APPEND(head,&els[0]); - DL_APPEND(head,&els[1]); - DL_APPEND(head,&els[2]); - DL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - DL_SEARCH_SCALAR(head, e, id, 'b'); - if (e) printf("search scalar found b\n"); - DL_SEARCH(head, e, &els[0], eltcmp); - if (e) printf("search found %c\n",e->id); - DL_FOREACH_SAFE(head,e,tmp) DL_DELETE(head,e); - printf("\n"); - - /* test CDL macros */ - printf("CDL macros\n"); - CDL_PREPEND(head,&els[0]); - CDL_PREPEND(head,&els[1]); - CDL_PREPEND(head,&els[2]); - CDL_FOREACH(head,e) - printf("%c ", e->id); - printf("\n"); - CDL_SEARCH_SCALAR(head, e, id, 'b'); - if (e) printf("search scalar found b\n"); - CDL_SEARCH(head, e, &els[0], eltcmp); - if (e) printf("search found %c\n",e->id); - CDL_FOREACH_SAFE(head,e,tmp,tmp2) CDL_DELETE(head,e); - - - return 0; -} diff --git a/src/util/uthash/tests/test43.ans b/src/util/uthash/tests/test43.ans deleted file mode 100644 index d09e9bd..0000000 --- a/src/util/uthash/tests/test43.ans +++ /dev/null @@ -1,88 +0,0 @@ -length is 0 -push -length is 1 -back is 1 2 -pop -length is 0 -push -push -length is 2 -1 2 -3 4 -erase [0] -length is 1 -3 4 -push -3 4 -1 2 -clear -length is 0 -extend -length is 1 -ip points to [0] ? yes -push -0 0 -1 2 -erase [1] -length is 1 -0 0 -push -0 0 -3 4 -back is 3 4 -copy -cpy length is 2 -cpy 0 0 -cpy 3 4 -insert cpy[0] -cpy length is 3 -cpy 5 6 -cpy 0 0 -cpy 3 4 -erase cpy [0] [1] -cpy length is 1 -cpy 3 4 -inserta at cpy[1] -cpy length is 3 -cpy 3 4 -cpy 0 0 -cpy 3 4 -free cpy -length is 2 -resize to 30 -length is 30 -0 0 -3 4 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -0 0 -resize to 1 -length is 1 -resize to 0 -length is 0 -free diff --git a/src/util/uthash/tests/test43.c b/src/util/uthash/tests/test43.c deleted file mode 100644 index fbd40c8..0000000 --- a/src/util/uthash/tests/test43.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include "utarray.h" - -typedef struct { - int a; - int b; -} intpair_t; - -UT_icd pairicd = { sizeof(intpair_t),NULL,NULL,NULL}; - -int main() { - UT_array *pairs, *pairs_cpy; - intpair_t it, *ip; - size_t zero=0; - utarray_new(pairs, &pairicd); - printf("length is %d\n", utarray_len(pairs)); - it.a = 1; it.b=2; utarray_push_back(pairs, &it); printf("push\n"); - printf("length is %d\n", utarray_len(pairs)); - ip = (intpair_t*)utarray_back(pairs); - printf("back is %d %d\n", ip->a, ip->b); - utarray_pop_back(pairs); printf("pop\n"); - printf("length is %d\n", utarray_len(pairs)); - it.a = 1; it.b=2; utarray_push_back(pairs, &it); printf("push\n"); - it.a = 3; it.b=4; utarray_push_back(pairs, &it); printf("push\n"); - printf("length is %d\n", utarray_len(pairs)); - ip=NULL; - while( (ip=(intpair_t*)utarray_next(pairs,ip))) printf("%d %d\n", ip->a, ip->b); - utarray_erase(pairs,0,1); printf("erase [0]\n"); - printf("length is %d\n", utarray_len(pairs)); - while( (ip=(intpair_t*)utarray_next(pairs,ip))) printf("%d %d\n", ip->a, ip->b); - it.a = 1; it.b=2; utarray_push_back(pairs, &it); printf("push\n"); - while( (ip=(intpair_t*)utarray_next(pairs,ip))) printf("%d %d\n", ip->a, ip->b); - utarray_clear(pairs); printf("clear\n"); - printf("length is %d\n", utarray_len(pairs)); - utarray_extend_back(pairs); printf("extend\n"); - ip = (intpair_t*)utarray_back(pairs); - printf("length is %d\n", utarray_len(pairs)); - printf("ip points to [0] ? %s\n", (ip==(intpair_t*)utarray_front(pairs)) ? "yes" : "no"); - it.a = 1; it.b=2; utarray_push_back(pairs, &it); printf("push\n"); - ip=NULL; - while( (ip=(intpair_t*)utarray_next(pairs,ip))) printf("%d %d\n", ip->a, ip->b); - utarray_erase(pairs,1,1); printf("erase [1]\n"); - printf("length is %d\n", utarray_len(pairs)); - while( (ip=(intpair_t*)utarray_next(pairs,ip))) printf("%d %d\n", ip->a, ip->b); - it.a = 3; it.b=4; utarray_push_back(pairs, &it); printf("push\n"); - for(ip=(intpair_t*)utarray_front(pairs);ip;ip=(intpair_t*)utarray_next(pairs,ip)) { - printf("%d %d\n", ip->a,ip->b); - } - ip = (intpair_t*)utarray_back(pairs); - printf("back is %d %d\n", ip->a, ip->b); - utarray_new(pairs_cpy, &pairicd); - utarray_concat(pairs_cpy, pairs); printf("copy\n"); - printf("cpy length is %d\n", utarray_len(pairs_cpy)); - ip=NULL; - while( (ip=(intpair_t*)utarray_next(pairs_cpy,ip))) printf("cpy %d %d\n", ip->a, ip->b); - it.a=5; it.b=6; utarray_insert(pairs_cpy, &it, 0); printf("insert cpy[0]\n"); - printf("cpy length is %d\n", utarray_len(pairs_cpy)); - while( (ip=(intpair_t*)utarray_next(pairs_cpy,ip))) printf("cpy %d %d\n", ip->a, ip->b); - utarray_erase(pairs_cpy,0,2); printf("erase cpy [0] [1]\n"); - printf("cpy length is %d\n", utarray_len(pairs_cpy)); - while( (ip=(intpair_t*)utarray_next(pairs_cpy,ip))) printf("cpy %d %d\n", ip->a, ip->b); - utarray_inserta(pairs_cpy, pairs, 1); printf("inserta at cpy[1]\n"); - printf("cpy length is %d\n", utarray_len(pairs_cpy)); - while( (ip=(intpair_t*)utarray_next(pairs_cpy,ip))) printf("cpy %d %d\n", ip->a, ip->b); - utarray_free(pairs_cpy); printf("free cpy\n"); - printf("length is %d\n", utarray_len(pairs)); - utarray_resize(pairs, 30); printf("resize to 30\n"); - printf("length is %d\n", utarray_len(pairs)); - while( (ip=(intpair_t*)utarray_next(pairs,ip))) printf("%d %d\n", ip->a, ip->b); - utarray_resize(pairs, 1); printf("resize to 1\n"); - printf("length is %d\n", utarray_len(pairs)); - utarray_resize(pairs, zero); printf("resize to 0\n"); - printf("length is %d\n", utarray_len(pairs)); - utarray_free(pairs); printf("free\n"); - return 0; -} diff --git a/src/util/uthash/tests/test44.ans b/src/util/uthash/tests/test44.ans deleted file mode 100644 index f771df8..0000000 --- a/src/util/uthash/tests/test44.ans +++ /dev/null @@ -1,9 +0,0 @@ -0 1 2 3 4 5 6 7 8 9 -9 8 7 6 5 4 3 2 1 0 -9 8 7 3 2 1 0 -9 3 2 1 0 -3 2 1 0 -3 2 1 -3 2 1 0 0 -3 2 1 - diff --git a/src/util/uthash/tests/test44.c b/src/util/uthash/tests/test44.c deleted file mode 100644 index 6c419c2..0000000 --- a/src/util/uthash/tests/test44.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include "utarray.h" - -int reverse(const void *a,const void*b) { - int _a = *(int*)a; - int _b = *(int*)b; - return _b - _a; -} - -int main() { - UT_array *a; - int i, *p; - utarray_new(a, &ut_int_icd); - for(i=0;i<10;i++) utarray_push_back(a,&i); - for(p=(int*)utarray_front(a); p; p=(int*)utarray_next(a,p)) printf("%d ",*p); - printf("\n"); - utarray_sort(a,reverse); - while ( (p=(int*)utarray_next(a,p))) printf("%d ", *p); - printf("\n"); - utarray_erase(a,3,3); - while ( (p=(int*)utarray_next(a,p))) printf("%d ", *p); - printf("\n"); - utarray_erase(a,1,2); - while ( (p=(int*)utarray_next(a,p))) printf("%d ", *p); - printf("\n"); - utarray_erase(a,0,1); - while ( (p=(int*)utarray_next(a,p))) printf("%d ", *p); - printf("\n"); - utarray_erase(a,3,1); - while ( (p=(int*)utarray_next(a,p))) printf("%d ", *p); - printf("\n"); - utarray_resize(a,5); - while ( (p=(int*)utarray_next(a,p))) printf("%d ", *p); - printf("\n"); - utarray_resize(a,3); - while ( (p=(int*)utarray_next(a,p))) printf("%d ", *p); - printf("\n"); - utarray_erase(a,0,3); - while ( (p=(int*)utarray_next(a,p))) printf("%d ", *p); - printf("\n"); - utarray_free(a); - return 0; -} - diff --git a/src/util/uthash/tests/test45.ans b/src/util/uthash/tests/test45.ans deleted file mode 100644 index 7e744bc..0000000 --- a/src/util/uthash/tests/test45.ans +++ /dev/null @@ -1,3 +0,0 @@ -1 2 3 4 5 6 7 8 -1 2 3 100 4 5 6 7 8 -1 2 3 100 4 5 6 7 8 1000 diff --git a/src/util/uthash/tests/test45.c b/src/util/uthash/tests/test45.c deleted file mode 100644 index dca7d9b..0000000 --- a/src/util/uthash/tests/test45.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include "utarray.h" - -int main() { - UT_array *a; - int i, *p=NULL; - utarray_new(a, &ut_int_icd); - for(i=0;i<10;i++) utarray_push_back(a,&i); - utarray_pop_back(a); - utarray_erase(a,0,1); - while ( (p=(int*)utarray_next(a,p))) printf("%d ",*p); printf("\n"); - i = 100; - utarray_insert(a,&i,3); - while ( (p=(int*)utarray_next(a,p))) printf("%d ",*p); printf("\n"); - utarray_extend_back(a); - p = (int*)utarray_back(a); - *p = 1000; - p = NULL; - while ( (p=(int*)utarray_next(a,p))) printf("%d ",*p); printf("\n"); - utarray_clear(a); - utarray_free(a); - return 0; -} - diff --git a/src/util/uthash/tests/test46.ans b/src/util/uthash/tests/test46.ans deleted file mode 100644 index be625f3..0000000 --- a/src/util/uthash/tests/test46.ans +++ /dev/null @@ -1,11 +0,0 @@ -hello world -begin hello world -alt begin hello world oth -hello world oth -hello world -hello world begin hello world -begin hello world -sorting strs2 -begin hello world -reverse sorting strs2 -world hello begin diff --git a/src/util/uthash/tests/test46.c b/src/util/uthash/tests/test46.c deleted file mode 100644 index b7b785a..0000000 --- a/src/util/uthash/tests/test46.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include "utarray.h" - -int strsort(const void *_a, const void *_b) { - char *a = *(char**)_a; - char *b = *(char**)_b; - return strcmp(a,b); -} - -int revsort(const void *_a, const void *_b) { - char *a = *(char**)_a; - char *b = *(char**)_b; - return strcmp(b,a); -} - -int main() { - UT_array *strs,*strs2; - char *s, **p=NULL; - utarray_new(strs, &ut_str_icd); - s="hello"; utarray_push_back(strs, &s); - s="world"; utarray_push_back(strs, &s); - while ( (p=(char**)utarray_next(strs,p))) printf("%s ",*p); printf("\n"); - s="begin"; utarray_insert(strs,&s,0); - while ( (p=(char**)utarray_next(strs,p))) printf("%s ",*p); printf("\n"); - utarray_new(strs2, &ut_str_icd); - s="alt"; utarray_push_back(strs2, &s); - s="oth"; utarray_push_back(strs2, &s); - utarray_inserta(strs2, strs, 1); - while ( (p=(char**)utarray_next(strs2,p))) printf("%s ",*p); printf("\n"); - utarray_erase(strs2,0,2); - while ( (p=(char**)utarray_next(strs2,p))) printf("%s ",*p); printf("\n"); - utarray_pop_back(strs2); - while ( (p=(char**)utarray_next(strs2,p))) printf("%s ",*p); printf("\n"); - utarray_concat(strs2, strs); - while ( (p=(char**)utarray_next(strs2,p))) printf("%s ",*p); printf("\n"); - utarray_clear(strs2); - utarray_concat(strs2, strs); - while ( (p=(char**)utarray_next(strs2,p))) printf("%s ",*p); printf("\n"); - printf("sorting strs2\n"); - utarray_sort(strs2,strsort); - while ( (p=(char**)utarray_next(strs2,p))) printf("%s ",*p); printf("\n"); - printf("reverse sorting strs2\n"); - utarray_sort(strs2,revsort); - while ( (p=(char**)utarray_next(strs2,p))) printf("%s ",*p); printf("\n"); - utarray_clear(strs2); - utarray_free(strs2); - utarray_free(strs); - return 0; -} diff --git a/src/util/uthash/tests/test47.ans b/src/util/uthash/tests/test47.ans deleted file mode 100644 index 546e064..0000000 --- a/src/util/uthash/tests/test47.ans +++ /dev/null @@ -1,8 +0,0 @@ -hello world -hello world text - second -hello world text second -cleared, length t now: 0 -length s now: 23 -one 1 two 2 three (3) -length t now: 21 diff --git a/src/util/uthash/tests/test47.c b/src/util/uthash/tests/test47.c deleted file mode 100644 index 1434d5a..0000000 --- a/src/util/uthash/tests/test47.c +++ /dev/null @@ -1,28 +0,0 @@ -#include /* printf */ -#include "utstring.h" - -int main() { - UT_string *s,*t; - char a[] = " text"; - utstring_new(s); - utstring_new(t); - - utstring_printf(s,"hello %s", "world"); - printf("%s\n", utstring_body(s)); - utstring_bincpy(s,a,sizeof(a)-1); - printf("%s\n", utstring_body(s)); - utstring_printf(t," second"); - printf("%s\n", utstring_body(t)); - utstring_concat(s,t); - printf("%s\n", utstring_body(s)); - utstring_clear(t); - printf("cleared, length t now: %d\n", utstring_len(t)); - printf("length s now: %d\n", utstring_len(s)); - utstring_printf(t,"one %d two %u three %s", 1, 2, "(3)"); - printf("%s\n", utstring_body(t)); - printf("length t now: %d\n", utstring_len(t)); - - - utstring_free(s); - return 0; -} diff --git a/src/util/uthash/tests/test48.ans b/src/util/uthash/tests/test48.ans deleted file mode 100644 index 8b1acc1..0000000 --- a/src/util/uthash/tests/test48.ans +++ /dev/null @@ -1,10 +0,0 @@ -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 diff --git a/src/util/uthash/tests/test48.c b/src/util/uthash/tests/test48.c deleted file mode 100644 index dd0fa75..0000000 --- a/src/util/uthash/tests/test48.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include "utarray.h" - -int main() { - UT_array *nums; - int i, *p; - - utarray_new(nums,&ut_int_icd); - for(i=0; i < 10; i++) utarray_push_back(nums,&i); - - for(p=(int*)utarray_front(nums); - p!=NULL; - p=(int*)utarray_next(nums,p)) { - printf("%d\n",*p); - } - - utarray_free(nums); - - return 0; -} diff --git a/src/util/uthash/tests/test49.ans b/src/util/uthash/tests/test49.ans deleted file mode 100644 index 94954ab..0000000 --- a/src/util/uthash/tests/test49.ans +++ /dev/null @@ -1,2 +0,0 @@ -hello -world diff --git a/src/util/uthash/tests/test49.c b/src/util/uthash/tests/test49.c deleted file mode 100644 index 00afb7a..0000000 --- a/src/util/uthash/tests/test49.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include "utarray.h" - -int main() { - UT_array *strs; - char *s, **p; - - utarray_new(strs,&ut_str_icd); - - s = "hello"; utarray_push_back(strs, &s); - s = "world"; utarray_push_back(strs, &s); - p = NULL; - while ( (p=(char**)utarray_next(strs,p))) { - printf("%s\n",*p); - } - - utarray_free(strs); - - return 0; -} diff --git a/src/util/uthash/tests/test5.ans b/src/util/uthash/tests/test5.ans deleted file mode 100644 index 2ece88f..0000000 --- a/src/util/uthash/tests/test5.ans +++ /dev/null @@ -1,5 +0,0 @@ -cookie 0 found, user id 0 -cookie 4 found, user id 2 -cookie 16 found, user id 4 -cookie 36 found, user id 6 -cookie 64 found, user id 8 diff --git a/src/util/uthash/tests/test5.c b/src/util/uthash/tests/test5.c deleted file mode 100644 index 7cfd278..0000000 --- a/src/util/uthash/tests/test5.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; - UT_hash_handle alth; -} example_user_t; - -int main(int argc,char *argv[]) { - int i,j; - example_user_t *user, *tmp, *users=NULL, *altusers=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - HASH_ADD(alth,altusers,cookie,sizeof(int),user); - } - - /* find cookie corresponding to each even ID */ - for(i=0;i<10;i+=2) { - j=i*i; - HASH_FIND(alth,altusers,&j,sizeof(int),tmp); - if (tmp) printf("cookie %d found, user id %d\n", tmp->cookie, tmp->id); - else printf("cookie %d not found\n", j); - } - return 0; -} diff --git a/src/util/uthash/tests/test50.ans b/src/util/uthash/tests/test50.ans deleted file mode 100644 index 1191247..0000000 --- a/src/util/uthash/tests/test50.ans +++ /dev/null @@ -1,2 +0,0 @@ -1 -2 diff --git a/src/util/uthash/tests/test50.c b/src/util/uthash/tests/test50.c deleted file mode 100644 index 0ef78d7..0000000 --- a/src/util/uthash/tests/test50.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include "utarray.h" - -UT_icd long_icd = {sizeof(long), NULL, NULL, NULL }; - -int main() { - UT_array *nums; - long l, *p; - utarray_new(nums, &long_icd); - - l=1; utarray_push_back(nums, &l); - l=2; utarray_push_back(nums, &l); - - p=NULL; - while( (p=(long*)utarray_next(nums,p))) printf("%ld\n", *p); - - utarray_free(nums); - return 0; -} diff --git a/src/util/uthash/tests/test51.ans b/src/util/uthash/tests/test51.ans deleted file mode 100644 index 3caf269..0000000 --- a/src/util/uthash/tests/test51.ans +++ /dev/null @@ -1,2 +0,0 @@ -1 2 -10 20 diff --git a/src/util/uthash/tests/test51.c b/src/util/uthash/tests/test51.c deleted file mode 100644 index 48df2e0..0000000 --- a/src/util/uthash/tests/test51.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include "utarray.h" - -typedef struct { - int a; - int b; -} intpair_t; - -UT_icd intpair_icd = {sizeof(intpair_t), NULL, NULL, NULL}; - -int main() { - - UT_array *pairs; - intpair_t ip, *p; - utarray_new(pairs,&intpair_icd); - - ip.a=1; ip.b=2; utarray_push_back(pairs, &ip); - ip.a=10; ip.b=20; utarray_push_back(pairs, &ip); - - for(p=(intpair_t*)utarray_front(pairs); - p!=NULL; - p=(intpair_t*)utarray_next(pairs,p)) { - printf("%d %d\n", p->a, p->b); - } - - utarray_free(pairs); - return 0; -} diff --git a/src/util/uthash/tests/test52.ans b/src/util/uthash/tests/test52.ans deleted file mode 100644 index bd37407..0000000 --- a/src/util/uthash/tests/test52.ans +++ /dev/null @@ -1,2 +0,0 @@ -1 hello -2 world diff --git a/src/util/uthash/tests/test52.c b/src/util/uthash/tests/test52.c deleted file mode 100644 index b4b3465..0000000 --- a/src/util/uthash/tests/test52.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include "utarray.h" - -typedef struct { - int a; - char *s; -} intchar_t; - -void intchar_copy(void *_dst, const void *_src) { - intchar_t *dst = (intchar_t*)_dst, *src = (intchar_t*)_src; - dst->a = src->a; - dst->s = src->s ? strdup(src->s) : NULL; -} - -void intchar_dtor(void *_elt) { - intchar_t *elt = (intchar_t*)_elt; - if (elt->s) free(elt->s); -} - -UT_icd intchar_icd = {sizeof(intchar_t), NULL, intchar_copy, intchar_dtor}; - -int main() { - UT_array *intchars; - intchar_t ic, *p; - utarray_new(intchars, &intchar_icd); - - ic.a=1; ic.s="hello"; utarray_push_back(intchars, &ic); - ic.a=2; ic.s="world"; utarray_push_back(intchars, &ic); - - p=NULL; - while( (p=(intchar_t*)utarray_next(intchars,p))) { - printf("%d %s\n", p->a, (p->s ? p->s : "null")); - } - - utarray_free(intchars); - return 0; -} - diff --git a/src/util/uthash/tests/test53.ans b/src/util/uthash/tests/test53.ans deleted file mode 100644 index a042389..0000000 --- a/src/util/uthash/tests/test53.ans +++ /dev/null @@ -1 +0,0 @@ -hello world! diff --git a/src/util/uthash/tests/test53.c b/src/util/uthash/tests/test53.c deleted file mode 100644 index b8fafc5..0000000 --- a/src/util/uthash/tests/test53.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include "utstring.h" - -int main() { - UT_string *s; - - utstring_new(s); - utstring_printf(s, "hello world!" ); - printf("%s\n", utstring_body(s)); - - utstring_free(s); - return 0; -} diff --git a/src/util/uthash/tests/test54.ans b/src/util/uthash/tests/test54.ans deleted file mode 100644 index df0083e..0000000 --- a/src/util/uthash/tests/test54.ans +++ /dev/null @@ -1,2 +0,0 @@ -length: 21 -hello world hi there diff --git a/src/util/uthash/tests/test54.c b/src/util/uthash/tests/test54.c deleted file mode 100644 index 8774bc5..0000000 --- a/src/util/uthash/tests/test54.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include "utstring.h" - -int main() { - UT_string *s, *t; - - utstring_new(s); - utstring_new(t); - - utstring_printf(s, "hello " ); - utstring_printf(s, "world " ); - - utstring_printf(t, "hi " ); - utstring_printf(t, "there " ); - - utstring_concat(s, t); - printf("length: %u\n", utstring_len(s)); - printf("%s\n", utstring_body(s)); - - utstring_free(s); - utstring_free(t); - return 0; -} diff --git a/src/util/uthash/tests/test55.ans b/src/util/uthash/tests/test55.ans deleted file mode 100644 index a75e7be..0000000 --- a/src/util/uthash/tests/test55.ans +++ /dev/null @@ -1,2 +0,0 @@ -length is 3 -number 10 diff --git a/src/util/uthash/tests/test55.c b/src/util/uthash/tests/test55.c deleted file mode 100644 index e421d68..0000000 --- a/src/util/uthash/tests/test55.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include "utstring.h" - -int main() { - UT_string *s; - char binary[] = "\xff\xff"; - - utstring_new(s); - utstring_bincpy(s, binary, sizeof(binary)); - printf("length is %u\n", utstring_len(s)); - - utstring_clear(s); - utstring_printf(s,"number %d", 10); - printf("%s\n", utstring_body(s)); - - utstring_free(s); - return 0; -} diff --git a/src/util/uthash/tests/test56.ans b/src/util/uthash/tests/test56.ans deleted file mode 100644 index f615d00..0000000 --- a/src/util/uthash/tests/test56.ans +++ /dev/null @@ -1,65 +0,0 @@ -ADRIAN -ARNOLDO -CARROLL -CARY -CHONG -CLIFTON -CODY -COLTON -CORNELL -DAMON -DANNIE -DARIO -DONN -DOUG -DOUGLAS -FREDERICK -FRITZ -GERALD -GUS -HARVEY -IRVING -ISAIAH -JARVIS -JOHN -KENTON -LAURENCE -LESTER -LINCOLN -LOWELL -NELSON -NEVILLE -NIGEL -NORMAND -ODIS -OMAR -ORLANDO -RAYMUNDO -REX -ROLANDO -RON -SHANE -TONEY -TRINIDAD -WALTER -WARNER -WARREN -WES -WILLARD -WILLIAM -WINFRED -XAVIER -found WES - -user 0, cookie 0 -user 1, cookie 1 -user 2, cookie 4 -user 3, cookie 9 -user 4, cookie 16 -user 5, cookie 25 -user 6, cookie 36 -user 7, cookie 49 -user 8, cookie 64 -user 9, cookie 81 -length is 3 -number 10 diff --git a/src/util/uthash/tests/test56.c b/src/util/uthash/tests/test56.c deleted file mode 100644 index 88c015c..0000000 --- a/src/util/uthash/tests/test56.c +++ /dev/null @@ -1,86 +0,0 @@ -#include /* malloc */ -#include /* printf */ -#include -#include "uthash.h" -#include "utlist.h" -#include "utstring.h" - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -#define BUFLEN 20 - -typedef struct el { - char bname[BUFLEN]; - struct el *next, *prev; -} el; - -int namecmp(void *_a, void *_b) { - el *a = (el*)_a; - el *b = (el*)_b; - return strcmp(a->bname,b->bname); -} - -el *head = NULL; /* important- initialize to NULL! */ - -int main(int argc, char *argv[]) { - el *name, *elt, *tmp, etmp; - int i; - example_user_t *user, *users=NULL; - - char linebuf[BUFLEN]; - FILE *file; - - UT_string *s; - char binary[] = "\xff\xff"; - - if ( (file = fopen( "test11.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,BUFLEN,file) != NULL) { - if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); - strncpy(name->bname,linebuf,BUFLEN); - DL_APPEND(head, name); - } - DL_SORT(head, namecmp); - DL_FOREACH(head,elt) printf("%s", elt->bname); - - memcpy(&etmp.bname, "WES\n", 5); - DL_SEARCH(head,elt,&etmp,namecmp); - if (elt) printf("found %s\n", elt->bname); - - /* now delete each element, use the safe iterator */ - DL_FOREACH_SAFE(head,elt,tmp) { - DL_DELETE(head,elt); - } - - fclose(file); - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - for(user=users; user != NULL; user=(example_user_t*)(user->hh.next)) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - - utstring_new(s); - utstring_bincpy(s, binary, sizeof(binary)); - printf("length is %u\n", utstring_len(s)); - - utstring_clear(s); - utstring_printf(s,"number %d", 10); - printf("%s\n", utstring_body(s)); - - utstring_free(s); - return 0; -} diff --git a/src/util/uthash/tests/test57.ans b/src/util/uthash/tests/test57.ans deleted file mode 100644 index 4d3bb1d..0000000 --- a/src/util/uthash/tests/test57.ans +++ /dev/null @@ -1 +0,0 @@ -found diff --git a/src/util/uthash/tests/test57.c b/src/util/uthash/tests/test57.c deleted file mode 100644 index 6a96e27..0000000 --- a/src/util/uthash/tests/test57.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include "uthash.h" - -typedef struct { - void *key; - int i; - UT_hash_handle hh; -} el_t; - -el_t *hash = NULL; -char *someaddr = NULL; - -int main() { - el_t *d; - el_t *e = (el_t*)malloc(sizeof(el_t)); - if (!e) return -1; - e->key = (void*)someaddr; - e->i = 1; - HASH_ADD_PTR(hash,key,e); - HASH_FIND_PTR(hash, &someaddr, d); - if (d) printf("found\n"); - - /* release memory */ - HASH_DEL(hash,e); - free(e); - return 0; -} diff --git a/src/util/uthash/tests/test58.ans b/src/util/uthash/tests/test58.ans deleted file mode 100644 index a23ca72..0000000 --- a/src/util/uthash/tests/test58.ans +++ /dev/null @@ -1,18 +0,0 @@ -user 0, cookie 0 -user 1, cookie 1 -user 2, cookie 4 -user 3, cookie 9 -user 4, cookie 16 -user 5, cookie 25 -user 6, cookie 36 -user 7, cookie 49 -user 8, cookie 64 -user 9, cookie 81 -10 users. Deleting odd id's... -user 0, cookie 0 -user 2, cookie 4 -user 4, cookie 16 -user 6, cookie 36 -user 8, cookie 64 -5 users. Deleting remaining id's... -0 users. diff --git a/src/util/uthash/tests/test58.c b/src/util/uthash/tests/test58.c deleted file mode 100644 index 6ec891c..0000000 --- a/src/util/uthash/tests/test58.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i,c; - example_user_t *user, *tmp, *users=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) - exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - /* show the hash */ - for(user=users; user != NULL; user=(example_user_t*)(user->hh.next)) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - - - c = HASH_COUNT(users); - printf("%d users. Deleting odd id's...\n", c); - /* delete the odd id's */ - HASH_ITER(hh, users, user, tmp) { - if (user->id & 1) HASH_DEL(users,user); - } - - /* show the hash */ - for(user=users; user != NULL; user=(example_user_t*)(user->hh.next)) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - - c = HASH_COUNT(users); - printf("%d users. Deleting remaining id's...\n", c); - /* delete all that are left */ - HASH_ITER(hh, users, user, tmp) { - HASH_DEL(users,user); - } - - c = HASH_COUNT(users); - printf("%d users.\n", c); - /* show the hash */ - for(user=users; user != NULL; user=(example_user_t*)(user->hh.next)) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - return 0; -} diff --git a/src/util/uthash/tests/test59.ans b/src/util/uthash/tests/test59.ans deleted file mode 100644 index e19f2f6..0000000 --- a/src/util/uthash/tests/test59.ans +++ /dev/null @@ -1 +0,0 @@ -$items{bob}{age} = 37 diff --git a/src/util/uthash/tests/test59.c b/src/util/uthash/tests/test59.c deleted file mode 100644 index 1fab25e..0000000 --- a/src/util/uthash/tests/test59.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include "uthash.h" - -/* hash of hashes */ -typedef struct item { - char name[10]; - struct item *sub; - int val; - UT_hash_handle hh; -} item_t; - -item_t *items=NULL; - -int main(int argc, char *argvp[]) { - item_t *item1, *item2, *tmp1, *tmp2; - - /* make initial element */ - item_t *i = malloc(sizeof(*i)); - strcpy(i->name, "bob"); - i->sub = NULL; - i->val = 0; - HASH_ADD_STR(items, name, i); - - /* add a sub hash table off this element */ - item_t *s = malloc(sizeof(*s)); - strcpy(s->name, "age"); - s->sub = NULL; - s->val = 37; - HASH_ADD_STR(i->sub, name, s); - - /* iterate over hash elements */ - HASH_ITER(hh, items, item1, tmp1) { - HASH_ITER(hh, item1->sub, item2, tmp2) { - printf("$items{%s}{%s} = %d\n", item1->name, item2->name, item2->val); - } - } - - /* clean up both hash tables */ - HASH_ITER(hh, items, item1, tmp1) { - HASH_ITER(hh, item1->sub, item2, tmp2) { - HASH_DEL(item1->sub, item2); - free(item2); - } - HASH_DEL(items, item1); - free(item1); - } - - return 0; -} diff --git a/src/util/uthash/tests/test6.ans b/src/util/uthash/tests/test6.ans deleted file mode 100644 index 5c95811..0000000 --- a/src/util/uthash/tests/test6.ans +++ /dev/null @@ -1 +0,0 @@ -alt malloc table diff --git a/src/util/uthash/tests/test6.c b/src/util/uthash/tests/test6.c deleted file mode 100644 index 40fc2aa..0000000 --- a/src/util/uthash/tests/test6.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -/* Set up macros for alternative malloc/free functions */ -#undef uthash_malloc -#undef uthash_free -#define uthash_malloc(sz) alt_malloc(sz) -#define uthash_free(ptr,sz) alt_free(ptr) - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -void *alt_malloc(size_t sz) { - if (sz == sizeof(UT_hash_table)) printf("%s\n", "alt malloc table"); - return malloc(sz); -} -void alt_free(void *ptr) { - /* printf("%s\n", "alt_free"); */ - free(ptr); -} - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *tmp, *users=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - /* delete each ID */ - for(i=0;i<10;i++) { - HASH_FIND_INT(users,&i,tmp); - if (tmp) { - HASH_DEL(users,tmp); - free(tmp); - } else printf("user id %d not found\n", i); - } - - /* show the hash */ - for(user=users; user != NULL; user=(example_user_t*)(user->hh.next)) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - return 0; -} diff --git a/src/util/uthash/tests/test60.ans b/src/util/uthash/tests/test60.ans deleted file mode 100644 index e19f2f6..0000000 --- a/src/util/uthash/tests/test60.ans +++ /dev/null @@ -1 +0,0 @@ -$items{bob}{age} = 37 diff --git a/src/util/uthash/tests/test60.c b/src/util/uthash/tests/test60.c deleted file mode 100644 index a1c1486..0000000 --- a/src/util/uthash/tests/test60.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include "uthash.h" - -/* hash of hashes */ -typedef struct item { - char name[10]; - struct item *sub; - int val; - UT_hash_handle hh; -} item_t; - -item_t *items=NULL; - -int main(int argc, char *argvp[]) { - item_t *item1, *item2, *tmp1, *tmp2; - - /* make initial element */ - item_t *i = malloc(sizeof(*i)); - strcpy(i->name, "bob"); - i->sub = NULL; - i->val = 0; - HASH_ADD_STR(items, name, i); - - /* add a sub hash table off this element */ - item_t *s = malloc(sizeof(*s)); - strcpy(s->name, "age"); - s->sub = NULL; - s->val = 37; - HASH_ADD_STR(i->sub, name, s); - - /* iterate over hash elements, printing and freeing them */ - HASH_ITER(hh, items, item1, tmp1) { - HASH_ITER(hh, item1->sub, item2, tmp2) { - printf("$items{%s}{%s} = %d\n", item1->name, item2->name, item2->val); - HASH_DEL(item1->sub, item2); - free(item2); - } - HASH_DEL(items, item1); - free(item1); - } - - return 0; -} diff --git a/src/util/uthash/tests/test61.ans b/src/util/uthash/tests/test61.ans deleted file mode 100644 index 39c63b4..0000000 --- a/src/util/uthash/tests/test61.ans +++ /dev/null @@ -1,16 +0,0 @@ -hello -world -one -two -three -sorting -finding hello - hello -finding one - one -finding three - three -finding two - two -finding world - world diff --git a/src/util/uthash/tests/test61.c b/src/util/uthash/tests/test61.c deleted file mode 100644 index b569957..0000000 --- a/src/util/uthash/tests/test61.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include "utarray.h" - -int strsort(const void *_a, const void *_b) { - char *a = *(char**)_a; - char *b = *(char**)_b; - return strcmp(a,b); -} - -int main() { - UT_array *strs; - char *s, **p; - - utarray_new(strs,&ut_str_icd); - - s = "hello"; utarray_push_back(strs, &s); - s = "world"; utarray_push_back(strs, &s); - s = "one"; utarray_push_back(strs, &s); - s = "two"; utarray_push_back(strs, &s); - s = "three"; utarray_push_back(strs, &s); - - p = NULL; - while ( (p=(char**)utarray_next(strs,p))) { - s = *p; - printf("%s\n",s); - } - - printf("sorting\n"); - utarray_sort(strs,strsort); - - p = NULL; - while ( (p=(char**)utarray_next(strs,p))) { - s = *p; - printf("finding %s\n",s); - p = utarray_find(strs,&s,strsort); - printf(" %s\n", p ? (*p) : "failed"); - } - - utarray_free(strs); - - return 0; -} diff --git a/src/util/uthash/tests/test62.ans b/src/util/uthash/tests/test62.ans deleted file mode 100644 index 1b71740..0000000 --- a/src/util/uthash/tests/test62.ans +++ /dev/null @@ -1,20 +0,0 @@ -al aligned (y): y -u1 aligned (n): n -u2 aligned (n): n -u3 aligned (n): n - -al plus1 (n): n -u1 plus1 (y): y -u2 plus1 (n): n -u3 plus1 (n): n - -al plus2 (n): n -u1 plus2 (n): n -u2 plus2 (y): y -u3 plus2 (n): n - -al plus3 (n): n -u1 plus3 (n): n -u2 plus3 (n): n -u3 plus3 (y): y - diff --git a/src/util/uthash/tests/test62.c b/src/util/uthash/tests/test62.c deleted file mode 100644 index ae80b9e..0000000 --- a/src/util/uthash/tests/test62.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include "uthash.h" - -#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) -#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) -#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) -#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) - -#define yn(rc) (rc?"y":"n") -int main(int argc,char*argv[]) { - unsigned rc; - char *c = malloc(8); - *(c+0) = 0x00; unsigned *al = (unsigned*)(c+0); - *(c+1) = 0x01; unsigned *u1 = (unsigned*)(c+1); - *(c+2) = 0x02; unsigned *u2 = (unsigned*)(c+2); - *(c+3) = 0x03; unsigned *u3 = (unsigned*)(c+3); - *(c+4) = 0x04; - *(c+5) = 0x05; - *(c+6) = 0x06; - *(c+7) = 0x07; - - /* ---------------------------------------- */ - /* test whether alignment is detected properly */ - - rc = MUR_PLUS0_ALIGNED(al); printf("al aligned (y): %s\n", yn(rc)); - rc = MUR_PLUS0_ALIGNED(u1); printf("u1 aligned (n): %s\n", yn(rc)); - rc = MUR_PLUS0_ALIGNED(u2); printf("u2 aligned (n): %s\n", yn(rc)); - rc = MUR_PLUS0_ALIGNED(u3); printf("u3 aligned (n): %s\n", yn(rc)); - printf("\n"); - - rc = MUR_PLUS1_ALIGNED(al); printf("al plus1 (n): %s\n", yn(rc)); - rc = MUR_PLUS1_ALIGNED(u1); printf("u1 plus1 (y): %s\n", yn(rc)); - rc = MUR_PLUS1_ALIGNED(u2); printf("u2 plus1 (n): %s\n", yn(rc)); - rc = MUR_PLUS1_ALIGNED(u3); printf("u3 plus1 (n): %s\n", yn(rc)); - printf("\n"); - - rc = MUR_PLUS2_ALIGNED(al); printf("al plus2 (n): %s\n", yn(rc)); - rc = MUR_PLUS2_ALIGNED(u1); printf("u1 plus2 (n): %s\n", yn(rc)); - rc = MUR_PLUS2_ALIGNED(u2); printf("u2 plus2 (y): %s\n", yn(rc)); - rc = MUR_PLUS2_ALIGNED(u3); printf("u3 plus2 (n): %s\n", yn(rc)); - printf("\n"); - - rc = MUR_PLUS3_ALIGNED(al); printf("al plus3 (n): %s\n", yn(rc)); - rc = MUR_PLUS3_ALIGNED(u1); printf("u1 plus3 (n): %s\n", yn(rc)); - rc = MUR_PLUS3_ALIGNED(u2); printf("u2 plus3 (n): %s\n", yn(rc)); - rc = MUR_PLUS3_ALIGNED(u3); printf("u3 plus3 (y): %s\n", yn(rc)); - printf("\n"); - - /* ---------------------------------------- */ - /* test careful reassembly of an unaligned integer */ -#if 0 /* commented out since result is endian dependent */ - rc = MUR_GETBLOCK(al,0); printf("%x\n", rc); - rc = MUR_GETBLOCK(u1,0); printf("%x\n", rc); - rc = MUR_GETBLOCK(u2,0); printf("%x\n", rc); - rc = MUR_GETBLOCK(u3,0); printf("%x\n", rc); -#endif - - return 0; -} diff --git a/src/util/uthash/tests/test63.ans b/src/util/uthash/tests/test63.ans deleted file mode 100644 index c570c50..0000000 --- a/src/util/uthash/tests/test63.ans +++ /dev/null @@ -1,7 +0,0 @@ -LL macros -a b c -d e f -a b c d e f -d e f -d e f -a b diff --git a/src/util/uthash/tests/test63.c b/src/util/uthash/tests/test63.c deleted file mode 100644 index 488f20b..0000000 --- a/src/util/uthash/tests/test63.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *headA = NULL, *headB = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[10], *e; - for(i=0;i<10;i++) els[i].id='a'+i; - - /* test LL macros */ - printf("LL macros\n"); - LL_APPEND(headA,&els[0]); - LL_APPEND(headA,&els[1]); - LL_APPEND(headA,&els[2]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - LL_APPEND(headB,&els[3]); - LL_APPEND(headB,&els[4]); - LL_APPEND(headB,&els[5]); - LL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - - LL_CONCAT(headA,headB); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* other variations */ - headA = NULL; - LL_CONCAT(headA,headB); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - headB = NULL; - LL_CONCAT(headA,headB); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - headA=NULL; - headB=NULL; - LL_APPEND(headA,&els[0]); - LL_APPEND(headB,&els[1]); - LL_CONCAT(headA,headB); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test64.ans b/src/util/uthash/tests/test64.ans deleted file mode 100644 index 1640241..0000000 --- a/src/util/uthash/tests/test64.ans +++ /dev/null @@ -1,7 +0,0 @@ -DL macros -a b c -d e f -a b c d e f -d e f -d e f -a b diff --git a/src/util/uthash/tests/test64.c b/src/util/uthash/tests/test64.c deleted file mode 100644 index 9d49e2d..0000000 --- a/src/util/uthash/tests/test64.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *headA = NULL, *headB = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[10], *e; - for(i=0;i<10;i++) els[i].id='a'+i; - - /* test DL macros */ - printf("DL macros\n"); - DL_APPEND(headA,&els[0]); - DL_APPEND(headA,&els[1]); - DL_APPEND(headA,&els[2]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - DL_APPEND(headB,&els[3]); - DL_APPEND(headB,&els[4]); - DL_APPEND(headB,&els[5]); - DL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - - DL_CONCAT(headA,headB); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* other variations */ - headA = NULL; - DL_CONCAT(headA,headB); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - headB = NULL; - DL_CONCAT(headA,headB); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - headA=NULL; - headB=NULL; - DL_APPEND(headA,&els[0]); - DL_APPEND(headB,&els[1]); - DL_CONCAT(headA,headB); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test65.ans b/src/util/uthash/tests/test65.ans deleted file mode 100644 index 5312b22..0000000 --- a/src/util/uthash/tests/test65.ans +++ /dev/null @@ -1,4 +0,0 @@ -LRU deleting JOHN - 0 -LRU deleting WILLIAM - 1 diff --git a/src/util/uthash/tests/test65.c b/src/util/uthash/tests/test65.c deleted file mode 100644 index ac0d4d8..0000000 --- a/src/util/uthash/tests/test65.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include "uthash.h" - -// this is an example of how to do a LRU cache in C using uthash -// http://troydhanson.github.com/uthash/ -// by Jehiah Czebotar 2011 - jehiah@gmail.com -// this code is in the public domain http://unlicense.org/ - -#define MAX_CACHE_SIZE 50 /* a real value would be much larger */ - -struct CacheEntry { - char *key; - char *value; - UT_hash_handle hh; -}; -struct CacheEntry *cache = NULL; - -char * /*value*/ find_in_cache(char *key) -{ - struct CacheEntry *entry; - HASH_FIND_STR(cache, key, entry); - if (entry) { - // remove it (so the subsequent add will throw it on the front of the list) - HASH_DELETE(hh, cache, entry); - HASH_ADD_KEYPTR(hh, cache, entry->key, strlen(entry->key), entry); - return entry->value; - } - return NULL; -} - -void add_to_cache(char *key, char *value) -{ - struct CacheEntry *entry, *tmp_entry; - entry = malloc(sizeof(struct CacheEntry)); - entry->key = strdup(key); - entry->value = strdup(value); - HASH_ADD_KEYPTR(hh, cache, entry->key, strlen(entry->key), entry); - - // prune the cache to MAX_CACHE_SIZE - if (HASH_COUNT(cache) >= MAX_CACHE_SIZE) { - HASH_ITER(hh, cache, entry, tmp_entry) { - // prune the first entry (loop is based on insertion order so this deletes the oldest item) - printf("LRU deleting %s %s\n", entry->key, entry->value); - HASH_DELETE(hh, cache, entry); - free(entry->key); - free(entry->value); - free(entry); - break; - } - } -} - -/* main added by Troy D. Hanson */ -int main(int argc, char *argv[]) { - char linebuf[100], nbuf[10]; - FILE *file; - int i=0; - - if ( (file = fopen( "test65.dat", "r" )) == NULL ) { - perror("can't open: "); - exit(-1); - } - - while (fgets(linebuf,sizeof(linebuf),file) != NULL) { - snprintf(nbuf,sizeof(nbuf),"%u",i++); - add_to_cache(linebuf, nbuf); - } - - fclose(file); - return 0; -} diff --git a/src/util/uthash/tests/test65.dat b/src/util/uthash/tests/test65.dat deleted file mode 100644 index bb6051b..0000000 --- a/src/util/uthash/tests/test65.dat +++ /dev/null @@ -1,51 +0,0 @@ -JOHN -WILLIAM -WALTER -DOUGLAS -GERALD -FREDERICK -WARREN -SHANE -LESTER -RON -HARVEY -ADRIAN -CODY -NELSON -CLIFTON -WILLARD -DOUG -ORLANDO -REX -OMAR -DAMON -LOWELL -IRVING -CARROLL -LAURENCE -ROLANDO -CARY -XAVIER -ISAIAH -GUS -JARVIS -WINFRED -RAYMUNDO -LINCOLN -CORNELL -NIGEL -NORMAND -FRITZ -DONN -TRINIDAD -ODIS -DANNIE -DARIO -KENTON -CHONG -NEVILLE -TONEY -WARNER -WES -COLTON -ARNOLDO diff --git a/src/util/uthash/tests/test66.ans b/src/util/uthash/tests/test66.ans deleted file mode 100644 index 727f397..0000000 --- a/src/util/uthash/tests/test66.ans +++ /dev/null @@ -1,20 +0,0 @@ -added bob (id 0) -added jack (id 1) -added gary (id 2) -added ty (id 3) -added bo (id 4) -added phil (id 5) -added art (id 6) -added gil (id 7) -added buck (id 8) -added ted (id 9) -found bob (id 0) -found jack (id 1) -found gary (id 2) -found ty (id 3) -found bo (id 4) -found phil (id 5) -found art (id 6) -found gil (id 7) -found buck (id 8) -found ted (id 9) diff --git a/src/util/uthash/tests/test66.c b/src/util/uthash/tests/test66.c deleted file mode 100644 index d50deb5..0000000 --- a/src/util/uthash/tests/test66.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "uthash.h" -#include -#include /* malloc */ - -typedef struct person_t { - char first_name[10]; - int id; - UT_hash_handle hh; -} person_t; - -int main(int argc, char*argv[]) { - person_t *people=NULL, *person; - const char **name; - const char * names[] = { "bob", "jack", "gary", "ty", "bo", "phil", "art", - "gil", "buck", "ted", NULL }; - int id=0; - - for(name=names; *name; name++) { - if ( (person = (person_t*)malloc(sizeof(person_t))) == NULL) exit(-1); - strncpy(person->first_name, *name,10); - person->id = id++; - HASH_ADD_STR(people,first_name,person); - printf("added %s (id %d)\n", person->first_name, person->id); - } - - person=NULL; - person_t **p=&person; - - for(name=names; *name; name++) { - HASH_FIND_STR(people,*name,*p); - if (person) - printf("found %s (id %d)\n", person->first_name, person->id); - else - printf("failed to find %s\n", *name); - } - return 0; -} diff --git a/src/util/uthash/tests/test67.ans b/src/util/uthash/tests/test67.ans deleted file mode 100644 index cd70769..0000000 --- a/src/util/uthash/tests/test67.ans +++ /dev/null @@ -1,20 +0,0 @@ -9 -8 -7 -6 -5 -4 -3 -2 -1 -0 -9 -8 -7 -6 -5 -4 -3 -2 -1 -0 diff --git a/src/util/uthash/tests/test67.c b/src/util/uthash/tests/test67.c deleted file mode 100644 index 00dc01a..0000000 --- a/src/util/uthash/tests/test67.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include "utarray.h" - -int main() { - UT_array *nums; - int i, *p; - - utarray_new(nums,&ut_int_icd); - for(i=0; i < 10; i++) utarray_push_back(nums,&i); - - for(p=(int*)utarray_back(nums); - p!=NULL; - p=(int*)utarray_prev(nums,p)) { - printf("%d\n",*p); - } - - /* the other form of iteration starting from NULL (back) */ - p=NULL; - while ( (p=(int*)utarray_prev(nums,p))) { - printf("%d\n",*p); - } - - - utarray_free(nums); - - return 0; -} diff --git a/src/util/uthash/tests/test68.ans b/src/util/uthash/tests/test68.ans deleted file mode 100644 index 704cdc5..0000000 --- a/src/util/uthash/tests/test68.ans +++ /dev/null @@ -1,10 +0,0 @@ -DL replace elem -a b c d -e b c d -f b c d -f b c g -f b c h -f i j h -k l m n -s -t diff --git a/src/util/uthash/tests/test68.c b/src/util/uthash/tests/test68.c deleted file mode 100644 index 7c5e77d..0000000 --- a/src/util/uthash/tests/test68.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *headA, *headB = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[20], *e, *tmp; - for(i=0;i<20;i++) els[i].id='a'+i; - - /* test DL macros */ - printf("DL replace elem\n"); - DL_APPEND(headA,&els[0]); - DL_APPEND(headA,&els[1]); - DL_APPEND(headA,&els[2]); - DL_APPEND(headA,&els[3]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace head elem */ - DL_REPLACE_ELEM(headA, &els[0], &els[4]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - DL_REPLACE_ELEM(headA, &els[4], &els[5]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace last elem */ - DL_REPLACE_ELEM(headA, &els[3], &els[6]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - DL_REPLACE_ELEM(headA, &els[6], &els[7]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace middle elem */ - DL_REPLACE_ELEM(headA, &els[1], &els[8]); - DL_REPLACE_ELEM(headA, &els[2], &els[9]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace all just to be sure the list is intact... */ - i = 10; - DL_FOREACH_SAFE(headA, e, tmp) { - DL_REPLACE_ELEM(headA, e, &els[i]); - i++; - } - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* single elem */ - DL_APPEND(headB, &els[18]); - DL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - DL_REPLACE_ELEM(headB, &els[18], &els[19]); - DL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test69.ans b/src/util/uthash/tests/test69.ans deleted file mode 100644 index fba8b64..0000000 --- a/src/util/uthash/tests/test69.ans +++ /dev/null @@ -1,11 +0,0 @@ -DL prepend elem -a b c d -e a b c d -f e a b c d -f e a b c g d -f e a b c h g d -f e a b i j c h g d -k f l e m a n b o i p j q c r h s g t d -u -v u -w v u diff --git a/src/util/uthash/tests/test69.c b/src/util/uthash/tests/test69.c deleted file mode 100644 index 169c222..0000000 --- a/src/util/uthash/tests/test69.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *headA, *headB = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[26], *e, *tmp; - for(i=0;i<25;i++) els[i].id='a'+i; - - /* test DL macros */ - printf("DL prepend elem\n"); - DL_APPEND(headA,&els[0]); - DL_APPEND(headA,&els[1]); - DL_APPEND(headA,&els[2]); - DL_APPEND(headA,&els[3]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend head elem */ - DL_PREPEND_ELEM(headA, &els[0], &els[4]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - DL_PREPEND_ELEM(headA, &els[4], &els[5]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend last elem */ - DL_PREPEND_ELEM(headA, &els[3], &els[6]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - DL_PREPEND_ELEM(headA, &els[6], &els[7]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend middle elem */ - DL_PREPEND_ELEM(headA, &els[2], &els[8]); - DL_PREPEND_ELEM(headA, &els[2], &els[9]); - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend all just to be sure the list is intact... */ - i = 10; - DL_FOREACH_SAFE(headA, e, tmp) { - DL_PREPEND_ELEM(headA, e, &els[i]); - i++; - } - DL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* single elem */ - DL_APPEND(headB, &els[20]); - DL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - DL_PREPEND_ELEM(headB, &els[20], &els[21]); - DL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - DL_PREPEND_ELEM(headB, &els[21], &els[22]); - DL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test7.ans b/src/util/uthash/tests/test7.ans deleted file mode 100644 index e69de29..0000000 diff --git a/src/util/uthash/tests/test7.c b/src/util/uthash/tests/test7.c deleted file mode 100644 index 3f76c8d..0000000 --- a/src/util/uthash/tests/test7.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *tmp, *users=NULL; - - /* create elements */ - for(i=0;i<1000;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - /* delete each ID */ - for(i=0;i<1000;i++) { - HASH_FIND_INT(users,&i,tmp); - if (tmp) { - HASH_DEL(users,tmp); - free(tmp); - } else printf("user id %d not found\n", i); - } - - /* show the hash */ - for(user=users; user != NULL; user=(example_user_t*)(user->hh.next)) { - printf("user %d, cookie %d\n", user->id, user->cookie); - } - return 0; -} diff --git a/src/util/uthash/tests/test70.ans b/src/util/uthash/tests/test70.ans deleted file mode 100644 index 00298ec..0000000 --- a/src/util/uthash/tests/test70.ans +++ /dev/null @@ -1,10 +0,0 @@ -LL replace elem -a b c d -e b c d -f b c d -f b c g -f b c h -f i j h -k l m n -s -t diff --git a/src/util/uthash/tests/test70.c b/src/util/uthash/tests/test70.c deleted file mode 100644 index c4291be..0000000 --- a/src/util/uthash/tests/test70.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *headA, *headB = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[20], *e, *tmp; - for(i=0;i<20;i++) els[i].id='a'+i; - - /* test LL macros */ - printf("LL replace elem\n"); - LL_APPEND(headA,&els[0]); - LL_APPEND(headA,&els[1]); - LL_APPEND(headA,&els[2]); - LL_APPEND(headA,&els[3]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace head elem */ - LL_REPLACE_ELEM(headA, &els[0], &els[4]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - LL_REPLACE_ELEM(headA, &els[4], &els[5]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace last elem */ - LL_REPLACE_ELEM(headA, &els[3], &els[6]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - LL_REPLACE_ELEM(headA, &els[6], &els[7]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace middle elem */ - LL_REPLACE_ELEM(headA, &els[1], &els[8]); - LL_REPLACE_ELEM(headA, &els[2], &els[9]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace all just to be sure the list is intact... */ - i = 10; - LL_FOREACH_SAFE(headA, e, tmp) { - LL_REPLACE_ELEM(headA, e, &els[i]); - i++; - } - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* single elem */ - LL_APPEND(headB, &els[18]); - LL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - LL_REPLACE_ELEM(headB, &els[18], &els[19]); - LL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test71.ans b/src/util/uthash/tests/test71.ans deleted file mode 100644 index 81d6b53..0000000 --- a/src/util/uthash/tests/test71.ans +++ /dev/null @@ -1,11 +0,0 @@ -LL prepend elem -a b c d -e a b c d -f e a b c d -f e a b c g d -f e a b c h g d -f e a b i j c h g d -k f l e m a n b o i p j q c r h s g t d -u -v u -w v u diff --git a/src/util/uthash/tests/test71.c b/src/util/uthash/tests/test71.c deleted file mode 100644 index e4126c1..0000000 --- a/src/util/uthash/tests/test71.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *headA, *headB = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[26], *e, *tmp; - for(i=0;i<25;i++) els[i].id='a'+i; - - /* test LL macros */ - printf("LL prepend elem\n"); - LL_APPEND(headA,&els[0]); - LL_APPEND(headA,&els[1]); - LL_APPEND(headA,&els[2]); - LL_APPEND(headA,&els[3]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend head elem */ - LL_PREPEND_ELEM(headA, &els[0], &els[4]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - LL_PREPEND_ELEM(headA, &els[4], &els[5]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend last elem */ - LL_PREPEND_ELEM(headA, &els[3], &els[6]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - LL_PREPEND_ELEM(headA, &els[6], &els[7]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend middle elem */ - LL_PREPEND_ELEM(headA, &els[2], &els[8]); - LL_PREPEND_ELEM(headA, &els[2], &els[9]); - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend all just to be sure the list is intact... */ - i = 10; - LL_FOREACH_SAFE(headA, e, tmp) { - LL_PREPEND_ELEM(headA, e, &els[i]); - i++; - } - LL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* single elem */ - LL_APPEND(headB, &els[20]); - LL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - LL_PREPEND_ELEM(headB, &els[20], &els[21]); - LL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - LL_PREPEND_ELEM(headB, &els[21], &els[22]); - LL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test72.ans b/src/util/uthash/tests/test72.ans deleted file mode 100644 index b5ccb14..0000000 --- a/src/util/uthash/tests/test72.ans +++ /dev/null @@ -1,10 +0,0 @@ -CDL replace elem -a b c d -e b c d -f b c d -f b c g -f b c h -f i j h -k l m n -s -t diff --git a/src/util/uthash/tests/test72.c b/src/util/uthash/tests/test72.c deleted file mode 100644 index 51a6fc4..0000000 --- a/src/util/uthash/tests/test72.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *headA, *headB = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[20], *e, *tmp, *tmp2; - for(i=0;i<20;i++) els[i].id='a'+i; - - /* test CDL macros */ - printf("CDL replace elem\n"); - CDL_PREPEND(headA,&els[3]); - CDL_PREPEND(headA,&els[2]); - CDL_PREPEND(headA,&els[1]); - CDL_PREPEND(headA,&els[0]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace head elem */ - CDL_REPLACE_ELEM(headA, &els[0], &els[4]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - CDL_REPLACE_ELEM(headA, &els[4], &els[5]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace last elem */ - CDL_REPLACE_ELEM(headA, &els[3], &els[6]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - CDL_REPLACE_ELEM(headA, &els[6], &els[7]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace middle elem */ - CDL_REPLACE_ELEM(headA, &els[1], &els[8]); - CDL_REPLACE_ELEM(headA, &els[2], &els[9]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* replace all just to be sure the list is intact... */ - i = 10; - CDL_FOREACH_SAFE(headA, e, tmp, tmp2) { - CDL_REPLACE_ELEM(headA, e, &els[i]); - i++; - } - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* single elem */ - CDL_PREPEND(headB, &els[18]); - CDL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - CDL_REPLACE_ELEM(headB, &els[18], &els[19]); - CDL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test73.ans b/src/util/uthash/tests/test73.ans deleted file mode 100644 index 2aa7bdc..0000000 --- a/src/util/uthash/tests/test73.ans +++ /dev/null @@ -1,11 +0,0 @@ -CDL prepend elem -a b c d -e a b c d -f e a b c d -f e a b c g d -f e a b c h g d -f e a b i j c h g d -k f l e m a n b o i p j q c r h s g t d -u -v u -w v u diff --git a/src/util/uthash/tests/test73.c b/src/util/uthash/tests/test73.c deleted file mode 100644 index f1112ea..0000000 --- a/src/util/uthash/tests/test73.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *next, *prev; -} el; - -el *headA, *headB = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[26], *e, *tmp, *tmp2; - for(i=0;i<25;i++) els[i].id='a'+i; - - /* test CDL macros */ - printf("CDL prepend elem\n"); - CDL_PREPEND(headA,&els[3]); - CDL_PREPEND(headA,&els[2]); - CDL_PREPEND(headA,&els[1]); - CDL_PREPEND(headA,&els[0]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend head elem */ - CDL_PREPEND_ELEM(headA, &els[0], &els[4]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - CDL_PREPEND_ELEM(headA, &els[4], &els[5]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend last elem */ - CDL_PREPEND_ELEM(headA, &els[3], &els[6]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - CDL_PREPEND_ELEM(headA, &els[6], &els[7]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend middle elem */ - CDL_PREPEND_ELEM(headA, &els[2], &els[8]); - CDL_PREPEND_ELEM(headA, &els[2], &els[9]); - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* prepend all just to be sure the list is intact... */ - i = 10; - CDL_FOREACH_SAFE(headA, e, tmp, tmp2) { - CDL_PREPEND_ELEM(headA, e, &els[i]); - i++; - } - CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); - - /* single elem */ - CDL_PREPEND(headB, &els[20]); - CDL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - CDL_PREPEND_ELEM(headB, &els[20], &els[21]); - CDL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - CDL_PREPEND_ELEM(headB, &els[21], &els[22]); - CDL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test74.ans b/src/util/uthash/tests/test74.ans deleted file mode 100644 index 79a16ba..0000000 --- a/src/util/uthash/tests/test74.ans +++ /dev/null @@ -1,6 +0,0 @@ -"There are two needle" len=55 -"needle" len=8 -utstring_find()=14 -utstring_find()=46 -utstring_find()=-1 -FindCnt=2 diff --git a/src/util/uthash/tests/test74.c b/src/util/uthash/tests/test74.c deleted file mode 100644 index e11ad55..0000000 --- a/src/util/uthash/tests/test74.c +++ /dev/null @@ -1,41 +0,0 @@ -#include /* printf */ -#include "utstring.h" - -int main() { - UT_string *s,*t; - char V_TestStr[] = "There are two needle\0s in this \0haystack with needle\0s."; - char V_NeedleStr[] = "needle\0s"; - long V_FindPos; - size_t V_FindCnt; - - - utstring_new(s); - utstring_new(t); - - utstring_bincpy(s, V_TestStr, sizeof(V_TestStr)-1); - printf("\"%s\" len=%u\n", utstring_body(s), utstring_len(s)); - utstring_bincpy(t, V_NeedleStr, sizeof(V_NeedleStr)-1); - printf("\"%s\" len=%u\n", utstring_body(t), utstring_len(t)); - - V_FindCnt = 0; - V_FindPos = 0; - do - { - V_FindPos = utstring_find(s, - V_FindPos, - utstring_body(t), - utstring_len(t)); - printf("utstring_find()=%ld\n", V_FindPos); - if (V_FindPos >= 0) - { - V_FindPos++; - V_FindCnt++; - } - } while (V_FindPos >= 0); - printf("FindCnt=%u\n", (unsigned)V_FindCnt); - - utstring_free(s); - utstring_free(t); - - return 0; -} diff --git a/src/util/uthash/tests/test75.ans b/src/util/uthash/tests/test75.ans deleted file mode 100644 index 8261ba3..0000000 --- a/src/util/uthash/tests/test75.ans +++ /dev/null @@ -1,6 +0,0 @@ -"There are two needle" len=55 -"needle" len=8 -utstring_findR()=46 -utstring_findR()=14 -utstring_findR()=-1 -FindCnt=2 diff --git a/src/util/uthash/tests/test75.c b/src/util/uthash/tests/test75.c deleted file mode 100644 index bb8e8e0..0000000 --- a/src/util/uthash/tests/test75.c +++ /dev/null @@ -1,41 +0,0 @@ -#include /* printf */ -#include "utstring.h" - -int main() { - UT_string *s,*t; - char V_TestStr[] = "There are two needle\0s in this \0haystack with needle\0s."; - char V_NeedleStr[] = "needle\0s"; - long V_FindPos; - size_t V_FindCnt; - - - utstring_new(s); - utstring_new(t); - - utstring_bincpy(s, V_TestStr, sizeof(V_TestStr)-1); - printf("\"%s\" len=%u\n", utstring_body(s), utstring_len(s)); - utstring_bincpy(t, V_NeedleStr, sizeof(V_NeedleStr)-1); - printf("\"%s\" len=%u\n", utstring_body(t), utstring_len(t)); - - V_FindCnt = 0; - V_FindPos = -1; - do - { - V_FindPos = utstring_findR(s, - V_FindPos, - utstring_body(t), - utstring_len(t)); - printf("utstring_findR()=%ld\n", V_FindPos); - if (V_FindPos >= 0) - { - V_FindPos--; - V_FindCnt++; - } - } while (V_FindPos >= 0); - printf("FindCnt=%u\n", (unsigned)V_FindCnt); - - utstring_free(s); - utstring_free(t); - - return 0; -} diff --git a/src/util/uthash/tests/test76.ans b/src/util/uthash/tests/test76.ans deleted file mode 100644 index 79a16ba..0000000 --- a/src/util/uthash/tests/test76.ans +++ /dev/null @@ -1,6 +0,0 @@ -"There are two needle" len=55 -"needle" len=8 -utstring_find()=14 -utstring_find()=46 -utstring_find()=-1 -FindCnt=2 diff --git a/src/util/uthash/tests/test76.c b/src/util/uthash/tests/test76.c deleted file mode 100644 index 8ead835..0000000 --- a/src/util/uthash/tests/test76.c +++ /dev/null @@ -1,58 +0,0 @@ -#include /* printf */ -#include "utstring.h" - -int main() { - UT_string *s,*t; - char V_TestStr[] = "There are two needle\0s in this \0haystack with needle\0s."; - char V_NeedleStr[] = "needle\0s"; - long *V_KMP_Table; - long V_FindPos; - size_t V_StartPos; - size_t V_FindCnt; - - - utstring_new(s); - utstring_new(t); - - utstring_bincpy(s, V_TestStr, sizeof(V_TestStr)-1); - printf("\"%s\" len=%u\n", utstring_body(s), utstring_len(s)); - utstring_bincpy(t, V_NeedleStr, sizeof(V_NeedleStr)-1); - printf("\"%s\" len=%u\n", utstring_body(t), utstring_len(t)); - - V_KMP_Table = (long *)malloc(sizeof(long) * (utstring_len(t) + 1)); - if (V_KMP_Table != NULL) - { - _utstring_BuildTable(utstring_body(t), utstring_len(t), V_KMP_Table); - - V_FindCnt = 0; - V_FindPos = 0; - V_StartPos = 0; - do - { - V_FindPos = _utstring_find(utstring_body(s) + V_StartPos, - utstring_len(s) - V_StartPos, - utstring_body(t), - utstring_len(t), - V_KMP_Table); - if (V_FindPos >= 0) - { - V_FindPos += V_StartPos; - V_FindCnt++; - V_StartPos = V_FindPos + 1; - } - printf("utstring_find()=%ld\n", V_FindPos); - } while (V_FindPos >= 0); - printf("FindCnt=%u\n", (unsigned)V_FindCnt); - - free(V_KMP_Table); - } - else - { - printf("malloc() failed...\n"); - } - - utstring_free(s); - utstring_free(t); - - return 0; -} diff --git a/src/util/uthash/tests/test77.ans b/src/util/uthash/tests/test77.ans deleted file mode 100644 index 3b2a109..0000000 --- a/src/util/uthash/tests/test77.ans +++ /dev/null @@ -1,13 +0,0 @@ -"There are two needle" len=55 -"needle" len=8 -utstring_find()=46 -utstring_find()=14 -utstring_find()=-1 -FindCnt=2 -expect 15 15 -expect 4 4 -expect -1 -1 -expect 11 11 -expect 4 4 -expect 11 11 -expect 0 0 diff --git a/src/util/uthash/tests/test77.c b/src/util/uthash/tests/test77.c deleted file mode 100644 index ee90b2a..0000000 --- a/src/util/uthash/tests/test77.c +++ /dev/null @@ -1,71 +0,0 @@ -#include /* printf */ -#include "utstring.h" - -int main() { - UT_string *s,*t; - char V_TestStr[] = "There are two needle\0s in this \0haystack with needle\0s."; - char V_NeedleStr[] = "needle\0s"; - long *V_KMP_Table; - long V_FindPos; - size_t V_StartPos; - size_t V_FindCnt; - - - utstring_new(s); - utstring_new(t); - - utstring_bincpy(s, V_TestStr, sizeof(V_TestStr)-1); - printf("\"%s\" len=%u\n", utstring_body(s), utstring_len(s)); - utstring_bincpy(t, V_NeedleStr, sizeof(V_NeedleStr)-1); - printf("\"%s\" len=%u\n", utstring_body(t), utstring_len(t)); - - V_KMP_Table = (long *)malloc(sizeof(long) * (utstring_len(t) + 1)); - if (V_KMP_Table != NULL) - { - _utstring_BuildTableR(utstring_body(t), utstring_len(t), V_KMP_Table); - - V_FindCnt = 0; - V_FindPos = 0; - V_StartPos = utstring_len(s) - 1; - do - { - V_FindPos = _utstring_findR(utstring_body(s), - V_StartPos + 1, - utstring_body(t), - utstring_len(t), - V_KMP_Table); - if (V_FindPos >= 0) - { - V_FindCnt++; - V_StartPos = V_FindPos - 1; - } - printf("utstring_find()=%ld\n", V_FindPos); - } while (V_FindPos >= 0); - printf("FindCnt=%u\n", (unsigned)V_FindCnt); - - free(V_KMP_Table); - } - else - { - printf("malloc() failed...\n"); - } - - utstring_free(t); - utstring_clear(s); - utstring_printf(s,"ABC ABCDAB ABCDABCDABDE"); - int o; - - o=utstring_find( s, -9, "ABC", 3 ) ; printf("expect 15 %d\n",o); - o=utstring_find( s, 3, "ABC", 3 ) ; printf("expect 4 %d\n",o); - o=utstring_find( s, 16, "ABC", 3 ) ; printf("expect -1 %d\n",o); - o=utstring_findR( s, -9, "ABC", 3 ) ; printf("expect 11 %d\n",o); - o=utstring_findR( s, 12, "ABC", 3 ) ; printf("expect 4 %d\n",o); - o=utstring_findR( s, 13, "ABC", 3 ) ; printf("expect 11 %d\n",o); - o=utstring_findR( s, 2, "ABC", 3 ) ; printf("expect 0 %d\n",o); - - - - utstring_free(s); - - return 0; -} diff --git a/src/util/uthash/tests/test78.ans b/src/util/uthash/tests/test78.ans deleted file mode 100644 index 5c71cdf..0000000 --- a/src/util/uthash/tests/test78.ans +++ /dev/null @@ -1,28 +0,0 @@ -CDL macros -c b a -advancing head pointer -b a c -b a c b a c b a c b -b c a b c a b c a b -deleting b -a c -deleting (a) -c -deleting (c) - -DL macros -a b c -deleting tail c -a b -deleting head a -b -deleting head b - -LL macros -a b c -deleting tail c -a b -deleting head a -b -deleting head b - diff --git a/src/util/uthash/tests/test78.c b/src/util/uthash/tests/test78.c deleted file mode 100644 index f73e029..0000000 --- a/src/util/uthash/tests/test78.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include "utlist.h" - -typedef struct el { - int id; - struct el *Next, *Prev; -} el; - -el *head = NULL; - -int main(int argc, char *argv[]) { - int i; - el els[10], *e; - for(i=0;i<10;i++) els[i].id='a'+i; - - /* test CDL macros */ - printf("CDL macros\n"); - CDL_PREPEND2(head,&els[0],Prev,Next); - CDL_PREPEND2(head,&els[1],Prev,Next); - CDL_PREPEND2(head,&els[2],Prev,Next); - CDL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - /* point head to head->next */ - printf("advancing head pointer\n"); - head = head->Next; - CDL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - /* follow circular loop a few times */ - for(i=0,e=head;e && i<10;i++,e=e->Next) - printf("%c ", e->id); - printf("\n"); - - /* follow circular loop backwards a few times */ - for(i=0,e=head;e && i<10;i++,e=e->Prev) - printf("%c ", e->id); - printf("\n"); - - printf("deleting b\n"); - CDL_DELETE2(head,&els[1],Prev,Next); - CDL_FOREACH2(head,e,Next) printf("%c ", e->id); - printf("\n"); - printf("deleting (a)\n"); - CDL_DELETE2(head,&els[0],Prev,Next); - CDL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - printf("deleting (c)\n"); - CDL_DELETE2(head,&els[2],Prev,Next); - CDL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - /* test DL macros */ - printf("DL macros\n"); - DL_APPEND2(head,&els[0],Prev,Next); - DL_APPEND2(head,&els[1],Prev,Next); - DL_APPEND2(head,&els[2],Prev,Next); - DL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - printf("deleting tail c\n"); - DL_DELETE2(head,&els[2],Prev,Next); - DL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - printf("deleting head a\n"); - DL_DELETE2(head,&els[0],Prev,Next); - DL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - printf("deleting head b\n"); - DL_DELETE2(head,&els[1],Prev,Next); - DL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - /* test LL macros */ - printf("LL macros\n"); - LL_APPEND2(head,&els[0],Next); - LL_APPEND2(head,&els[1],Next); - LL_APPEND2(head,&els[2],Next); - LL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - printf("deleting tail c\n"); - LL_DELETE2(head,&els[2],Next); - LL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - printf("deleting head a\n"); - LL_DELETE2(head,&els[0],Next); - LL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - printf("deleting head b\n"); - LL_DELETE2(head,&els[1],Next); - LL_FOREACH2(head,e,Next) - printf("%c ", e->id); - printf("\n"); - - return 0; -} diff --git a/src/util/uthash/tests/test79.ans b/src/util/uthash/tests/test79.ans deleted file mode 100644 index c8737e4..0000000 --- a/src/util/uthash/tests/test79.ans +++ /dev/null @@ -1,8 +0,0 @@ -added 10 100 -id 10, tag 100 -added 11 101 -id 10, tag 100 -id 11, tag 101 -replaced 11 that had tag 101 with tag 102 -id 10, tag 100 -id 11, tag 102 diff --git a/src/util/uthash/tests/test79.c b/src/util/uthash/tests/test79.c deleted file mode 100644 index f4ad83b..0000000 --- a/src/util/uthash/tests/test79.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include "uthash.h" - -typedef struct hs_t { - int id; - int tag; - UT_hash_handle hh; -} hs_t; - - -static void pr(hs_t **hdpp){ - hs_t *el, *tmp, *hdp = *hdpp; - HASH_ITER(hh, hdp, el, tmp){ - printf("id %d, tag %d\n",el->id,el->tag); - } -} - -int main(int argc, char *argv[]) { - - hs_t *hs_head=NULL, *tmp, *replaced=NULL; - - tmp = (hs_t*)malloc(sizeof(hs_t)); - tmp->id = 10; - tmp->tag = 100; - HASH_REPLACE_INT(hs_head,id,tmp,replaced); - if(replaced == NULL) - printf("added %d %d\n",tmp->id,tmp->tag); - else - printf("ERROR, ended up replacing a value, replaced: %p\n",replaced); - - pr(&hs_head); - - tmp = (hs_t*)malloc(sizeof(hs_t)); - tmp->id=11; - tmp->tag = 101; - HASH_REPLACE_INT(hs_head,id,tmp,replaced); - if(replaced == NULL) - printf("added %d %d\n",tmp->id,tmp->tag); - else - printf("ERROR, ended up replacing a value, replaced: %p\n",replaced); - - pr(&hs_head); - - tmp = (hs_t*)malloc(sizeof(hs_t)); - tmp->id=11; - tmp->tag = 102; - HASH_REPLACE_INT(hs_head,id,tmp,replaced); - if(replaced == NULL) - printf("ERROR, exected to replace a value with key: %d\n",tmp->id); - else - printf("replaced %d that had tag %d with tag %d\n",tmp->id,replaced->tag,tmp->tag); - - pr(&hs_head); - - return 0; -} diff --git a/src/util/uthash/tests/test8.ans b/src/util/uthash/tests/test8.ans deleted file mode 100644 index 9d28857..0000000 --- a/src/util/uthash/tests/test8.ans +++ /dev/null @@ -1,15 +0,0 @@ -num_items in hash: 1 -num_items in hash: 2 -num_items in hash: 3 -num_items in hash: 4 -num_items in hash: 5 -num_items in hash: 6 -num_items in hash: 7 -num_items in hash: 8 -num_items in hash: 9 -num_items in hash: 10 -deleted; num_items in hash: 9 -deleted; num_items in hash: 8 -deleted; num_items in hash: 7 -deleted; num_items in hash: 6 -deleted; num_items in hash: 5 diff --git a/src/util/uthash/tests/test8.c b/src/util/uthash/tests/test8.c deleted file mode 100644 index f7c7c8d..0000000 --- a/src/util/uthash/tests/test8.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *tmp, *users=NULL; - - /* create elements */ - for(i=0;i<10;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - printf("num_items in hash: %d\n", user->hh.tbl->num_items); - } - - /* delete each even ID */ - for(i=0;i<10;i+=2) { - HASH_FIND_INT(users,&i,tmp); - if (tmp) { - HASH_DEL(users,tmp); - free(tmp); - printf("deleted; num_items in hash: %d\n", user->hh.tbl->num_items); - } else printf("user id %d not found\n", i); - } - return 0; -} diff --git a/src/util/uthash/tests/test80.ans b/src/util/uthash/tests/test80.ans deleted file mode 100644 index 763f637..0000000 --- a/src/util/uthash/tests/test80.ans +++ /dev/null @@ -1,6 +0,0 @@ -0 1 2 3 4 5 6 7 8 9 -len: 10 - -0 1 2 3 4 5 6 7 8 9 0 11 -len: 12 - diff --git a/src/util/uthash/tests/test80.c b/src/util/uthash/tests/test80.c deleted file mode 100644 index 9a415b4..0000000 --- a/src/util/uthash/tests/test80.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include "utarray.h" - -int main() { - UT_array *a; - int i, *p; - utarray_new(a, &ut_int_icd); - for(i=0;i<10;i++) utarray_push_back(a,&i); - for(p=(int*)utarray_front(a); p; p=(int*)utarray_next(a,p)) printf("%d ",*p); - printf("\n"); - printf("len: %u\n\n", utarray_len(a)); - - i=11; utarray_insert(a, &i, 11); - while ( (p=(int*)utarray_next(a,p))) printf("%d ", *p); printf("\n"); - printf("len: %u\n\n", utarray_len(a)); - - utarray_free(a); - return 0; -} - diff --git a/src/util/uthash/tests/test81.ans b/src/util/uthash/tests/test81.ans deleted file mode 100644 index 24adbd9..0000000 --- a/src/util/uthash/tests/test81.ans +++ /dev/null @@ -1,6 +0,0 @@ -0 1 2 3 4 5 6 7 8 9 -len: 10 - -0 1 2 3 4 5 6 7 8 9 10 -len: 11 - diff --git a/src/util/uthash/tests/test81.c b/src/util/uthash/tests/test81.c deleted file mode 100644 index 022d42e..0000000 --- a/src/util/uthash/tests/test81.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include "utarray.h" - -int main() { - UT_array *a; - int i, *p; - utarray_new(a, &ut_int_icd); - for(i=0;i<10;i++) utarray_push_back(a,&i); - for(p=(int*)utarray_front(a); p; p=(int*)utarray_next(a,p)) printf("%d ",*p); - printf("\n"); - printf("len: %u\n\n", utarray_len(a)); - - i=10; utarray_insert(a, &i, 10); - while ( (p=(int*)utarray_next(a,p))) printf("%d ", *p); printf("\n"); - printf("len: %u\n\n", utarray_len(a)); - - utarray_free(a); - return 0; -} - diff --git a/src/util/uthash/tests/test82.ans b/src/util/uthash/tests/test82.ans deleted file mode 100644 index ce8f5b5..0000000 --- a/src/util/uthash/tests/test82.ans +++ /dev/null @@ -1,9 +0,0 @@ -0 1 2 3 4 5 6 7 8 9 -len: 10 - -0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 len: 20 - -0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 len: 30 - -0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 0 1 2 3 4 5 6 7 8 9 5 6 7 8 9 len: 40 - diff --git a/src/util/uthash/tests/test82.c b/src/util/uthash/tests/test82.c deleted file mode 100644 index 8860554..0000000 --- a/src/util/uthash/tests/test82.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include "utarray.h" - -int main() { - UT_array *a,*b; - int i, *p; - utarray_new(a, &ut_int_icd); - utarray_new(b, &ut_int_icd); - - for(i=0;i<10;i++) utarray_push_back(a,&i); - for(p=(int*)utarray_front(a); p; p=(int*)utarray_next(a,p)) printf("%d ",*p); - printf("\n"); - printf("len: %u\n\n", utarray_len(a)); - - utarray_inserta(b,a,10); - for(p=(int*)utarray_front(b); p; p=(int*)utarray_next(b,p)) printf("%d ",*p); - printf("len: %u\n\n", utarray_len(b)); - - utarray_inserta(b,a,0); - for(p=(int*)utarray_front(b); p; p=(int*)utarray_next(b,p)) printf("%d ",*p); - printf("len: %u\n\n", utarray_len(b)); - - utarray_inserta(b,a,25); - for(p=(int*)utarray_front(b); p; p=(int*)utarray_next(b,p)) printf("%d ",*p); - printf("len: %u\n\n", utarray_len(b)); - - utarray_free(a); - utarray_free(b); - return 0; -} - diff --git a/src/util/uthash/tests/test9.ans b/src/util/uthash/tests/test9.ans deleted file mode 100644 index 13a9402..0000000 --- a/src/util/uthash/tests/test9.ans +++ /dev/null @@ -1,500 +0,0 @@ -user 0, cookie 0 -user 2, cookie 4 -user 4, cookie 16 -user 6, cookie 36 -user 8, cookie 64 -user 10, cookie 100 -user 12, cookie 144 -user 14, cookie 196 -user 16, cookie 256 -user 18, cookie 324 -user 20, cookie 400 -user 22, cookie 484 -user 24, cookie 576 -user 26, cookie 676 -user 28, cookie 784 -user 30, cookie 900 -user 32, cookie 1024 -user 34, cookie 1156 -user 36, cookie 1296 -user 38, cookie 1444 -user 40, cookie 1600 -user 42, cookie 1764 -user 44, cookie 1936 -user 46, cookie 2116 -user 48, cookie 2304 -user 50, cookie 2500 -user 52, cookie 2704 -user 54, cookie 2916 -user 56, cookie 3136 -user 58, cookie 3364 -user 60, cookie 3600 -user 62, cookie 3844 -user 64, cookie 4096 -user 66, cookie 4356 -user 68, cookie 4624 -user 70, cookie 4900 -user 72, cookie 5184 -user 74, cookie 5476 -user 76, cookie 5776 -user 78, cookie 6084 -user 80, cookie 6400 -user 82, cookie 6724 -user 84, cookie 7056 -user 86, cookie 7396 -user 88, cookie 7744 -user 90, cookie 8100 -user 92, cookie 8464 -user 94, cookie 8836 -user 96, cookie 9216 -user 98, cookie 9604 -user 100, cookie 10000 -user 102, cookie 10404 -user 104, cookie 10816 -user 106, cookie 11236 -user 108, cookie 11664 -user 110, cookie 12100 -user 112, cookie 12544 -user 114, cookie 12996 -user 116, cookie 13456 -user 118, cookie 13924 -user 120, cookie 14400 -user 122, cookie 14884 -user 124, cookie 15376 -user 126, cookie 15876 -user 128, cookie 16384 -user 130, cookie 16900 -user 132, cookie 17424 -user 134, cookie 17956 -user 136, cookie 18496 -user 138, cookie 19044 -user 140, cookie 19600 -user 142, cookie 20164 -user 144, cookie 20736 -user 146, cookie 21316 -user 148, cookie 21904 -user 150, cookie 22500 -user 152, cookie 23104 -user 154, cookie 23716 -user 156, cookie 24336 -user 158, cookie 24964 -user 160, cookie 25600 -user 162, cookie 26244 -user 164, cookie 26896 -user 166, cookie 27556 -user 168, cookie 28224 -user 170, cookie 28900 -user 172, cookie 29584 -user 174, cookie 30276 -user 176, cookie 30976 -user 178, cookie 31684 -user 180, cookie 32400 -user 182, cookie 33124 -user 184, cookie 33856 -user 186, cookie 34596 -user 188, cookie 35344 -user 190, cookie 36100 -user 192, cookie 36864 -user 194, cookie 37636 -user 196, cookie 38416 -user 198, cookie 39204 -user 200, cookie 40000 -user 202, cookie 40804 -user 204, cookie 41616 -user 206, cookie 42436 -user 208, cookie 43264 -user 210, cookie 44100 -user 212, cookie 44944 -user 214, cookie 45796 -user 216, cookie 46656 -user 218, cookie 47524 -user 220, cookie 48400 -user 222, cookie 49284 -user 224, cookie 50176 -user 226, cookie 51076 -user 228, cookie 51984 -user 230, cookie 52900 -user 232, cookie 53824 -user 234, cookie 54756 -user 236, cookie 55696 -user 238, cookie 56644 -user 240, cookie 57600 -user 242, cookie 58564 -user 244, cookie 59536 -user 246, cookie 60516 -user 248, cookie 61504 -user 250, cookie 62500 -user 252, cookie 63504 -user 254, cookie 64516 -user 256, cookie 65536 -user 258, cookie 66564 -user 260, cookie 67600 -user 262, cookie 68644 -user 264, cookie 69696 -user 266, cookie 70756 -user 268, cookie 71824 -user 270, cookie 72900 -user 272, cookie 73984 -user 274, cookie 75076 -user 276, cookie 76176 -user 278, cookie 77284 -user 280, cookie 78400 -user 282, cookie 79524 -user 284, cookie 80656 -user 286, cookie 81796 -user 288, cookie 82944 -user 290, cookie 84100 -user 292, cookie 85264 -user 294, cookie 86436 -user 296, cookie 87616 -user 298, cookie 88804 -user 300, cookie 90000 -user 302, cookie 91204 -user 304, cookie 92416 -user 306, cookie 93636 -user 308, cookie 94864 -user 310, cookie 96100 -user 312, cookie 97344 -user 314, cookie 98596 -user 316, cookie 99856 -user 318, cookie 101124 -user 320, cookie 102400 -user 322, cookie 103684 -user 324, cookie 104976 -user 326, cookie 106276 -user 328, cookie 107584 -user 330, cookie 108900 -user 332, cookie 110224 -user 334, cookie 111556 -user 336, cookie 112896 -user 338, cookie 114244 -user 340, cookie 115600 -user 342, cookie 116964 -user 344, cookie 118336 -user 346, cookie 119716 -user 348, cookie 121104 -user 350, cookie 122500 -user 352, cookie 123904 -user 354, cookie 125316 -user 356, cookie 126736 -user 358, cookie 128164 -user 360, cookie 129600 -user 362, cookie 131044 -user 364, cookie 132496 -user 366, cookie 133956 -user 368, cookie 135424 -user 370, cookie 136900 -user 372, cookie 138384 -user 374, cookie 139876 -user 376, cookie 141376 -user 378, cookie 142884 -user 380, cookie 144400 -user 382, cookie 145924 -user 384, cookie 147456 -user 386, cookie 148996 -user 388, cookie 150544 -user 390, cookie 152100 -user 392, cookie 153664 -user 394, cookie 155236 -user 396, cookie 156816 -user 398, cookie 158404 -user 400, cookie 160000 -user 402, cookie 161604 -user 404, cookie 163216 -user 406, cookie 164836 -user 408, cookie 166464 -user 410, cookie 168100 -user 412, cookie 169744 -user 414, cookie 171396 -user 416, cookie 173056 -user 418, cookie 174724 -user 420, cookie 176400 -user 422, cookie 178084 -user 424, cookie 179776 -user 426, cookie 181476 -user 428, cookie 183184 -user 430, cookie 184900 -user 432, cookie 186624 -user 434, cookie 188356 -user 436, cookie 190096 -user 438, cookie 191844 -user 440, cookie 193600 -user 442, cookie 195364 -user 444, cookie 197136 -user 446, cookie 198916 -user 448, cookie 200704 -user 450, cookie 202500 -user 452, cookie 204304 -user 454, cookie 206116 -user 456, cookie 207936 -user 458, cookie 209764 -user 460, cookie 211600 -user 462, cookie 213444 -user 464, cookie 215296 -user 466, cookie 217156 -user 468, cookie 219024 -user 470, cookie 220900 -user 472, cookie 222784 -user 474, cookie 224676 -user 476, cookie 226576 -user 478, cookie 228484 -user 480, cookie 230400 -user 482, cookie 232324 -user 484, cookie 234256 -user 486, cookie 236196 -user 488, cookie 238144 -user 490, cookie 240100 -user 492, cookie 242064 -user 494, cookie 244036 -user 496, cookie 246016 -user 498, cookie 248004 -user 500, cookie 250000 -user 502, cookie 252004 -user 504, cookie 254016 -user 506, cookie 256036 -user 508, cookie 258064 -user 510, cookie 260100 -user 512, cookie 262144 -user 514, cookie 264196 -user 516, cookie 266256 -user 518, cookie 268324 -user 520, cookie 270400 -user 522, cookie 272484 -user 524, cookie 274576 -user 526, cookie 276676 -user 528, cookie 278784 -user 530, cookie 280900 -user 532, cookie 283024 -user 534, cookie 285156 -user 536, cookie 287296 -user 538, cookie 289444 -user 540, cookie 291600 -user 542, cookie 293764 -user 544, cookie 295936 -user 546, cookie 298116 -user 548, cookie 300304 -user 550, cookie 302500 -user 552, cookie 304704 -user 554, cookie 306916 -user 556, cookie 309136 -user 558, cookie 311364 -user 560, cookie 313600 -user 562, cookie 315844 -user 564, cookie 318096 -user 566, cookie 320356 -user 568, cookie 322624 -user 570, cookie 324900 -user 572, cookie 327184 -user 574, cookie 329476 -user 576, cookie 331776 -user 578, cookie 334084 -user 580, cookie 336400 -user 582, cookie 338724 -user 584, cookie 341056 -user 586, cookie 343396 -user 588, cookie 345744 -user 590, cookie 348100 -user 592, cookie 350464 -user 594, cookie 352836 -user 596, cookie 355216 -user 598, cookie 357604 -user 600, cookie 360000 -user 602, cookie 362404 -user 604, cookie 364816 -user 606, cookie 367236 -user 608, cookie 369664 -user 610, cookie 372100 -user 612, cookie 374544 -user 614, cookie 376996 -user 616, cookie 379456 -user 618, cookie 381924 -user 620, cookie 384400 -user 622, cookie 386884 -user 624, cookie 389376 -user 626, cookie 391876 -user 628, cookie 394384 -user 630, cookie 396900 -user 632, cookie 399424 -user 634, cookie 401956 -user 636, cookie 404496 -user 638, cookie 407044 -user 640, cookie 409600 -user 642, cookie 412164 -user 644, cookie 414736 -user 646, cookie 417316 -user 648, cookie 419904 -user 650, cookie 422500 -user 652, cookie 425104 -user 654, cookie 427716 -user 656, cookie 430336 -user 658, cookie 432964 -user 660, cookie 435600 -user 662, cookie 438244 -user 664, cookie 440896 -user 666, cookie 443556 -user 668, cookie 446224 -user 670, cookie 448900 -user 672, cookie 451584 -user 674, cookie 454276 -user 676, cookie 456976 -user 678, cookie 459684 -user 680, cookie 462400 -user 682, cookie 465124 -user 684, cookie 467856 -user 686, cookie 470596 -user 688, cookie 473344 -user 690, cookie 476100 -user 692, cookie 478864 -user 694, cookie 481636 -user 696, cookie 484416 -user 698, cookie 487204 -user 700, cookie 490000 -user 702, cookie 492804 -user 704, cookie 495616 -user 706, cookie 498436 -user 708, cookie 501264 -user 710, cookie 504100 -user 712, cookie 506944 -user 714, cookie 509796 -user 716, cookie 512656 -user 718, cookie 515524 -user 720, cookie 518400 -user 722, cookie 521284 -user 724, cookie 524176 -user 726, cookie 527076 -user 728, cookie 529984 -user 730, cookie 532900 -user 732, cookie 535824 -user 734, cookie 538756 -user 736, cookie 541696 -user 738, cookie 544644 -user 740, cookie 547600 -user 742, cookie 550564 -user 744, cookie 553536 -user 746, cookie 556516 -user 748, cookie 559504 -user 750, cookie 562500 -user 752, cookie 565504 -user 754, cookie 568516 -user 756, cookie 571536 -user 758, cookie 574564 -user 760, cookie 577600 -user 762, cookie 580644 -user 764, cookie 583696 -user 766, cookie 586756 -user 768, cookie 589824 -user 770, cookie 592900 -user 772, cookie 595984 -user 774, cookie 599076 -user 776, cookie 602176 -user 778, cookie 605284 -user 780, cookie 608400 -user 782, cookie 611524 -user 784, cookie 614656 -user 786, cookie 617796 -user 788, cookie 620944 -user 790, cookie 624100 -user 792, cookie 627264 -user 794, cookie 630436 -user 796, cookie 633616 -user 798, cookie 636804 -user 800, cookie 640000 -user 802, cookie 643204 -user 804, cookie 646416 -user 806, cookie 649636 -user 808, cookie 652864 -user 810, cookie 656100 -user 812, cookie 659344 -user 814, cookie 662596 -user 816, cookie 665856 -user 818, cookie 669124 -user 820, cookie 672400 -user 822, cookie 675684 -user 824, cookie 678976 -user 826, cookie 682276 -user 828, cookie 685584 -user 830, cookie 688900 -user 832, cookie 692224 -user 834, cookie 695556 -user 836, cookie 698896 -user 838, cookie 702244 -user 840, cookie 705600 -user 842, cookie 708964 -user 844, cookie 712336 -user 846, cookie 715716 -user 848, cookie 719104 -user 850, cookie 722500 -user 852, cookie 725904 -user 854, cookie 729316 -user 856, cookie 732736 -user 858, cookie 736164 -user 860, cookie 739600 -user 862, cookie 743044 -user 864, cookie 746496 -user 866, cookie 749956 -user 868, cookie 753424 -user 870, cookie 756900 -user 872, cookie 760384 -user 874, cookie 763876 -user 876, cookie 767376 -user 878, cookie 770884 -user 880, cookie 774400 -user 882, cookie 777924 -user 884, cookie 781456 -user 886, cookie 784996 -user 888, cookie 788544 -user 890, cookie 792100 -user 892, cookie 795664 -user 894, cookie 799236 -user 896, cookie 802816 -user 898, cookie 806404 -user 900, cookie 810000 -user 902, cookie 813604 -user 904, cookie 817216 -user 906, cookie 820836 -user 908, cookie 824464 -user 910, cookie 828100 -user 912, cookie 831744 -user 914, cookie 835396 -user 916, cookie 839056 -user 918, cookie 842724 -user 920, cookie 846400 -user 922, cookie 850084 -user 924, cookie 853776 -user 926, cookie 857476 -user 928, cookie 861184 -user 930, cookie 864900 -user 932, cookie 868624 -user 934, cookie 872356 -user 936, cookie 876096 -user 938, cookie 879844 -user 940, cookie 883600 -user 942, cookie 887364 -user 944, cookie 891136 -user 946, cookie 894916 -user 948, cookie 898704 -user 950, cookie 902500 -user 952, cookie 906304 -user 954, cookie 910116 -user 956, cookie 913936 -user 958, cookie 917764 -user 960, cookie 921600 -user 962, cookie 925444 -user 964, cookie 929296 -user 966, cookie 933156 -user 968, cookie 937024 -user 970, cookie 940900 -user 972, cookie 944784 -user 974, cookie 948676 -user 976, cookie 952576 -user 978, cookie 956484 -user 980, cookie 960400 -user 982, cookie 964324 -user 984, cookie 968256 -user 986, cookie 972196 -user 988, cookie 976144 -user 990, cookie 980100 -user 992, cookie 984064 -user 994, cookie 988036 -user 996, cookie 992016 -user 998, cookie 996004 diff --git a/src/util/uthash/tests/test9.c b/src/util/uthash/tests/test9.c deleted file mode 100644 index a8a16dd..0000000 --- a/src/util/uthash/tests/test9.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "uthash.h" -#include /* malloc */ -#include /* printf */ - -typedef struct example_user_t { - int id; - int cookie; - UT_hash_handle hh; -} example_user_t; - -int main(int argc,char *argv[]) { - int i; - example_user_t *user, *tmp, *users=NULL; - - /* create elements */ - for(i=0;i<1000;i++) { - if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1); - user->id = i; - user->cookie = i*i; - HASH_ADD_INT(users,id,user); - } - - /* delete each ID */ - for(i=0;i<1000;i+=2) { - HASH_FIND_INT(users,&i,tmp); - if (tmp) { - printf("user %d, cookie %d\n", tmp->id, tmp->cookie); - } else printf("user id %d not found\n", i); - } - return 0; -} diff --git a/src/util/uthash/tests/threads/README b/src/util/uthash/tests/threads/README deleted file mode 100644 index e49a62e..0000000 --- a/src/util/uthash/tests/threads/README +++ /dev/null @@ -1,2 +0,0 @@ -test1: exercise a two-reader, one-writer, rwlock-protected hash. -test2: a template for a nthread, nloop kind of program diff --git a/src/util/uthash/tests/threads/do_tests b/src/util/uthash/tests/threads/do_tests deleted file mode 100755 index e6809a1..0000000 --- a/src/util/uthash/tests/threads/do_tests +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -my @tests; -for (glob "test*[0-9]") { - push @tests, $_ if -e "$_.ans"; -} - -my $num_failed=0; - -for my $test (@tests) { - `./$test > $test.out 2> $test.err`; - `diff $test.out $test.ans`; - print "$test failed\n" if $?; - $num_failed++ if $?; - unlink "$test.err" if -z "$test.err"; -} - -print scalar @tests . " tests conducted, $num_failed failed.\n"; -exit $num_failed; diff --git a/src/util/uthash/tests/threads/test1.c b/src/util/uthash/tests/threads/test1.c deleted file mode 100644 index 1045086..0000000 --- a/src/util/uthash/tests/threads/test1.c +++ /dev/null @@ -1,111 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "uthash.h" - -#undef uthash_noexpand_fyi -#define uthash_noexpand_fyi fprintf(stderr,"warning: bucket expansion inhibited\n"); - -#define LOOPS 100000 - -typedef struct { - int i; - UT_hash_handle hh; -} elt; - -elt *elts=NULL; /* this is our hash table which two threads will use */ -pthread_rwlock_t lock; - -void *thread_routine_r( void *arg ) { - int i; - long num_found=0; - elt *e; - - for(i=0;ii = i; - HASH_ADD_INT(elts, i, e); - } - pthread_rwlock_unlock(&lock); - } - return (void*)num_deld; -} - -int main() { - unsigned i; - long num_added=0; - int status; - pthread_t thread_r1,thread_r2,thread_w1,thread_w2; - void *thread_result; - elt tmp, *e; - - if (pthread_rwlock_init(&lock,NULL) != 0) { - fprintf(stderr,"lock init failed\n"); - exit(-1); - } - - if ( status = pthread_create( &thread_r1, NULL, thread_routine_r, NULL )) { - printf("failure: status %d\n", status); - exit(-1); - } - if ( status = pthread_create( &thread_r2, NULL, thread_routine_r, NULL )) { - printf("failure: status %d\n", status); - exit(-1); - } - if ( status = pthread_create( &thread_w1, NULL, thread_routine_w, NULL )) { - printf("failure: status %d\n", status); - exit(-1); - } - if ( status = pthread_create( &thread_w2, NULL, thread_routine_w, NULL )) { - printf("failure: status %d\n", status); - exit(-1); - } - - status = pthread_join( thread_r1, &thread_result ); - printf("thread result: %d %ld\n", status, (long)thread_result); - - status = pthread_join( thread_r2, &thread_result ); - printf("thread result: %d %ld\n", status, (long)thread_result); - - status = pthread_join( thread_w1, &thread_result ); - printf("thread result: %d %ld\n", status, (long)thread_result); - - status = pthread_join( thread_w2, &thread_result ); - printf("thread result: %d %ld\n", status, (long)thread_result); - - i = HASH_COUNT(elts); - printf("final count of items in hash: %u\n", i); -} diff --git a/src/util/uthash/tests/threads/test2.c b/src/util/uthash/tests/threads/test2.c deleted file mode 100644 index 20d984f..0000000 --- a/src/util/uthash/tests/threads/test2.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "uthash.h" - -#undef uthash_noexpand_fyi -#define uthash_noexpand_fyi fprintf(stderr,"warning: bucket expansion inhibited\n"); - -#define LOOPS 100000 -#define NTHREADS 2 - -typedef struct { - int i; - int v; - UT_hash_handle hh; -} elt; - -elt *elts=NULL; /* this is our hash table which two threads will use */ -pthread_rwlock_t lock; - -void *thread_routine( void *arg ) { - int keepgoing=0; - /* TODO write me */ - return NULL; -} - -int main() { - unsigned i; - long num_added=0; - int status; - pthread_t thread[NTHREADS]; - void *thread_result; - elt tmp, *e; - - if (pthread_rwlock_init(&lock,NULL) != 0) { - fprintf(stderr,"lock init failed\n"); - exit(-1); - } - - /* populate it to start */ - for(i=0; ii = i; - e->v = 0; - HASH_ADD_INT(elts, i, e); - } - - for(i=0; i