Improved hash-map tests.
This commit is contained in:
parent
cb898fc8a6
commit
58fdfcb573
5
Makefile
5
Makefile
@ -3,7 +3,7 @@ SUBDIRS := libhashset example test
|
||||
BUILD_ALL := $(patsubst %,build\:%,$(SUBDIRS))
|
||||
CLEAN_ALL := $(patsubst %,clean\:%,$(SUBDIRS))
|
||||
|
||||
.PHONY: all clean $(BUILD_ALL) $(CLEAN_ALL)
|
||||
.PHONY: all test clean $(BUILD_ALL) $(CLEAN_ALL)
|
||||
|
||||
all: $(BUILD_ALL)
|
||||
|
||||
@ -14,3 +14,6 @@ $(BUILD_ALL):
|
||||
|
||||
$(CLEAN_ALL):
|
||||
$(MAKE) -C $(patsubst clean:%,%,$@) clean
|
||||
|
||||
test: $(BUILD_ALL)
|
||||
$(MAKE) -C test test
|
||||
|
@ -1,16 +1,22 @@
|
||||
SUBDIRS := hash-set
|
||||
SUBDIRS := hash-set hash-map
|
||||
|
||||
BUILD_ALL := $(patsubst %,build\:%,$(SUBDIRS))
|
||||
CLEAN_ALL := $(patsubst %,clean\:%,$(SUBDIRS))
|
||||
TESTS_ALL := $(patsubst %,rtest\:%,$(SUBDIRS))
|
||||
|
||||
.PHONY: all clean $(BUILD_ALL) $(CLEAN_ALL)
|
||||
.PHONY: all clean test $(BUILD_ALL) $(CLEAN_ALL) $(TESTS_ALL)
|
||||
|
||||
all: $(BUILD_ALL)
|
||||
|
||||
clean: $(CLEAN_ALL)
|
||||
|
||||
test: $(TESTS_ALL)
|
||||
|
||||
$(BUILD_ALL):
|
||||
$(MAKE) -C $(patsubst build:%,%,$@)
|
||||
|
||||
$(CLEAN_ALL):
|
||||
$(MAKE) -C $(patsubst clean:%,%,$@) clean
|
||||
|
||||
$(TESTS_ALL):
|
||||
$(MAKE) -C $(patsubst rtest:%,%,$@) test
|
||||
|
@ -10,7 +10,7 @@ ALL_PATH := $(SRC_PATH) $(BIN_PATH)
|
||||
BIN_FILE := $(BIN_PATH)/test-hash-set$(EXE_SUFFIX)
|
||||
SRC_FILE := $(wildcard $(SRC_PATH)/*.c)
|
||||
|
||||
.PHONY: all build clean
|
||||
.PHONY: all build clean test
|
||||
|
||||
all: clean build
|
||||
|
||||
@ -24,3 +24,6 @@ $(ALL_PATH):
|
||||
|
||||
clean:
|
||||
rm -vf $(BIN_FILE)
|
||||
|
||||
test: build
|
||||
./$(BIN_FILE)
|
||||
|
@ -35,6 +35,8 @@ int main(void)
|
||||
}
|
||||
|
||||
RUN_TEST_CASE(1);
|
||||
RUN_TEST_CASE(2);
|
||||
RUN_TEST_CASE(3);
|
||||
|
||||
hash_map_destroy64(hash_set);
|
||||
puts("Tests completed successfully.");
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define TEST_COUNT 4
|
||||
#define TEST_COUNT 3
|
||||
|
||||
/* ========================================================================= */
|
||||
/* Utilities */
|
||||
@ -41,28 +41,35 @@ while(0)
|
||||
int test_function_1(hash_map64_t *const hash_set)
|
||||
{
|
||||
size_t r, j, cursor, capacity, valid, deleted, limit;
|
||||
uint64_t key, value;
|
||||
uint8_t spinner = 0U, *test1, *test2;
|
||||
uint64_t key, value, *test_data;
|
||||
uint8_t spinner = 0U, *test_key1, *test_key2;
|
||||
|
||||
random_t random;
|
||||
random_init(&random);
|
||||
|
||||
test1 = (uint8_t*) malloc(TEST_SIZE * sizeof(uint8_t));
|
||||
if (!test1)
|
||||
test_key1 = (uint8_t*) malloc(TEST_SIZE * sizeof(uint8_t));
|
||||
if (!test_key1)
|
||||
{
|
||||
abort(); /*malloc has failed!*/
|
||||
}
|
||||
|
||||
test2 = (uint8_t*) malloc(TEST_SIZE * sizeof(uint8_t));
|
||||
if (!test2)
|
||||
test_key2 = (uint8_t*) malloc(TEST_SIZE * sizeof(uint8_t));
|
||||
if (!test_key2)
|
||||
{
|
||||
abort(); /*malloc has failed!*/
|
||||
}
|
||||
|
||||
test_data = (uint64_t*) malloc(TEST_SIZE * sizeof(uint64_t));
|
||||
if (!test_data)
|
||||
{
|
||||
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));
|
||||
memset(test_key1, 0, TEST_SIZE * sizeof(uint8_t));
|
||||
memset(test_key2, 0, TEST_SIZE * sizeof(uint8_t));
|
||||
memset(test_data, 0, TEST_SIZE * sizeof(uint64_t));
|
||||
|
||||
for (j = 0U; j < TEST_SIZE / 3U; ++j)
|
||||
{
|
||||
@ -71,15 +78,167 @@ int test_function_1(hash_map64_t *const hash_set)
|
||||
{
|
||||
rnd = random_next(&random) % TEST_SIZE;
|
||||
}
|
||||
while (test1[rnd]);
|
||||
INVERT(test1[rnd]);
|
||||
while (test_key1[rnd]);
|
||||
INVERT(test_key1[rnd]);
|
||||
}
|
||||
|
||||
for (j = 0U; j < TEST_SIZE; ++j)
|
||||
{
|
||||
if (test1[j])
|
||||
if (test_key1[j])
|
||||
{
|
||||
const errno_t error = hash_map_insert64(hash_set, j, 0U);
|
||||
const errno_t error = hash_map_insert64(hash_set, j, test_data[j] = random_next(&random));
|
||||
if (error)
|
||||
{
|
||||
printf("Insert operation has failed! (error: %d)\n", error);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (!(++spinner & 0x0F))
|
||||
{
|
||||
PRINT_SET_INFO(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0U; j < TEST_SIZE; ++j)
|
||||
{
|
||||
const errno_t error = hash_map_contains64(hash_set, j);
|
||||
if (error != (test_key1[j] ? 0 : ENOENT))
|
||||
{
|
||||
printf("Contains operation has failed! (error: %d)\n", error);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
cursor = 0U;
|
||||
while (!hash_map_iterate64(hash_set, &cursor, &key, &value))
|
||||
{
|
||||
if ((!test_key1[key]) || test_key2[key])
|
||||
{
|
||||
puts("Iteration error has been detected!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
INVERT(test_key2[key]);
|
||||
}
|
||||
|
||||
for (j = 0U; j < TEST_SIZE; ++j)
|
||||
{
|
||||
if (test_key1[j] != test_key2[j])
|
||||
{
|
||||
puts("Iteration error has been detected!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0U; j < TEST_SIZE; ++j)
|
||||
{
|
||||
if (test_key1[j])
|
||||
{
|
||||
if (!hash_map_get64(hash_set, j, &value))
|
||||
{
|
||||
if (value != test_data[j])
|
||||
{
|
||||
puts("Value mismatch has been detected!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
puts("Failed to retrieve the value!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0U; j < TEST_SIZE; ++j)
|
||||
{
|
||||
if (test_key1[j])
|
||||
{
|
||||
const errno_t error = hash_map_remove64(hash_set, j);
|
||||
if (error)
|
||||
{
|
||||
printf("Remove operation has failed! (error: %d)\n", error);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (!(++spinner & 0x0F))
|
||||
{
|
||||
PRINT_SET_INFO(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0U; j < TEST_SIZE; ++j)
|
||||
{
|
||||
const errno_t error = hash_map_contains64(hash_set, j);
|
||||
if (error != ENOENT)
|
||||
{
|
||||
printf("Contains operation has failed! (error: %d)\n", error);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (hash_map_size64(hash_set) != 0U)
|
||||
{
|
||||
puts("Invalid size!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
free(test_key1);
|
||||
free(test_key2);
|
||||
free(test_data);
|
||||
|
||||
PRINT_SET_INFO(1);
|
||||
puts("---------");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
/* TEST #2 */
|
||||
/* ========================================================================= */
|
||||
|
||||
int test_function_2(hash_map64_t *const hash_set)
|
||||
{
|
||||
size_t r, j, capacity, valid, deleted, limit;
|
||||
uint64_t value, *test_val;
|
||||
uint8_t spinner = 0U, *test_key;
|
||||
|
||||
random_t random;
|
||||
random_init(&random);
|
||||
|
||||
test_key = (uint8_t*) malloc(TEST_SIZE * sizeof(uint8_t));
|
||||
if (!test_key)
|
||||
{
|
||||
abort(); /*malloc has failed!*/
|
||||
}
|
||||
|
||||
test_val = (uint64_t*) malloc(TEST_SIZE * sizeof(uint64_t));
|
||||
if (!test_val)
|
||||
{
|
||||
abort(); /*malloc has failed!*/
|
||||
}
|
||||
|
||||
for (r = 0U; r < 64U; ++r)
|
||||
{
|
||||
memset(test_key, 0, TEST_SIZE * sizeof(uint8_t));
|
||||
memset(test_val, 0, TEST_SIZE * sizeof(uint64_t));
|
||||
|
||||
for (j = 0U; j < TEST_SIZE / 3U; ++j)
|
||||
{
|
||||
size_t rnd;
|
||||
do
|
||||
{
|
||||
rnd = random_next(&random) % TEST_SIZE;
|
||||
}
|
||||
while (test_key[rnd]);
|
||||
INVERT(test_key[rnd]);
|
||||
}
|
||||
|
||||
for (j = 0U; j < TEST_SIZE; ++j)
|
||||
{
|
||||
if (test_key[j])
|
||||
{
|
||||
const errno_t error = hash_map_insert64(hash_set, j, test_val[j] = random_next(&random));
|
||||
if (error)
|
||||
{
|
||||
printf("Insert operation has failed! (error: %d)\n", error);
|
||||
@ -92,34 +251,14 @@ int test_function_1(hash_map64_t *const hash_set)
|
||||
}
|
||||
}
|
||||
|
||||
cursor = 0U;
|
||||
while (!hash_map_iterate64(hash_set, &cursor, &key, &value))
|
||||
{
|
||||
if ((!test1[key]) || test2[key])
|
||||
{
|
||||
puts("Iteration error has been detected!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
INVERT(test2[key]);
|
||||
}
|
||||
|
||||
for (j = 0U; j < TEST_SIZE; ++j)
|
||||
{
|
||||
if (test1[j] != test2[j])
|
||||
if (test_key[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_map_remove64(hash_set, j);
|
||||
if (error)
|
||||
const errno_t error = hash_map_insert64(hash_set, j, test_val[j] = random_next(&random));
|
||||
if (error != EEXIST)
|
||||
{
|
||||
printf("Remove operation has failed! (error: %d)\n", error);
|
||||
printf("Insert operation has failed! (error: %d)\n", error);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (!(++spinner & 0x0F))
|
||||
@ -129,18 +268,110 @@ int test_function_1(hash_map64_t *const hash_set)
|
||||
}
|
||||
}
|
||||
|
||||
if (hash_map_size64(hash_set) != 0U)
|
||||
for (j = 0U; j < TEST_SIZE; ++j)
|
||||
{
|
||||
puts("Invalid size!");
|
||||
if (test_key[j])
|
||||
{
|
||||
if (!hash_map_get64(hash_set, j, &value))
|
||||
{
|
||||
if (value != test_val[j])
|
||||
{
|
||||
puts("Value mismatch has been detected!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
puts("Failed to retrieve the value!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hash_map_clear64(hash_set))
|
||||
{
|
||||
puts("Failed to clear the map!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
free(test1);
|
||||
free(test2);
|
||||
free(test_key);
|
||||
free(test_val);
|
||||
|
||||
PRINT_SET_INFO(2);
|
||||
puts("---------");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
/* TEST #3 */
|
||||
/* ========================================================================= */
|
||||
|
||||
#define VALUE(X) (((X) ^ UINT64_C(0xB7E151628AED2A6A)) * UINT64_C(65599))
|
||||
|
||||
int test_function_3(hash_map64_t *const hash_set)
|
||||
{
|
||||
size_t r, cursor, capacity, valid, deleted, limit;
|
||||
uint8_t spinner = 0U;
|
||||
clock_t last_update = clock();
|
||||
uint64_t key, value;
|
||||
|
||||
random_t random;
|
||||
random_init(&random);
|
||||
|
||||
for (r = 0U; r < 3U; ++r)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
const uint64_t rnd = random_next(&random) & UINT64_C(0x1FFFFFFFFFFFFFF);
|
||||
const errno_t error = hash_map_insert64(hash_set, rnd, VALUE(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! [0x%016" PRIX64 "]\n", rnd);
|
||||
cursor = 0U;
|
||||
while (!hash_map_iterate64(hash_set, &cursor, &key, &value))
|
||||
{
|
||||
if (value != VALUE(key))
|
||||
{
|
||||
puts("Value mismatch has been detected!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
puts("Value verification successful.");
|
||||
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_map_clear64(hash_set))
|
||||
{
|
||||
puts("Clear operation has failed!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
PRINT_SET_INFO(3);
|
||||
puts("---------");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -9,5 +9,7 @@
|
||||
#include <hash_map.h>
|
||||
|
||||
int test_function_1(hash_map64_t *const hash_set);
|
||||
int test_function_2(hash_map64_t *const hash_set);
|
||||
int test_function_3(hash_map64_t *const hash_set);
|
||||
|
||||
#endif /*_TEST_TESTS_INCLUDED*/
|
||||
|
@ -10,7 +10,7 @@ ALL_PATH := $(SRC_PATH) $(BIN_PATH)
|
||||
BIN_FILE := $(BIN_PATH)/test-hash-set$(EXE_SUFFIX)
|
||||
SRC_FILE := $(wildcard $(SRC_PATH)/*.c)
|
||||
|
||||
.PHONY: all build clean
|
||||
.PHONY: all build clean test
|
||||
|
||||
all: clean build
|
||||
|
||||
@ -24,3 +24,6 @@ $(ALL_PATH):
|
||||
|
||||
clean:
|
||||
rm -vf $(BIN_FILE)
|
||||
|
||||
test: build
|
||||
./$(BIN_FILE)
|
||||
|
@ -314,7 +314,7 @@ int test_function_3(hash_set64_t *const hash_set)
|
||||
else
|
||||
{
|
||||
PRINT_SET_INFO(3);
|
||||
printf("Collision detected! [%016" PRIx64 "]\n", rnd);
|
||||
printf("Collision detected! [0x%016" PRIX64 "]\n", rnd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user