diff --git a/example/Makefile b/example/Makefile
index bc11336..e25089a 100644
--- a/example/Makefile
+++ b/example/Makefile
@@ -1,7 +1,7 @@
DUMPMACHINE := $(shell $(CC) -dumpmachine)
ifneq ($(SANITIZE_ADDRESS),1)
- XCFLAGS = -Ofast -DNDEBUG -s -static
+ XCFLAGS = -Ofast -flto -DNDEBUG -s -static
ifneq ($(firstword $(filter x86_64-%,$(DUMPMACHINE))),)
XCFLAGS += -march=x86-64 -mtune=nocona
else ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),)
@@ -25,7 +25,7 @@ BIN_PATH := bin
ALL_PATH := $(SRC_PATH) $(BIN_PATH)
BIN_FILE := $(BIN_PATH)/hashset-example$(EXE_SUFFIX)
-SRC_FILE := $(SRC_PATH)/main.c
+SRC_FILE := $(wildcard $(SRC_PATH)/*.c)
LIB_FILE := ../libhashset/lib/libhashset-1.a
.PHONY: all build clean
diff --git a/example/hashset-example.vcxproj b/example/hashset-example.vcxproj
index 9a03fa9..f44c56a 100644
--- a/example/hashset-example.vcxproj
+++ b/example/hashset-example.vcxproj
@@ -39,6 +39,7 @@
+
@@ -46,6 +47,9 @@
{8cf3bd19-28b1-435d-b719-e00b052dfc3a}
+
+
+
16.0
Win32Proj
diff --git a/example/hashset-example.vcxproj.filters b/example/hashset-example.vcxproj.filters
index 0b7f47e..274df3c 100644
--- a/example/hashset-example.vcxproj.filters
+++ b/example/hashset-example.vcxproj.filters
@@ -18,5 +18,13 @@
Source Files
+
+ Source Files
+
+
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/example/src/input.c b/example/src/input.c
new file mode 100644
index 0000000..8e38d14
--- /dev/null
+++ b/example/src/input.c
@@ -0,0 +1,50 @@
+/******************************************************************************/
+/* HashSet for C99, by LoRd_MuldeR */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+#include "input.h"
+
+#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0U]))
+
+/* ========================================================================= */
+/* I/O Functions */
+/* ========================================================================= */
+
+static const uint64_t INPUT_DATA[] =
+{
+ UINT64_C(0xEC7D0A721D57EC50), UINT64_C(0x2D6A7AB6BF627C22), UINT64_C(0x4FDD65C766A875B3), UINT64_C(0x820325C26E55AADE), UINT64_C(0xDAAA501D96EEF99B),
+ UINT64_C(0x8144E2BD50513672), UINT64_C(0x292CE22A29D5DB2B), UINT64_C(0xBC6CF8B2053A5334), UINT64_C(0x6D1401A1D373E7D1), UINT64_C(0x24ADEDD753FA66AE),
+ UINT64_C(0xC10245EBF7AA2022), UINT64_C(0x023529AB3C7CD028), UINT64_C(0x36D2B9AC4939E5B6), UINT64_C(0xC03EBAFFF82F66AA), UINT64_C(0xF192D661B62529F8),
+ UINT64_C(0xB704F3B5D339E013), UINT64_C(0xA9FF1DACC3E51172), UINT64_C(0x56B07D81D1075239), UINT64_C(0xB1871C613F7AABE2), UINT64_C(0xA8EF994549F8FE4A),
+ UINT64_C(0xA57BB923C5253144), UINT64_C(0x00D86833851697B3), UINT64_C(0xDA9E46FDD32DC65D), UINT64_C(0x7ACB9C0ADDDFAB93), UINT64_C(0xB5B5850E76C843DB),
+ UINT64_C(0x3B6A7C89C7E81A5D), UINT64_C(0x4EB1262597175FCD), UINT64_C(0xB6FBE2171D1D7EA0), UINT64_C(0x081137EA1D536FC4), UINT64_C(0xE0445CD0FAD5C7DD),
+ UINT64_C(0x893007682A3BF169), UINT64_C(0xD0C19098FBD42472), UINT64_C(0xEDB93F32F0A49B30), UINT64_C(0x2EA9A358058AB291), UINT64_C(0x8DAEDB071BA37583),
+ UINT64_C(0x7D82157789453793), UINT64_C(0xBB2773CA12083932), UINT64_C(0x6303F020DEFC11A9), UINT64_C(0xD41F0AD15E0189DC), UINT64_C(0x19B057F06E39C89E),
+ UINT64_C(0x4253F25E0B30719C), UINT64_C(0x09463D8E5BA23234), UINT64_C(0x34D04E31976724AA), UINT64_C(0x4671121B954F5A79), UINT64_C(0xE92C10C3DB5D8D1B),
+ UINT64_C(0xE9CBC62D55911AE7), UINT64_C(0x2A1AB1C994DB788E), UINT64_C(0xC8C33ECF2C582D77), UINT64_C(0x5FA82FE6C15B629E), UINT64_C(0x466CEED23C511177),
+ UINT64_C(0x036D0870BAE19AE1), UINT64_C(0x6606CC0204159016), UINT64_C(0xD6238C8747BC5852), UINT64_C(0x223E4185F09E378F), UINT64_C(0xA9B3F004F76E5444),
+ UINT64_C(0x23C9471F9E0284DD), UINT64_C(0x8B8FD1A11AA899F1), UINT64_C(0x0AB371E3FC9D3B56), UINT64_C(0xAC2E67112F3A040D), UINT64_C(0x192A053B04315830),
+ UINT64_C(0x432D3397538C1F92), UINT64_C(0xE959C8CB414D0179), UINT64_C(0x2CBAD874DD3E7ED3), UINT64_C(0x27C1B56C45A07443), UINT64_C(0x985DCE41B814DB32),
+ UINT64_C(0x7D89DA5C4F0A66B3), UINT64_C(0x8BDD31E4EBE03149), UINT64_C(0xDE099239E444C693), UINT64_C(0x1ADD95B03AF163A0), UINT64_C(0x36CD32A83DE833F2),
+ UINT64_C(0xDF4A8C3B1DC66B09), UINT64_C(0xC29C92C5A077B9FE), UINT64_C(0x56950ECB370CBC27), UINT64_C(0x7FEAD937FCA475F1), UINT64_C(0x1E4AD443AD9D41EC),
+ UINT64_C(0x9A265C879D7E5872), UINT64_C(0x455AB983F8BA1441), UINT64_C(0x027C2ED163D11C29), UINT64_C(0xA7A7D23CAA6F4DC6), UINT64_C(0xEE7939920BE1E7BC),
+ UINT64_C(0x2AE02B16E28F02F6), UINT64_C(0xFE8A0CB4EB33DA1B), UINT64_C(0x8CCBF16F006BE241), UINT64_C(0x3371EF26F2850DAF), UINT64_C(0xC35EA57F39EA9E58),
+ UINT64_C(0x20977AD263FB0272), UINT64_C(0x29BBDD2B8DFCD944), UINT64_C(0x3EF8BD07A2CA3369), UINT64_C(0x64FC3600F0B37716), UINT64_C(0x53CBD741D2433E51),
+ UINT64_C(0x69459841B5CEE1AB), UINT64_C(0x170B6EBB26B0102C), UINT64_C(0xAF7D361D649AED05), UINT64_C(0x8843B951E1A79CA4), UINT64_C(0xCC0B139063D3EF0A),
+ UINT64_C(0x85CB5DBD53986A64), UINT64_C(0x7C66F5CD3E46FDB7), UINT64_C(0xE863F4436E8BD7F8), UINT64_C(0x82496CD067153344), UINT64_C(0x863F1F732CE3751E),
+};
+
+int have_more_items(const size_t offset)
+{
+ return offset < ARRAY_SIZE(INPUT_DATA);
+}
+
+uint64_t get_next_item(const size_t offset)
+{
+ if (offset < ARRAY_SIZE(INPUT_DATA))
+ {
+ return INPUT_DATA[offset];
+ }
+ return 0U;
+}
diff --git a/example/src/input.h b/example/src/input.h
new file mode 100644
index 0000000..3457a47
--- /dev/null
+++ b/example/src/input.h
@@ -0,0 +1,15 @@
+/******************************************************************************/
+/* HashSet for C99, by LoRd_MuldeR */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+#ifndef _EXAMPLE_INPUT_INCLUDED
+#define _EXAMPLE_INPUT_INCLUDED
+
+#include
+#include
+
+int have_more_items(const size_t offset);
+uint64_t get_next_item(const size_t offset);
+
+#endif /*_EXAMPLE_INPUT_INCLUDED*/
diff --git a/example/src/main.c b/example/src/main.c
index 0920c9d..b9b4f85 100644
--- a/example/src/main.c
+++ b/example/src/main.c
@@ -6,50 +6,7 @@
#include
#include
#include
-
-#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0U]))
-
-/* ========================================================================= */
-/* I/O Functions */
-/* ========================================================================= */
-
-static const uint64_t INPUT_DATA[] =
-{
- UINT64_C(0xEC7D0A721D57EC50), UINT64_C(0x2D6A7AB6BF627C22), UINT64_C(0x4FDD65C766A875B3), UINT64_C(0x820325C26E55AADE), UINT64_C(0xDAAA501D96EEF99B),
- UINT64_C(0x8144E2BD50513672), UINT64_C(0x292CE22A29D5DB2B), UINT64_C(0xBC6CF8B2053A5334), UINT64_C(0x6D1401A1D373E7D1), UINT64_C(0x24ADEDD753FA66AE),
- UINT64_C(0xC10245EBF7AA2022), UINT64_C(0x023529AB3C7CD028), UINT64_C(0x36D2B9AC4939E5B6), UINT64_C(0xC03EBAFFF82F66AA), UINT64_C(0xF192D661B62529F8),
- UINT64_C(0xB704F3B5D339E013), UINT64_C(0xA9FF1DACC3E51172), UINT64_C(0x56B07D81D1075239), UINT64_C(0xB1871C613F7AABE2), UINT64_C(0xA8EF994549F8FE4A),
- UINT64_C(0xA57BB923C5253144), UINT64_C(0x00D86833851697B3), UINT64_C(0xDA9E46FDD32DC65D), UINT64_C(0x7ACB9C0ADDDFAB93), UINT64_C(0xB5B5850E76C843DB),
- UINT64_C(0x3B6A7C89C7E81A5D), UINT64_C(0x4EB1262597175FCD), UINT64_C(0xB6FBE2171D1D7EA0), UINT64_C(0x081137EA1D536FC4), UINT64_C(0xE0445CD0FAD5C7DD),
- UINT64_C(0x893007682A3BF169), UINT64_C(0xD0C19098FBD42472), UINT64_C(0xEDB93F32F0A49B30), UINT64_C(0x2EA9A358058AB291), UINT64_C(0x8DAEDB071BA37583),
- UINT64_C(0x7D82157789453793), UINT64_C(0xBB2773CA12083932), UINT64_C(0x6303F020DEFC11A9), UINT64_C(0xD41F0AD15E0189DC), UINT64_C(0x19B057F06E39C89E),
- UINT64_C(0x4253F25E0B30719C), UINT64_C(0x09463D8E5BA23234), UINT64_C(0x34D04E31976724AA), UINT64_C(0x4671121B954F5A79), UINT64_C(0xE92C10C3DB5D8D1B),
- UINT64_C(0xE9CBC62D55911AE7), UINT64_C(0x2A1AB1C994DB788E), UINT64_C(0xC8C33ECF2C582D77), UINT64_C(0x5FA82FE6C15B629E), UINT64_C(0x466CEED23C511177),
- UINT64_C(0x036D0870BAE19AE1), UINT64_C(0x6606CC0204159016), UINT64_C(0xD6238C8747BC5852), UINT64_C(0x223E4185F09E378F), UINT64_C(0xA9B3F004F76E5444),
- UINT64_C(0x23C9471F9E0284DD), UINT64_C(0x8B8FD1A11AA899F1), UINT64_C(0x0AB371E3FC9D3B56), UINT64_C(0xAC2E67112F3A040D), UINT64_C(0x192A053B04315830),
- UINT64_C(0x432D3397538C1F92), UINT64_C(0xE959C8CB414D0179), UINT64_C(0x2CBAD874DD3E7ED3), UINT64_C(0x27C1B56C45A07443), UINT64_C(0x985DCE41B814DB32),
- UINT64_C(0x7D89DA5C4F0A66B3), UINT64_C(0x8BDD31E4EBE03149), UINT64_C(0xDE099239E444C693), UINT64_C(0x1ADD95B03AF163A0), UINT64_C(0x36CD32A83DE833F2),
- UINT64_C(0xDF4A8C3B1DC66B09), UINT64_C(0xC29C92C5A077B9FE), UINT64_C(0x56950ECB370CBC27), UINT64_C(0x7FEAD937FCA475F1), UINT64_C(0x1E4AD443AD9D41EC),
- UINT64_C(0x9A265C879D7E5872), UINT64_C(0x455AB983F8BA1441), UINT64_C(0x027C2ED163D11C29), UINT64_C(0xA7A7D23CAA6F4DC6), UINT64_C(0xEE7939920BE1E7BC),
- UINT64_C(0x2AE02B16E28F02F6), UINT64_C(0xFE8A0CB4EB33DA1B), UINT64_C(0x8CCBF16F006BE241), UINT64_C(0x3371EF26F2850DAF), UINT64_C(0xC35EA57F39EA9E58),
- UINT64_C(0x20977AD263FB0272), UINT64_C(0x29BBDD2B8DFCD944), UINT64_C(0x3EF8BD07A2CA3369), UINT64_C(0x64FC3600F0B37716), UINT64_C(0x53CBD741D2433E51),
- UINT64_C(0x69459841B5CEE1AB), UINT64_C(0x170B6EBB26B0102C), UINT64_C(0xAF7D361D649AED05), UINT64_C(0x8843B951E1A79CA4), UINT64_C(0xCC0B139063D3EF0A),
- UINT64_C(0x85CB5DBD53986A64), UINT64_C(0x7C66F5CD3E46FDB7), UINT64_C(0xE863F4436E8BD7F8), UINT64_C(0x82496CD067153344), UINT64_C(0x863F1F732CE3751E),
-};
-
-static int have_more_items(const size_t offset)
-{
- return offset < ARRAY_SIZE(INPUT_DATA);
-}
-
-static uint64_t get_next_item(const size_t offset)
-{
- if (offset < ARRAY_SIZE(INPUT_DATA))
- {
- return INPUT_DATA[offset];
- }
- return 0U;
-}
+#include "input.h"
/* ========================================================================= */
/* MAIN */
diff --git a/libhashset/Makefile b/libhashset/Makefile
index 23d2b5a..256ed4a 100644
--- a/libhashset/Makefile
+++ b/libhashset/Makefile
@@ -1,7 +1,7 @@
DUMPMACHINE := $(shell $(CC) -dumpmachine)
ifneq ($(SANITIZE_ADDRESS),1)
- XCFLAGS = -Ofast -DNDEBUG
+ XCFLAGS = -Ofast -flto -DNDEBUG
ifneq ($(firstword $(filter x86_64-%,$(DUMPMACHINE))),)
XCFLAGS += -march=x86-64 -mtune=nocona
else ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),)
diff --git a/test/Makefile b/test/Makefile
index 82dc065..53680b3 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,7 +1,7 @@
DUMPMACHINE := $(shell $(CC) -dumpmachine)
ifneq ($(SANITIZE_ADDRESS),1)
- XCFLAGS = -Ofast -DNDEBUG -s -static
+ XCFLAGS = -Ofast -flto -DNDEBUG -s -static
ifneq ($(firstword $(filter x86_64-%,$(DUMPMACHINE))),)
XCFLAGS += -march=x86-64 -mtune=nocona
else ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),)
@@ -25,7 +25,7 @@ BIN_PATH := bin
ALL_PATH := $(SRC_PATH) $(BIN_PATH)
BIN_FILE := $(BIN_PATH)/hashset-test$(EXE_SUFFIX)
-SRC_FILE := $(SRC_PATH)/main.c
+SRC_FILE := $(wildcard $(SRC_PATH)/*.c)
LIB_FILE := ../libhashset/lib/libhashset-1.a
.PHONY: all build clean
diff --git a/test/hashset-test.vcxproj b/test/hashset-test.vcxproj
index 0867a52..90c1596 100644
--- a/test/hashset-test.vcxproj
+++ b/test/hashset-test.vcxproj
@@ -40,12 +40,18 @@
+
+
{8cf3bd19-28b1-435d-b719-e00b052dfc3a}
+
+
+
+
16.0
Win32Proj
diff --git a/test/hashset-test.vcxproj.filters b/test/hashset-test.vcxproj.filters
index 0b7f47e..100d11c 100644
--- a/test/hashset-test.vcxproj.filters
+++ b/test/hashset-test.vcxproj.filters
@@ -18,5 +18,19 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/test/src/main.c b/test/src/main.c
index d558356..eb7754a 100644
--- a/test/src/main.c
+++ b/test/src/main.c
@@ -3,457 +3,19 @@
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
-#include
-
+#include "tests.h"
#include
#include
-#include
-#include
-#include
-#ifndef _WIN32
-# include
-#endif
-
-#if defined(__GNUC__)
-# define INLINE __inline__
-#elif defined(_MSC_VER)
-# define INLINE __inline
-#else
-# define INLINE
-#endif
-
-/* ========================================================================= */
-/* Utilities */
-/* ========================================================================= */
-
-#define INVERT(X) do { (X) = (!(X)); } while(0)
-
-#define UNUSED(X) ((void)X)
-
-#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0U]))
-
-#ifdef _WIN32
-#define RtlGenRandom SystemFunction036
-#define getentropy(X,Y) (RtlGenRandom((X),(uint32_t)(Y)) ? 0 : (-1))
-unsigned char __stdcall RtlGenRandom(void *buffer, uint32_t length);
-#endif
-
-typedef struct
-{
- size_t offset;
- uint64_t buffer[16U];
-}
-random_t;
-
-static INLINE void random_init(random_t *const rnd)
-{
- memset(rnd, 0, sizeof(random_t));
- rnd->offset = SIZE_MAX;
-}
-
-static INLINE uint64_t random_next(random_t *const rnd)
-{
- if (rnd->offset >= ARRAY_SIZE(rnd->buffer))
- {
- rnd->offset = 0U;
- if (getentropy(rnd->buffer, sizeof(rnd->buffer)) < 0)
- {
- abort();
- }
- }
-
- return rnd->buffer[rnd->offset++];
-}
-
-#define PRINT_SET_INFO(X) do \
-{\
- if (!hash_set_info64(hash_set, &capacity, &valid, &deleted, &limit)) \
+#define RUN_TEST_CASE(X) do \
+{ \
+ if (test_function_##X(hash_set) != EXIT_SUCCESS) \
{ \
- fprintf(stdout, "[#%d] capacity: %010zu, valid: %010zu, deleted: %010zu, limit: %010zu\n", (X), capacity, valid, deleted, limit); \
- fflush(stdout); \
+ goto failure; \
} \
} \
while(0)
-/* ========================================================================= */
-/* TEST #1 */
-/* ========================================================================= */
-
-#define MAXIMUM 425984U
-
-static int dump_callback(const size_t index, const char status, const uint64_t value)
-{
-#ifndef NDEBUG
- printf("%016zX: %c -> %016" PRIX64 "\n", index, status, value);
-#else
- UNUSED(index); UNUSED(status); UNUSED(value);
-#endif
- return 1;
-}
-
-static int test_function_1(hash_set64_t *const hash_set)
-{
- size_t r, capacity, valid, deleted, limit;
- uint64_t i;
- uint8_t spinner = 0U;
-
- for (r = 0U; r < 5U; ++r)
- {
- for (i = 0; i < MAXIMUM; ++i)
- {
- if ((i != 3167U) && (i != 9887U) && (i != 185903U) && (i != 387083U))
- {
- const errno_t error = hash_set_insert64(hash_set, i);
- if (error)
- {
- printf("Insert operation has failed! (error: %d)\n", error);
- return EXIT_FAILURE;
- }
- }
- if (!(++spinner & 0x0F))
- {
- PRINT_SET_INFO(1);
- }
- }
-
- if (hash_set_size64(hash_set) != MAXIMUM - 4U)
- {
- puts("Invalid size!");
- return EXIT_FAILURE;
- }
-
- for (i = 0; i < MAXIMUM; ++i)
- {
- if ((i != 3167U) && (i != 9887U) && (i != 387083U))
- {
- const errno_t error = hash_set_insert64(hash_set, i);
- if (error != ((i != 185903U) ? EEXIST : 0))
- {
- printf("Insert operation has failed! (error: %d)\n", error);
- return EXIT_FAILURE;
- }
- }
- }
-
- if (hash_set_size64(hash_set) != MAXIMUM - 3U)
- {
- puts("Invalid size!");
- return EXIT_FAILURE;
- }
-
- for (i = 0; i < MAXIMUM; ++i)
- {
- const errno_t error = hash_set_contains64(hash_set, i);
- if (error != ((i != 3167U) && (i != 9887U) && (i != 387083U)) ? 0 : ENOENT)
- {
- printf("Contains operation has failed! (error: %d)\n", error);
- return EXIT_FAILURE;
- }
- }
-
- if (hash_set_dump64(hash_set, dump_callback))
- {
- puts("Dump operation has failed!");
- return EXIT_FAILURE;
- }
-
- for (i = 0; i < MAXIMUM; ++i)
- {
- if ((i != 3167U) && (i != 9887U) && (i != 216263U) && (i != 387083U))
- {
- const errno_t error = hash_set_remove64(hash_set, i);
- if (error)
- {
- printf("Remove operation has failed! (error: %d)\n", error);
- return EXIT_FAILURE;
- }
- }
- if (!(++spinner & 0x0F))
- {
- PRINT_SET_INFO(1);
- }
- }
-
- if (hash_set_size64(hash_set) != 1U)
- {
- puts("Invalid size!");
- return EXIT_FAILURE;
- }
-
- for (i = 0; i < MAXIMUM; ++i)
- {
- const errno_t error = hash_set_contains64(hash_set, i);
- if (error != ((i != 216263U) ? ENOENT : 0))
- {
- printf("Contains operation has failed! (error: %d)\n", error);
- return EXIT_FAILURE;
- }
- }
-
- if (!hash_set_remove64(hash_set, 9887U))
- {
- puts("Final remove operation has failed!");
- return EXIT_FAILURE;
- }
-
- if (hash_set_remove64(hash_set, 216263U))
- {
- puts("Final remove operation has failed!");
- return EXIT_FAILURE;
- }
-
- if (hash_set_size64(hash_set) != 0U)
- {
- puts("Invalid size!");
- return EXIT_FAILURE;
- }
-
- PRINT_SET_INFO(1);
- puts("---------");
- }
-
- return EXIT_SUCCESS;
-}
-
-/* ========================================================================= */
-/* TEST #2 */
-/* ========================================================================= */
-
-#define TEST_SIZE 499979U
-
-static int test_function_2(hash_set64_t *const hash_set)
-{
- size_t r, j, capacity, valid, deleted, limit;
- uint64_t value;
- uint8_t spinner = 0U, *test1, *test2;
- uintptr_t cursor;
-
- random_t random;
- random_init(&random);
-
- test1 = (uint8_t*) malloc(TEST_SIZE * sizeof(uint8_t));
- if (!test1)
- {
- abort(); /*malloc has failed!*/
- }
-
- test2 = (uint8_t*) malloc(TEST_SIZE * sizeof(uint8_t));
- if (!test2)
- {
- abort(); /*malloc has failed!*/
- }
-
- for (r = 0U; r < 64U; ++r)
- {
- memset(test1, 0, TEST_SIZE * sizeof(uint8_t));
- memset(test2, 0, TEST_SIZE * sizeof(uint8_t));
-
- for (j = 0U; j < TEST_SIZE / 3U; ++j)
- {
- size_t rnd;
- do
- {
- rnd = random_next(&random) % TEST_SIZE;
- }
- while (test1[rnd]);
- INVERT(test1[rnd]);
- }
-
- for (j = 0U; j < TEST_SIZE; ++j)
- {
- if (test1[j])
- {
- const errno_t error = hash_set_insert64(hash_set, j);
- if (error)
- {
- printf("Insert operation has failed! (error: %d)\n", error);
- return EXIT_FAILURE;
- }
- if (!(++spinner & 0x0F))
- {
- PRINT_SET_INFO(2);
- }
- }
- }
-
- cursor = 0U;
- while (!hash_set_iterate64(hash_set, &cursor, &value))
- {
- if ((!test1[value]) || test2[value])
- {
- puts("Iteration error has been detected!");
- return EXIT_FAILURE;
- }
- INVERT(test2[value]);
- }
-
- for (j = 0U; j < TEST_SIZE; ++j)
- {
- if (test1[j] != test2[j])
- {
- puts("Iteration error has been detected!");
- return EXIT_FAILURE;
- }
- }
-
- for (j = 0U; j < TEST_SIZE; ++j)
- {
- if (test1[j])
- {
- const errno_t error = hash_set_remove64(hash_set, j);
- if (error)
- {
- printf("Remove operation has failed! (error: %d)\n", error);
- return EXIT_FAILURE;
- }
- if (!(++spinner & 0x0F))
- {
- PRINT_SET_INFO(2);
- }
- }
- }
-
- if (hash_set_size64(hash_set) != 0U)
- {
- puts("Invalid size!");
- return EXIT_FAILURE;
- }
- }
-
- free(test1);
- free(test2);
-
- PRINT_SET_INFO(2);
- puts("---------");
-
- return EXIT_SUCCESS;
-}
-
-/* ========================================================================= */
-/* TEST #3 */
-/* ========================================================================= */
-
-static int test_function_3(hash_set64_t *const hash_set)
-{
- size_t r, capacity, valid, deleted, limit;
- uint8_t spinner = 0U;
- clock_t last_update = clock();
-
- random_t random;
- random_init(&random);
-
- for (r = 0U; r < 3U; ++r)
- {
- for (;;)
- {
- const uint64_t rnd = random_next(&random) & UINT64_C(0x3FFFFFFFFFFFFFF);
- const errno_t error = hash_set_insert64(hash_set, rnd);
- if (error)
- {
- if (error != EEXIST)
- {
- printf("Insert operation has failed! (error: %d)\n", error);
- return EXIT_FAILURE;
- }
- else
- {
- PRINT_SET_INFO(3);
- printf("Collision detected! [%016" PRIx64 "]\n", rnd);
- break;
- }
- }
- if (!(++spinner & 0x7F))
- {
- const clock_t clock_now = clock();
- if ((clock_now < last_update) || (clock_now >= last_update + CLOCKS_PER_SEC))
- {
- PRINT_SET_INFO(3);
- last_update = clock_now;
- }
- }
- }
-
- PRINT_SET_INFO(3);
-
- if (hash_set_clear64(hash_set))
- {
- puts("Clear operation has failed!");
- return EXIT_FAILURE;
- }
- }
-
- PRINT_SET_INFO(3);
- puts("---------");
-
- return EXIT_SUCCESS;
-}
-
-/* ========================================================================= */
-/* TEST #4 */
-/* ========================================================================= */
-
-#define LIMIT (((uint64_t)UINT32_MAX) >> 2)
-
-static int test_function_4(hash_set64_t *const hash_set)
-{
- size_t capacity, valid, deleted, limit;
- uint64_t value;
- uint8_t spinner = 0U;
- clock_t last_update = clock();
-
- for (value = 0U; value < LIMIT; ++value)
- {
- const errno_t error = hash_set_insert64(hash_set, value);
- if (error)
- {
- PRINT_SET_INFO(4);
- printf("Insert operation has failed! (error: %d)\n", error);
- return EXIT_FAILURE;
- }
- if (!(++spinner & 0x7F))
- {
- const clock_t clock_now = clock();
- if ((clock_now < last_update) || (clock_now >= last_update + CLOCKS_PER_SEC))
- {
- PRINT_SET_INFO(4);
- last_update = clock_now;
- }
- }
- }
-
- for (value = 0U; value < LIMIT; ++value)
- {
- const errno_t error = hash_set_remove64(hash_set, value);
- if (error)
- {
- PRINT_SET_INFO(4);
- printf("Remove operation has failed! (error: %d)\n", error);
- return EXIT_FAILURE;
- }
- if (!(++spinner & 0x7F))
- {
- const clock_t clock_now = clock();
- if ((clock_now < last_update) || (clock_now >= last_update + CLOCKS_PER_SEC))
- {
- PRINT_SET_INFO(4);
- last_update = clock_now;
- }
- }
- }
-
- if (hash_set_size64(hash_set) != 0U)
- {
- puts("Invalid size!");
- return EXIT_FAILURE;
- }
-
- PRINT_SET_INFO(4);
- puts("---------");
-
- return EXIT_SUCCESS;
-}
-
/* ========================================================================= */
/* MAIN */
/* ========================================================================= */
@@ -472,32 +34,17 @@ int main(void)
return EXIT_FAILURE;
}
- if (test_function_1(hash_set) != EXIT_SUCCESS)
- {
- goto failure;
- }
-
- if (test_function_2(hash_set) != EXIT_SUCCESS)
- {
- goto failure;
- }
-
- if (test_function_3(hash_set) != EXIT_SUCCESS)
- {
- goto failure;
- }
-
- if (test_function_4(hash_set) != EXIT_SUCCESS)
- {
- goto failure;
- }
+ RUN_TEST_CASE(1);
+ RUN_TEST_CASE(2);
+ RUN_TEST_CASE(3);
+ RUN_TEST_CASE(4);
hash_set_destroy64(hash_set);
- puts("Test completed successfully.");
+ puts("Tests completed successfully.");
return EXIT_SUCCESS;
failure:
hash_set_destroy64(hash_set);
- puts("Something went wrong !!!");
+ puts("\nSomething went wrong !!!");
return EXIT_FAILURE;
}
diff --git a/test/src/random.c b/test/src/random.c
new file mode 100644
index 0000000..bd13c50
--- /dev/null
+++ b/test/src/random.c
@@ -0,0 +1,39 @@
+/******************************************************************************/
+/* HashSet for C99, by LoRd_MuldeR */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+#include "random.h"
+#include
+
+#ifndef _WIN32
+# include
+#endif
+
+#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0U]))
+
+#ifdef _WIN32
+#define RtlGenRandom SystemFunction036
+#define getentropy(X,Y) (RtlGenRandom((X),(uint32_t)(Y)) ? 0 : (-1))
+unsigned char __stdcall RtlGenRandom(void* buffer, uint32_t length);
+#endif
+
+void random_init(random_t *const rnd)
+{
+ memset(rnd, 0, sizeof(random_t));
+ rnd->offset = SIZE_MAX;
+}
+
+uint64_t random_next(random_t *const rnd)
+{
+ if (rnd->offset >= ARRAY_SIZE(rnd->buffer))
+ {
+ rnd->offset = 0U;
+ if (getentropy(rnd->buffer, sizeof(rnd->buffer)) < 0)
+ {
+ abort();
+ }
+ }
+
+ return rnd->buffer[rnd->offset++];
+}
diff --git a/test/src/random.h b/test/src/random.h
new file mode 100644
index 0000000..f7b698b
--- /dev/null
+++ b/test/src/random.h
@@ -0,0 +1,22 @@
+/******************************************************************************/
+/* HashSet for C99, by LoRd_MuldeR */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+#ifndef _TEST_RANDOM_INCLUDED
+#define _TEST_RANDOM_INCLUDED
+
+#include
+#include
+
+typedef struct
+{
+ size_t offset;
+ uint64_t buffer[16U];
+}
+random_t;
+
+void random_init(random_t *const rnd);
+uint64_t random_next(random_t *const rnd);
+
+#endif /*_TEST_RANDOM_INCLUDED*/
diff --git a/test/src/tests.c b/test/src/tests.c
new file mode 100644
index 0000000..1e0adbf
--- /dev/null
+++ b/test/src/tests.c
@@ -0,0 +1,411 @@
+/******************************************************************************/
+/* HashSet for C99, by LoRd_MuldeR */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+#include "tests.h"
+#include "random.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#define TEST_COUNT 4
+
+/* ========================================================================= */
+/* Utilities */
+/* ========================================================================= */
+
+#define UNUSED(X) ((void)X)
+
+#define INVERT(X) do { (X) = (!(X)); } while(0)
+
+#define PRINT_SET_INFO(X) do \
+{\
+ if (!hash_set_info64(hash_set, &capacity, &valid, &deleted, &limit)) \
+ { \
+ fprintf(stdout, "[Test %d/%d] capacity: %010zu, valid: %010zu, deleted: %010zu, limit: %010zu\n", (X), TEST_COUNT, capacity, valid, deleted, limit); \
+ fflush(stdout); \
+ } \
+} \
+while(0)
+
+/* ========================================================================= */
+/* TEST #1 */
+/* ========================================================================= */
+
+#define MAXIMUM 425984U
+
+static int dump_callback(const size_t index, const char status, const uint64_t value)
+{
+#ifndef NDEBUG
+ printf("%016zX: %c -> %016" PRIX64 "\n", index, status, value);
+#else
+ UNUSED(index); UNUSED(status); UNUSED(value);
+#endif
+ return 1;
+}
+
+int test_function_1(hash_set64_t *const hash_set)
+{
+ size_t r, capacity, valid, deleted, limit;
+ uint64_t i;
+ uint8_t spinner = 0U;
+
+ for (r = 0U; r < 5U; ++r)
+ {
+ for (i = 0; i < MAXIMUM; ++i)
+ {
+ if ((i != 3167U) && (i != 9887U) && (i != 185903U) && (i != 387083U))
+ {
+ const errno_t error = hash_set_insert64(hash_set, i);
+ if (error)
+ {
+ printf("Insert operation has failed! (error: %d)\n", error);
+ return EXIT_FAILURE;
+ }
+ }
+ if (!(++spinner & 0x0F))
+ {
+ PRINT_SET_INFO(1);
+ }
+ }
+
+ if (hash_set_size64(hash_set) != MAXIMUM - 4U)
+ {
+ puts("Invalid size!");
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; i < MAXIMUM; ++i)
+ {
+ if ((i != 3167U) && (i != 9887U) && (i != 387083U))
+ {
+ const errno_t error = hash_set_insert64(hash_set, i);
+ if (error != ((i != 185903U) ? EEXIST : 0))
+ {
+ printf("Insert operation has failed! (error: %d)\n", error);
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ if (hash_set_size64(hash_set) != MAXIMUM - 3U)
+ {
+ puts("Invalid size!");
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; i < MAXIMUM; ++i)
+ {
+ const errno_t error = hash_set_contains64(hash_set, i);
+ if (error != ((i != 3167U) && (i != 9887U) && (i != 387083U)) ? 0 : ENOENT)
+ {
+ printf("Contains operation has failed! (error: %d)\n", error);
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (hash_set_dump64(hash_set, dump_callback))
+ {
+ puts("Dump operation has failed!");
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; i < MAXIMUM; ++i)
+ {
+ if ((i != 3167U) && (i != 9887U) && (i != 216263U) && (i != 387083U))
+ {
+ const errno_t error = hash_set_remove64(hash_set, i);
+ if (error)
+ {
+ printf("Remove operation has failed! (error: %d)\n", error);
+ return EXIT_FAILURE;
+ }
+ }
+ if (!(++spinner & 0x0F))
+ {
+ PRINT_SET_INFO(1);
+ }
+ }
+
+ if (hash_set_size64(hash_set) != 1U)
+ {
+ puts("Invalid size!");
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; i < MAXIMUM; ++i)
+ {
+ const errno_t error = hash_set_contains64(hash_set, i);
+ if (error != ((i != 216263U) ? ENOENT : 0))
+ {
+ printf("Contains operation has failed! (error: %d)\n", error);
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (!hash_set_remove64(hash_set, 9887U))
+ {
+ puts("Final remove operation has failed!");
+ return EXIT_FAILURE;
+ }
+
+ if (hash_set_remove64(hash_set, 216263U))
+ {
+ puts("Final remove operation has failed!");
+ return EXIT_FAILURE;
+ }
+
+ if (hash_set_size64(hash_set) != 0U)
+ {
+ puts("Invalid size!");
+ return EXIT_FAILURE;
+ }
+
+ PRINT_SET_INFO(1);
+ puts("---------");
+ }
+
+ return EXIT_SUCCESS;
+}
+
+/* ========================================================================= */
+/* TEST #2 */
+/* ========================================================================= */
+
+#define TEST_SIZE 499979U
+
+int test_function_2(hash_set64_t *const hash_set)
+{
+ size_t r, j, capacity, valid, deleted, limit;
+ uint64_t value;
+ uint8_t spinner = 0U, *test1, *test2;
+ uintptr_t cursor;
+
+ random_t random;
+ random_init(&random);
+
+ test1 = (uint8_t*) malloc(TEST_SIZE * sizeof(uint8_t));
+ if (!test1)
+ {
+ abort(); /*malloc has failed!*/
+ }
+
+ test2 = (uint8_t*) malloc(TEST_SIZE * sizeof(uint8_t));
+ if (!test2)
+ {
+ abort(); /*malloc has failed!*/
+ }
+
+ for (r = 0U; r < 64U; ++r)
+ {
+ memset(test1, 0, TEST_SIZE * sizeof(uint8_t));
+ memset(test2, 0, TEST_SIZE * sizeof(uint8_t));
+
+ for (j = 0U; j < TEST_SIZE / 3U; ++j)
+ {
+ size_t rnd;
+ do
+ {
+ rnd = random_next(&random) % TEST_SIZE;
+ }
+ while (test1[rnd]);
+ INVERT(test1[rnd]);
+ }
+
+ for (j = 0U; j < TEST_SIZE; ++j)
+ {
+ if (test1[j])
+ {
+ const errno_t error = hash_set_insert64(hash_set, j);
+ if (error)
+ {
+ printf("Insert operation has failed! (error: %d)\n", error);
+ return EXIT_FAILURE;
+ }
+ if (!(++spinner & 0x0F))
+ {
+ PRINT_SET_INFO(2);
+ }
+ }
+ }
+
+ cursor = 0U;
+ while (!hash_set_iterate64(hash_set, &cursor, &value))
+ {
+ if ((!test1[value]) || test2[value])
+ {
+ puts("Iteration error has been detected!");
+ return EXIT_FAILURE;
+ }
+ INVERT(test2[value]);
+ }
+
+ for (j = 0U; j < TEST_SIZE; ++j)
+ {
+ if (test1[j] != test2[j])
+ {
+ puts("Iteration error has been detected!");
+ return EXIT_FAILURE;
+ }
+ }
+
+ for (j = 0U; j < TEST_SIZE; ++j)
+ {
+ if (test1[j])
+ {
+ const errno_t error = hash_set_remove64(hash_set, j);
+ if (error)
+ {
+ printf("Remove operation has failed! (error: %d)\n", error);
+ return EXIT_FAILURE;
+ }
+ if (!(++spinner & 0x0F))
+ {
+ PRINT_SET_INFO(2);
+ }
+ }
+ }
+
+ if (hash_set_size64(hash_set) != 0U)
+ {
+ puts("Invalid size!");
+ return EXIT_FAILURE;
+ }
+ }
+
+ free(test1);
+ free(test2);
+
+ PRINT_SET_INFO(2);
+ puts("---------");
+
+ return EXIT_SUCCESS;
+}
+
+/* ========================================================================= */
+/* TEST #3 */
+/* ========================================================================= */
+
+int test_function_3(hash_set64_t *const hash_set)
+{
+ size_t r, capacity, valid, deleted, limit;
+ uint8_t spinner = 0U;
+ clock_t last_update = clock();
+
+ random_t random;
+ random_init(&random);
+
+ for (r = 0U; r < 3U; ++r)
+ {
+ for (;;)
+ {
+ const uint64_t rnd = random_next(&random) & UINT64_C(0x3FFFFFFFFFFFFFF);
+ const errno_t error = hash_set_insert64(hash_set, rnd);
+ if (error)
+ {
+ if (error != EEXIST)
+ {
+ printf("Insert operation has failed! (error: %d)\n", error);
+ return EXIT_FAILURE;
+ }
+ else
+ {
+ PRINT_SET_INFO(3);
+ printf("Collision detected! [%016" PRIx64 "]\n", rnd);
+ break;
+ }
+ }
+ if (!(++spinner & 0x7F))
+ {
+ const clock_t clock_now = clock();
+ if ((clock_now < last_update) || (clock_now >= last_update + CLOCKS_PER_SEC))
+ {
+ PRINT_SET_INFO(3);
+ last_update = clock_now;
+ }
+ }
+ }
+
+ PRINT_SET_INFO(3);
+
+ if (hash_set_clear64(hash_set))
+ {
+ puts("Clear operation has failed!");
+ return EXIT_FAILURE;
+ }
+ }
+
+ PRINT_SET_INFO(3);
+ puts("---------");
+
+ return EXIT_SUCCESS;
+}
+
+/* ========================================================================= */
+/* TEST #4 */
+/* ========================================================================= */
+
+#define LIMIT (((uint64_t)UINT32_MAX) >> 2)
+
+int test_function_4(hash_set64_t *const hash_set)
+{
+ size_t capacity, valid, deleted, limit;
+ uint64_t value;
+ uint8_t spinner = 0U;
+ clock_t last_update = clock();
+
+ for (value = 0U; value < LIMIT; ++value)
+ {
+ const errno_t error = hash_set_insert64(hash_set, value);
+ if (error)
+ {
+ PRINT_SET_INFO(4);
+ printf("Insert operation has failed! (error: %d)\n", error);
+ return EXIT_FAILURE;
+ }
+ if (!(++spinner & 0x7F))
+ {
+ const clock_t clock_now = clock();
+ if ((clock_now < last_update) || (clock_now >= last_update + CLOCKS_PER_SEC))
+ {
+ PRINT_SET_INFO(4);
+ last_update = clock_now;
+ }
+ }
+ }
+
+ for (value = 0U; value < LIMIT; ++value)
+ {
+ const errno_t error = hash_set_remove64(hash_set, value);
+ if (error)
+ {
+ PRINT_SET_INFO(4);
+ printf("Remove operation has failed! (error: %d)\n", error);
+ return EXIT_FAILURE;
+ }
+ if (!(++spinner & 0x7F))
+ {
+ const clock_t clock_now = clock();
+ if ((clock_now < last_update) || (clock_now >= last_update + CLOCKS_PER_SEC))
+ {
+ PRINT_SET_INFO(4);
+ last_update = clock_now;
+ }
+ }
+ }
+
+ if (hash_set_size64(hash_set) != 0U)
+ {
+ puts("Invalid size!");
+ return EXIT_FAILURE;
+ }
+
+ PRINT_SET_INFO(4);
+ puts("---------");
+
+ return EXIT_SUCCESS;
+}
diff --git a/test/src/tests.h b/test/src/tests.h
new file mode 100644
index 0000000..9d6d7f7
--- /dev/null
+++ b/test/src/tests.h
@@ -0,0 +1,16 @@
+/******************************************************************************/
+/* HashSet for C99, by LoRd_MuldeR */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+#ifndef _TEST_TESTS_INCLUDED
+#define _TEST_TESTS_INCLUDED
+
+#include
+
+int test_function_1(hash_set64_t *const hash_set);
+int test_function_2(hash_set64_t *const hash_set);
+int test_function_3(hash_set64_t *const hash_set);
+int test_function_4(hash_set64_t *const hash_set);
+
+#endif /*_TEST_TESTS_INCLUDED*/