diff --git a/example/Makefile b/example/Makefile index 15b031a..4f44c6a 100644 --- a/example/Makefile +++ b/example/Makefile @@ -1,52 +1,16 @@ -DUMPMACHINE := $(shell $(CC) -dumpmachine) +SUBDIRS := hash-set -ifneq ($(DEBUG),) - XCFLAGS = -Og -g -else -ifneq ($(ASAN),) - XCFLAGS = -O1 -g -fsanitize=address -fno-omit-frame-pointer -static-libasan -else - XCFLAGS = -Ofast -DNDEBUG -ifneq ($(firstword $(filter x86_64-%,$(DUMPMACHINE))),) - XCFLAGS += -march=x86-64 -mtune=nocona -else ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),) - XCFLAGS += -march=pentiumpro -mtune=intel -endif -ifneq ($(FLTO),) - XCFLAGS += -flto -endif - XCFLAGS += -s -static -endif -endif +BUILD_ALL := $(patsubst %,build\:%,$(SUBDIRS)) +CLEAN_ALL := $(patsubst %,clean\:%,$(SUBDIRS)) -ifneq ($(firstword $(filter %-mingw32 %-cygwin,$(DUMPMACHINE))),) - EXE_SUFFIX := .exe -ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),) - XCFLAGS += -Wl,--large-address-aware -endif -endif +.PHONY: all clean $(BUILD_ALL) $(CLEAN_ALL) -CFLAGS = -std=c99 -D_DEFAULT_SOURCE -Wpedantic -I../libhashset/include $(XCFLAGS) +all: $(BUILD_ALL) -SRC_PATH := src -BIN_PATH := bin -ALL_PATH := $(SRC_PATH) $(BIN_PATH) +clean: $(CLEAN_ALL) -BIN_FILE := $(BIN_PATH)/hashset-example$(EXE_SUFFIX) -SRC_FILE := $(wildcard $(SRC_PATH)/*.c) -LIB_FILE := ../libhashset/lib/libhashset-1.a +$(BUILD_ALL): + $(MAKE) -C $(patsubst build:%,%,$@) -.PHONY: all build clean - -all: clean build - -build: $(ALL_PATH) $(BIN_FILE) - -$(BIN_FILE): $(SRC_FILE) $(LIB_FILE) - $(CC) $(CFLAGS) -o $@ $^ - -$(ALL_PATH): - mkdir -p $@ - -clean: - rm -f $(BIN_FILE) +$(CLEAN_ALL): + $(MAKE) -C $(patsubst clean:%,%,$@) clean diff --git a/example/hash-set/Makefile b/example/hash-set/Makefile new file mode 100644 index 0000000..4cd675c --- /dev/null +++ b/example/hash-set/Makefile @@ -0,0 +1,52 @@ +DUMPMACHINE := $(shell $(CC) -dumpmachine) + +ifneq ($(DEBUG),) + XCFLAGS = -Og -g +else +ifneq ($(ASAN),) + XCFLAGS = -O1 -g -fsanitize=address -fno-omit-frame-pointer -static-libasan +else + XCFLAGS = -Ofast -DNDEBUG +ifneq ($(firstword $(filter x86_64-%,$(DUMPMACHINE))),) + XCFLAGS += -march=x86-64 -mtune=nocona +else ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),) + XCFLAGS += -march=pentiumpro -mtune=intel +endif +ifneq ($(FLTO),) + XCFLAGS += -flto +endif + XCFLAGS += -s -static +endif +endif + +ifneq ($(firstword $(filter %-mingw32 %-cygwin,$(DUMPMACHINE))),) + EXE_SUFFIX := .exe +ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),) + XCFLAGS += -Wl,--large-address-aware +endif +endif + +CFLAGS = -std=c99 -D_DEFAULT_SOURCE -Wpedantic -I../../libhashset/include $(XCFLAGS) + +SRC_PATH := src +BIN_PATH := bin +ALL_PATH := $(SRC_PATH) $(BIN_PATH) + +BIN_FILE := $(BIN_PATH)/hashset-example$(EXE_SUFFIX) +SRC_FILE := $(wildcard $(SRC_PATH)/*.c) +LIB_FILE := ../../libhashset/lib/libhashset-1.a + +.PHONY: all build clean + +all: clean build + +build: $(ALL_PATH) $(BIN_FILE) + +$(BIN_FILE): $(SRC_FILE) $(LIB_FILE) + $(CC) $(CFLAGS) -o $@ $^ + +$(ALL_PATH): + mkdir -p $@ + +clean: + rm -f $(BIN_FILE) diff --git a/example/hashset-example.vcxproj b/example/hash-set/hashset-example.vcxproj similarity index 99% rename from example/hashset-example.vcxproj rename to example/hash-set/hashset-example.vcxproj index f44c56a..497a4fb 100644 --- a/example/hashset-example.vcxproj +++ b/example/hash-set/hashset-example.vcxproj @@ -43,20 +43,20 @@ - - {8cf3bd19-28b1-435d-b719-e00b052dfc3a} - + - + + {8cf3bd19-28b1-435d-b719-e00b052dfc3a} + 16.0 Win32Proj {8FB9B9DE-DC49-4224-892B-589422484766} - hashset-example + example-hash-set 10.0.19041.0 - hashset-example + example-hash-set diff --git a/example/hashset-example.vcxproj.filters b/example/hash-set/hashset-example.vcxproj.filters similarity index 100% rename from example/hashset-example.vcxproj.filters rename to example/hash-set/hashset-example.vcxproj.filters diff --git a/example/src/input.c b/example/hash-set/src/input.c similarity index 100% rename from example/src/input.c rename to example/hash-set/src/input.c diff --git a/example/src/input.h b/example/hash-set/src/input.h similarity index 100% rename from example/src/input.h rename to example/hash-set/src/input.h diff --git a/example/src/main.c b/example/hash-set/src/main.c similarity index 100% rename from example/src/main.c rename to example/hash-set/src/main.c diff --git a/hashset.sln b/hashset.sln index 72d30b7..78b29d6 100644 --- a/hashset.sln +++ b/hashset.sln @@ -3,11 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33027.164 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hashset-test", "test\hashset-test.vcxproj", "{0B7ABB95-B60F-418B-8386-930B1629058F}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhashset", "libhashset\libhashset.vcxproj", "{8CF3BD19-28B1-435D-B719-E00B052DFC3A}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hashset-example", "example\hashset-example.vcxproj", "{8FB9B9DE-DC49-4224-892B-589422484766}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example-hash-set", "example\hash-set\hashset-example.vcxproj", "{8FB9B9DE-DC49-4224-892B-589422484766}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{1EFCA710-2528-41D7-B757-F4615301DCA2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{42437750-05E3-4DB6-AADA-FB44E73729B0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-hash-set", "test\hash-set\hashset-test.vcxproj", "{0B7ABB95-B60F-418B-8386-930B1629058F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -22,24 +26,6 @@ Global Static|x86 = Static|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|ARM64.Build.0 = Debug|ARM64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|x64.ActiveCfg = Debug|x64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|x64.Build.0 = Debug|x64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|x86.ActiveCfg = Debug|Win32 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|x86.Build.0 = Debug|Win32 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|ARM64.ActiveCfg = Shared|ARM64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|ARM64.Build.0 = Shared|ARM64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|x64.ActiveCfg = Shared|x64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|x64.Build.0 = Shared|x64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|x86.ActiveCfg = Shared|Win32 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|x86.Build.0 = Shared|Win32 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|ARM64.ActiveCfg = Static|ARM64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|ARM64.Build.0 = Static|ARM64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|x64.ActiveCfg = Static|x64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|x64.Build.0 = Static|x64 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|x86.ActiveCfg = Static|Win32 - {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|x86.Build.0 = Static|Win32 {8CF3BD19-28B1-435D-B719-E00B052DFC3A}.Debug|ARM64.ActiveCfg = Debug|ARM64 {8CF3BD19-28B1-435D-B719-E00B052DFC3A}.Debug|ARM64.Build.0 = Debug|ARM64 {8CF3BD19-28B1-435D-B719-E00B052DFC3A}.Debug|x64.ActiveCfg = Debug|x64 @@ -76,10 +62,32 @@ Global {8FB9B9DE-DC49-4224-892B-589422484766}.Static|x64.Build.0 = Static|x64 {8FB9B9DE-DC49-4224-892B-589422484766}.Static|x86.ActiveCfg = Static|Win32 {8FB9B9DE-DC49-4224-892B-589422484766}.Static|x86.Build.0 = Static|Win32 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|ARM64.Build.0 = Debug|ARM64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|x64.ActiveCfg = Debug|x64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|x64.Build.0 = Debug|x64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|x86.ActiveCfg = Debug|Win32 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Debug|x86.Build.0 = Debug|Win32 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|ARM64.ActiveCfg = Shared|ARM64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|ARM64.Build.0 = Shared|ARM64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|x64.ActiveCfg = Shared|x64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|x64.Build.0 = Shared|x64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|x86.ActiveCfg = Shared|Win32 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Shared|x86.Build.0 = Shared|Win32 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|ARM64.ActiveCfg = Static|ARM64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|ARM64.Build.0 = Static|ARM64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|x64.ActiveCfg = Static|x64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|x64.Build.0 = Static|x64 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|x86.ActiveCfg = Static|Win32 + {0B7ABB95-B60F-418B-8386-930B1629058F}.Static|x86.Build.0 = Static|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {8FB9B9DE-DC49-4224-892B-589422484766} = {1EFCA710-2528-41D7-B757-F4615301DCA2} + {0B7ABB95-B60F-418B-8386-930B1629058F} = {42437750-05E3-4DB6-AADA-FB44E73729B0} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DC8E0EA3-7ABA-4BA8-B2E1-D9A43934BA40} EndGlobalSection diff --git a/libhashset/include/hash_map.h b/libhashset/include/hash_map.h index cbdf3cd..9ed54a1 100644 --- a/libhashset/include/hash_map.h +++ b/libhashset/include/hash_map.h @@ -46,8 +46,8 @@ HASHSET_API hash_map64_t *hash_map_create64(const size_t initial_capacity, const HASHSET_API void hash_map_destroy32(hash_map32_t *const instance); HASHSET_API void hash_map_destroy64(hash_map64_t *const instance); -HASHSET_API errno_t hash_map_insert32(hash_map32_t *const instance, const uint32_t key, const uintptr_t value); -HASHSET_API errno_t hash_map_insert64(hash_map64_t *const instance, const uint64_t key, const uintptr_t value); +HASHSET_API errno_t hash_map_insert32(hash_map32_t *const instance, const uint32_t key, const uint32_t value); +HASHSET_API errno_t hash_map_insert64(hash_map64_t *const instance, const uint64_t key, const uint64_t value); HASHSET_API errno_t hash_map_remove32(hash_map32_t *const instance, const uint32_t key); HASHSET_API errno_t hash_map_remove64(hash_map64_t *const instance, const uint64_t key); @@ -58,11 +58,11 @@ HASHSET_API errno_t hash_map_clear64(hash_map64_t *const instance); HASHSET_API errno_t hash_map_contains32(const hash_map32_t *const instance, const uint32_t key); HASHSET_API errno_t hash_map_contains64(const hash_map64_t *const instance, const uint64_t key); -HASHSET_API errno_t hash_map_get32(const hash_map32_t *const instance, const uint32_t key, uintptr_t *const value); -HASHSET_API errno_t hash_map_get64(const hash_map64_t *const instance, const uint64_t key, uintptr_t *const value); +HASHSET_API errno_t hash_map_get32(const hash_map32_t *const instance, const uint32_t key, uint32_t *const value); +HASHSET_API errno_t hash_map_get64(const hash_map64_t *const instance, const uint64_t key, uint64_t *const value); -HASHSET_API errno_t hash_map_iterate32(const hash_map32_t *const instance, size_t *const cursor, uint32_t *const key, uintptr_t *const value); -HASHSET_API errno_t hash_map_iterate64(const hash_map64_t *const instance, size_t *const cursor, uint64_t *const key, uintptr_t *const value); +HASHSET_API errno_t hash_map_iterate32(const hash_map32_t *const instance, size_t *const cursor, uint32_t *const key, uint32_t *const value); +HASHSET_API errno_t hash_map_iterate64(const hash_map64_t *const instance, size_t *const cursor, uint64_t *const key, uint64_t *const value); HASHSET_API size_t hash_map_size32(const hash_map32_t *const instance); HASHSET_API size_t hash_map_size64(const hash_map64_t *const instance); @@ -70,8 +70,11 @@ HASHSET_API size_t hash_map_size64(const hash_map64_t *const instance); HASHSET_API errno_t hash_map_info32(const hash_map32_t *const instance, size_t *const capacity, size_t *const valid, size_t *const deleted, size_t *const limit); HASHSET_API errno_t hash_map_info64(const hash_map64_t *const instance, size_t *const capacity, size_t *const valid, size_t *const deleted, size_t *const limit); -HASHSET_API errno_t hash_map_dump32(const hash_map32_t *const instance, int (*const callback)(const size_t index, const char status, const uint32_t key, const uintptr_t value)); -HASHSET_API errno_t hash_map_dump64(const hash_map64_t *const instance, int (*const callback)(const size_t index, const char status, const uint64_t key, const uintptr_t value)); +typedef int (*hash_map_callback32_t)(const size_t index, const char status, const uint32_t key, const uint32_t value); +typedef int (*hash_map_callback64_t)(const size_t index, const char status, const uint64_t key, const uint64_t value); + +HASHSET_API errno_t hash_map_dump32(const hash_map32_t *const instance, const hash_map_callback32_t callback); +HASHSET_API errno_t hash_map_dump64(const hash_map64_t *const instance, const hash_map_callback64_t callback); #ifdef __cplusplus } diff --git a/libhashset/include/hash_set.h b/libhashset/include/hash_set.h index d82a0ca..bdb3331 100644 --- a/libhashset/include/hash_set.h +++ b/libhashset/include/hash_set.h @@ -67,8 +67,11 @@ HASHSET_API size_t hash_set_size64(const hash_set64_t *const instance); HASHSET_API errno_t hash_set_info32(const hash_set32_t *const instance, size_t *const capacity, size_t *const valid, size_t *const deleted, size_t *const limit); HASHSET_API errno_t hash_set_info64(const hash_set64_t *const instance, size_t *const capacity, size_t *const valid, size_t *const deleted, size_t *const limit); -HASHSET_API errno_t hash_set_dump32(const hash_set32_t *const instance, int (*const callback)(const size_t index, const char status, const uint32_t item)); -HASHSET_API errno_t hash_set_dump64(const hash_set64_t *const instance, int (*const callback)(const size_t index, const char status, const uint64_t item)); +typedef int (*hash_set_callback32_t)(const size_t index, const char status, const uint32_t item); +typedef int (*hash_set_callback64_t)(const size_t index, const char status, const uint64_t item); + +HASHSET_API errno_t hash_set_dump32(const hash_set32_t *const instance, const hash_set_callback32_t callback); +HASHSET_API errno_t hash_set_dump64(const hash_set64_t *const instance, const hash_set_callback64_t callback); #ifdef __cplusplus } diff --git a/libhashset/src/common.h b/libhashset/src/common.h index 5764eba..f8f544f 100644 --- a/libhashset/src/common.h +++ b/libhashset/src/common.h @@ -44,6 +44,9 @@ static const double DEFAULT_LOADFCTR = 0.8; #define SAFE_FREE(X) do { if ((X)) { free((X)); (X) = NULL; } } while(0) +#define _CONCAT(X,Y) X##Y +#define CONCAT(X,Y) _CONCAT(X,Y) + /* ------------------------------------------------- */ /* Math */ /* ------------------------------------------------- */ diff --git a/libhashset/src/generic_hash_map.h b/libhashset/src/generic_hash_map.h index e96f1fb..a9087e8 100644 --- a/libhashset/src/generic_hash_map.h +++ b/libhashset/src/generic_hash_map.h @@ -12,9 +12,6 @@ #error NAME_SUFFIX must be defined! #endif -#define _CONCAT(X,Y) X##Y -#define CONCAT(X,Y) _CONCAT(X,Y) - #define DECLARE(X) CONCAT(X,NAME_SUFFIX) /* ------------------------------------------------- */ @@ -23,8 +20,7 @@ typedef struct DECLARE(_hash_map_data) { - key_t *keys; - uintptr_t *values; + value_t *keys, *values; uint8_t *used, *deleted; size_t capacity; } @@ -45,13 +41,13 @@ static INLINE bool_t alloc_data(hash_data_t *const data, const size_t capacity) { zero_memory(data, 1U, sizeof(hash_data_t)); - data->keys = (key_t*) calloc(capacity, sizeof(key_t)); + data->keys = (value_t*) calloc(capacity, sizeof(value_t)); if (!data->values) { return FALSE; } - data->values = (uintptr_t*) calloc(capacity, sizeof(uintptr_t)); + data->values = (value_t*) calloc(capacity, sizeof(value_t)); if (!data->values) { return FALSE; @@ -94,7 +90,7 @@ static INLINE void free_data(hash_data_t *const data) #define INDEX(X) ((size_t)((X) % data->capacity)) -static INLINE bool_t find_slot(const hash_data_t *const data, const key_t key, size_t *const index_out, bool_t *const reused_out) +static INLINE bool_t find_slot(const hash_data_t *const data, const value_t key, size_t *const index_out, bool_t *const reused_out) { uint64_t loop = 0U; bool_t is_saved = FALSE; @@ -131,7 +127,7 @@ static INLINE bool_t find_slot(const hash_data_t *const data, const key_t key, s return FALSE; } -static INLINE void put_value(hash_data_t *const data, const size_t index, const key_t key, const uintptr_t value, const bool_t reusing) +static INLINE void put_value(hash_data_t *const data, const size_t index, const value_t key, const value_t value, const bool_t reusing) { data->keys[index] = key; data->values[index] = value; @@ -179,8 +175,7 @@ static INLINE errno_t rebuild_map(hash_map_t *const instance, const size_t new_c { if (IS_VALID(instance->data, k)) { - const key_t key = instance->data.keys[k]; - const uintptr_t value = instance->data.values[k]; + const value_t key = instance->data.keys[k], value = instance->data.values[k]; if (find_slot(&temp, key, &index, NULL)) { free_data(&temp); @@ -232,7 +227,7 @@ void DECLARE(hash_map_destroy)(hash_map_t *instance) } } -errno_t DECLARE(hash_map_insert)(hash_map_t *const instance, const key_t key, const uintptr_t value) +errno_t DECLARE(hash_map_insert)(hash_map_t *const instance, const value_t key, const value_t value) { size_t index; bool_t slot_reused; @@ -244,7 +239,7 @@ errno_t DECLARE(hash_map_insert)(hash_map_t *const instance, const key_t key, co if (find_slot(&instance->data, key, &index, &slot_reused)) { - instance->data.values[index] = index; + instance->data.values[index] = value; return EEXIST; } @@ -272,7 +267,7 @@ errno_t DECLARE(hash_map_insert)(hash_map_t *const instance, const key_t key, co return 0; } -errno_t DECLARE(hash_map_contains)(const hash_map_t *const instance, const key_t key) +errno_t DECLARE(hash_map_contains)(const hash_map_t *const instance, const value_t key) { if ((!instance) || (!instance->data.keys)) { @@ -282,7 +277,7 @@ errno_t DECLARE(hash_map_contains)(const hash_map_t *const instance, const key_t return (instance->valid && find_slot(&instance->data, key, NULL, NULL)) ? 0 : ENOENT; } -errno_t DECLARE(hash_map_get)(const hash_map_t *const instance, const key_t key, uintptr_t *const value) +errno_t DECLARE(hash_map_get)(const hash_map_t *const instance, const value_t key, value_t *const value) { size_t index; @@ -300,7 +295,7 @@ errno_t DECLARE(hash_map_get)(const hash_map_t *const instance, const key_t key, return 0; } -errno_t DECLARE(hash_map_remove)(hash_map_t *const instance, const key_t key) +errno_t DECLARE(hash_map_remove)(hash_map_t *const instance, const value_t key) { size_t index; @@ -367,7 +362,7 @@ errno_t DECLARE(hash_map_clear)(hash_map_t *const instance) return 0; } -errno_t DECLARE(hash_map_iterate)(const hash_map_t *const instance, size_t *const cursor, key_t *const key, uintptr_t *const value) +errno_t DECLARE(hash_map_iterate)(const hash_map_t *const instance, size_t *const cursor, value_t *const key, value_t *const value) { size_t index; @@ -429,11 +424,11 @@ errno_t DECLARE(hash_map_info)(const hash_map_t *const instance, size_t *const c return 0; } -HASHSET_API errno_t DECLARE(hash_map_dump)(const hash_map_t *const instance, int (*const callback)(const size_t index, const char status, const key_t key, const uintptr_t value)) +HASHSET_API errno_t DECLARE(hash_map_dump)(const hash_map_t *const instance, const hash_map_callback_t callback) { size_t index; - if ((!instance) || (!instance->data.values)) + if ((!instance) || (!instance->data.values) || (!callback)) { return EINVAL; } diff --git a/libhashset/src/generic_hash_set.h b/libhashset/src/generic_hash_set.h index aedf05f..00c68ff 100644 --- a/libhashset/src/generic_hash_set.h +++ b/libhashset/src/generic_hash_set.h @@ -12,9 +12,6 @@ #error NAME_SUFFIX must be defined! #endif -#define _CONCAT(X,Y) X##Y -#define CONCAT(X,Y) _CONCAT(X,Y) - #define DECLARE(X) CONCAT(X,NAME_SUFFIX) /* ------------------------------------------------- */ @@ -23,7 +20,7 @@ typedef struct DECLARE(_hash_set_data) { - item_t *items; + value_t *items; uint8_t *used, *deleted; size_t capacity; } @@ -44,7 +41,7 @@ static INLINE bool_t alloc_data(hash_data_t *const data, const size_t capacity) { zero_memory(data, 1U, sizeof(hash_data_t)); - data->items = (item_t*) calloc(capacity, sizeof(item_t)); + data->items = (value_t*) calloc(capacity, sizeof(value_t)); if (!data->items) { return FALSE; @@ -86,7 +83,7 @@ static INLINE void free_data(hash_data_t *const data) #define INDEX(X) ((size_t)((X) % data->capacity)) -static INLINE bool_t find_slot(const hash_data_t *const data, const item_t item, size_t *const index_out, bool_t *const reused_out) +static INLINE bool_t find_slot(const hash_data_t *const data, const value_t item, size_t *const index_out, bool_t *const reused_out) { uint64_t loop = 0U; bool_t is_saved = FALSE; @@ -123,7 +120,7 @@ static INLINE bool_t find_slot(const hash_data_t *const data, const item_t item, return FALSE; } -static INLINE void put_item(hash_data_t *const data, const size_t index, const item_t item, const bool_t reusing) +static INLINE void put_item(hash_data_t *const data, const size_t index, const value_t item, const bool_t reusing) { data->items[index] = item; @@ -170,7 +167,7 @@ static INLINE errno_t rebuild_set(hash_set_t *const instance, const size_t new_c { if (IS_VALID(instance->data, k)) { - const item_t item = instance->data.items[k]; + const value_t item = instance->data.items[k]; if (find_slot(&temp, item, &index, NULL)) { free_data(&temp); @@ -222,7 +219,7 @@ void DECLARE(hash_set_destroy)(hash_set_t *instance) } } -errno_t DECLARE(hash_set_insert)(hash_set_t *const instance, const item_t item) +errno_t DECLARE(hash_set_insert)(hash_set_t *const instance, const value_t item) { size_t index; bool_t slot_reused; @@ -261,7 +258,7 @@ errno_t DECLARE(hash_set_insert)(hash_set_t *const instance, const item_t item) return 0; } -errno_t DECLARE(hash_set_contains)(const hash_set_t *const instance, const item_t item) +errno_t DECLARE(hash_set_contains)(const hash_set_t *const instance, const value_t item) { if ((!instance) || (!instance->data.items)) { @@ -271,7 +268,7 @@ errno_t DECLARE(hash_set_contains)(const hash_set_t *const instance, const item_ return (instance->valid && find_slot(&instance->data, item, NULL, NULL)) ? 0 : ENOENT; } -errno_t DECLARE(hash_set_remove)(hash_set_t *const instance, const item_t item) +errno_t DECLARE(hash_set_remove)(hash_set_t *const instance, const value_t item) { size_t index; @@ -338,7 +335,7 @@ errno_t DECLARE(hash_set_clear)(hash_set_t *const instance) return 0; } -errno_t DECLARE(hash_set_iterate)(const hash_set_t *const instance, size_t *const cursor, item_t *const item) +errno_t DECLARE(hash_set_iterate)(const hash_set_t *const instance, size_t *const cursor, value_t *const item) { size_t index; @@ -396,11 +393,11 @@ errno_t DECLARE(hash_set_info)(const hash_set_t *const instance, size_t *const c return 0; } -HASHSET_API errno_t DECLARE(hash_set_dump)(const hash_set_t *const instance, int (*const callback)(const size_t index, const char status, const item_t item)) +HASHSET_API errno_t DECLARE(hash_set_dump)(const hash_set_t *const instance, const hash_set_callback_t callback) { size_t index; - if ((!instance) || (!instance->data.items)) + if ((!instance) || (!instance->data.items) || (!callback)) { return EINVAL; } diff --git a/libhashset/src/hash_map_32.c b/libhashset/src/hash_map_32.c index ad1d195..735b480 100644 --- a/libhashset/src/hash_map_32.c +++ b/libhashset/src/hash_map_32.c @@ -7,6 +7,7 @@ #define NAME_SUFFIX 32 typedef hash_map32_t hash_map_t; -typedef uint32_t key_t; +typedef hash_map_callback32_t hash_map_callback_t; +typedef uint32_t value_t; #include "generic_hash_map.h" diff --git a/libhashset/src/hash_map_64.c b/libhashset/src/hash_map_64.c index 496ecc0..45ffb7f 100644 --- a/libhashset/src/hash_map_64.c +++ b/libhashset/src/hash_map_64.c @@ -7,6 +7,7 @@ #define NAME_SUFFIX 64 typedef hash_map64_t hash_map_t; -typedef uint64_t key_t; +typedef hash_map_callback64_t hash_map_callback_t; +typedef uint64_t value_t; #include "generic_hash_map.h" diff --git a/libhashset/src/hash_set_32.c b/libhashset/src/hash_set_32.c index a6c3a92..8aacc8e 100644 --- a/libhashset/src/hash_set_32.c +++ b/libhashset/src/hash_set_32.c @@ -7,6 +7,7 @@ #define NAME_SUFFIX 32 typedef hash_set32_t hash_set_t; -typedef uint32_t item_t; +typedef hash_set_callback32_t hash_set_callback_t; +typedef uint32_t value_t; #include "generic_hash_set.h" diff --git a/libhashset/src/hash_set_64.c b/libhashset/src/hash_set_64.c index 12292b4..c90d6d9 100644 --- a/libhashset/src/hash_set_64.c +++ b/libhashset/src/hash_set_64.c @@ -7,6 +7,7 @@ #define NAME_SUFFIX 64 typedef hash_set64_t hash_set_t; -typedef uint64_t item_t; +typedef hash_set_callback64_t hash_set_callback_t; +typedef uint64_t value_t; #include "generic_hash_set.h" diff --git a/test/Makefile b/test/Makefile index 1e821d0..4f44c6a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,52 +1,16 @@ -DUMPMACHINE := $(shell $(CC) -dumpmachine) +SUBDIRS := hash-set -ifneq ($(DEBUG),) - XCFLAGS = -Og -g -else -ifneq ($(ASAN),) - XCFLAGS = -O1 -g -fsanitize=address -fno-omit-frame-pointer -static-libasan -else - XCFLAGS = -Ofast -DNDEBUG -ifneq ($(firstword $(filter x86_64-%,$(DUMPMACHINE))),) - XCFLAGS += -march=x86-64 -mtune=nocona -else ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),) - XCFLAGS += -march=pentiumpro -mtune=intel -endif -ifneq ($(FLTO),) - XCFLAGS += -flto -endif - XCFLAGS += -s -static -endif -endif +BUILD_ALL := $(patsubst %,build\:%,$(SUBDIRS)) +CLEAN_ALL := $(patsubst %,clean\:%,$(SUBDIRS)) -ifneq ($(firstword $(filter %-mingw32 %-cygwin,$(DUMPMACHINE))),) - EXE_SUFFIX := .exe -ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),) - XCFLAGS += -Wl,--large-address-aware -endif -endif +.PHONY: all clean $(BUILD_ALL) $(CLEAN_ALL) -CFLAGS = -std=c99 -D_DEFAULT_SOURCE -Wpedantic -I../libhashset/include $(XCFLAGS) +all: $(BUILD_ALL) -SRC_PATH := src -BIN_PATH := bin -ALL_PATH := $(SRC_PATH) $(BIN_PATH) +clean: $(CLEAN_ALL) -BIN_FILE := $(BIN_PATH)/hashset-test$(EXE_SUFFIX) -SRC_FILE := $(wildcard $(SRC_PATH)/*.c) -LIB_FILE := ../libhashset/lib/libhashset-1.a +$(BUILD_ALL): + $(MAKE) -C $(patsubst build:%,%,$@) -.PHONY: all build clean - -all: clean build - -build: $(ALL_PATH) $(BIN_FILE) - -$(BIN_FILE): $(SRC_FILE) $(LIB_FILE) - $(CC) $(CFLAGS) -o $@ $^ - -$(ALL_PATH): - mkdir -p $@ - -clean: - rm -f $(BIN_FILE) +$(CLEAN_ALL): + $(MAKE) -C $(patsubst clean:%,%,$@) clean diff --git a/test/hash-set/Makefile b/test/hash-set/Makefile new file mode 100644 index 0000000..14b182d --- /dev/null +++ b/test/hash-set/Makefile @@ -0,0 +1,52 @@ +DUMPMACHINE := $(shell $(CC) -dumpmachine) + +ifneq ($(DEBUG),) + XCFLAGS = -Og -g +else +ifneq ($(ASAN),) + XCFLAGS = -O1 -g -fsanitize=address -fno-omit-frame-pointer -static-libasan +else + XCFLAGS = -Ofast -DNDEBUG +ifneq ($(firstword $(filter x86_64-%,$(DUMPMACHINE))),) + XCFLAGS += -march=x86-64 -mtune=nocona +else ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),) + XCFLAGS += -march=pentiumpro -mtune=intel +endif +ifneq ($(FLTO),) + XCFLAGS += -flto +endif + XCFLAGS += -s -static +endif +endif + +ifneq ($(firstword $(filter %-mingw32 %-cygwin,$(DUMPMACHINE))),) + EXE_SUFFIX := .exe +ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),) + XCFLAGS += -Wl,--large-address-aware +endif +endif + +CFLAGS = -std=c99 -D_DEFAULT_SOURCE -Wpedantic -I../../libhashset/include $(XCFLAGS) + +SRC_PATH := src +BIN_PATH := bin +ALL_PATH := $(SRC_PATH) $(BIN_PATH) + +BIN_FILE := $(BIN_PATH)/hashset-test$(EXE_SUFFIX) +SRC_FILE := $(wildcard $(SRC_PATH)/*.c) +LIB_FILE := ../../libhashset/lib/libhashset-1.a + +.PHONY: all build clean + +all: clean build + +build: $(ALL_PATH) $(BIN_FILE) + +$(BIN_FILE): $(SRC_FILE) $(LIB_FILE) + $(CC) $(CFLAGS) -o $@ $^ + +$(ALL_PATH): + mkdir -p $@ + +clean: + rm -f $(BIN_FILE) diff --git a/test/hashset-test.vcxproj b/test/hash-set/hashset-test.vcxproj similarity index 99% rename from test/hashset-test.vcxproj rename to test/hash-set/hashset-test.vcxproj index 90c1596..6ad33b7 100644 --- a/test/hashset-test.vcxproj +++ b/test/hash-set/hashset-test.vcxproj @@ -43,22 +43,22 @@ - - - {8cf3bd19-28b1-435d-b719-e00b052dfc3a} - - + + + {8cf3bd19-28b1-435d-b719-e00b052dfc3a} + + 16.0 Win32Proj {0b7abb95-b60f-418b-8386-930b1629058f} - hashset-test + test-hash-set 10.0.19041.0 - hashset-test + test-hash-set diff --git a/test/hashset-test.vcxproj.filters b/test/hash-set/hashset-test.vcxproj.filters similarity index 100% rename from test/hashset-test.vcxproj.filters rename to test/hash-set/hashset-test.vcxproj.filters diff --git a/test/src/main.c b/test/hash-set/src/main.c similarity index 100% rename from test/src/main.c rename to test/hash-set/src/main.c diff --git a/test/src/random.c b/test/hash-set/src/random.c similarity index 100% rename from test/src/random.c rename to test/hash-set/src/random.c diff --git a/test/src/random.h b/test/hash-set/src/random.h similarity index 100% rename from test/src/random.h rename to test/hash-set/src/random.h diff --git a/test/src/tests.c b/test/hash-set/src/tests.c similarity index 98% rename from test/src/tests.c rename to test/hash-set/src/tests.c index 28b0e5b..0eead94 100644 --- a/test/src/tests.c +++ b/test/hash-set/src/tests.c @@ -38,12 +38,12 @@ while(0) #define MAXIMUM 425984U -static int dump_callback(const size_t index, const char status, const uint64_t value) +static int dump_callback(const size_t index, const char status, const uint64_t item) { #ifndef NDEBUG - printf("%016zX: %c -> %016" PRIX64 "\n", index, status, value); + printf("%016zX: %c -> %016" PRIX64 "\n", index, status, item); #else - UNUSED(index); UNUSED(status); UNUSED(value); + UNUSED(index); UNUSED(status); UNUSED(item); #endif return 1; } diff --git a/test/src/tests.h b/test/hash-set/src/tests.h similarity index 100% rename from test/src/tests.h rename to test/hash-set/src/tests.h