Compare commits

...

40 Commits

Author SHA1 Message Date
36168c34aa Updated README file. 2022-12-06 15:15:46 +01:00
c6ecc3c813 Added build helper script for MacOS X. 2022-12-06 03:15:56 +01:00
e48efa984a Added missing line breaks. 2022-12-05 17:30:34 +01:00
da0321549d Explicitly set LD_LIBRARY_PATH (or PATH, if running on Windows) when invoking the test programs. 2022-12-05 15:44:56 +01:00
e5ea933f04 Fixed a circular dependency in Makefile. 2022-12-05 00:59:45 +01:00
6308ee1cd4 Fixed build on MacOS X. 2022-12-05 00:34:26 +01:00
661b9ce39b Return error EFBIG, if the set or map cannot grow any further because of the SIZE_MAX limit. 2022-12-04 22:57:29 +01:00
669bf3a28b hash_map_insert(): Added parameter 'update' to specify if the value of an existing key should be updated +
hash_map_remove(): Added parameter 'value' to return the value that was associated with the deleted key (optional).
2022-12-04 21:47:44 +01:00
f229c7ccfb Small improvement to Linux build script. 2022-12-04 19:40:02 +01:00
4983652ddf Added helper script for Linux and MinGW/Cygwin build. 2022-12-04 17:57:08 +01:00
91a714ac6e Updated README file. 2022-12-03 22:55:40 +01:00
d1cf093e76 Small improvement to map entry handling. 2022-12-03 22:44:14 +01:00
fb8ec13127 Updated README file. 2022-12-03 16:11:20 +01:00
04a3313116 MSVC: Exclude DllMain() function from the "static" library. 2022-12-03 15:47:15 +01:00
83911e9a5d Fixed a few warnings of MSVC at "EnableAllWarnings" level. 2022-12-03 15:42:31 +01:00
d43d9e98cf Fixed detection of Clang compiler on Windows platform. 2022-12-03 14:54:55 +01:00
30d981a6ff Fixed a few warnings of GCC at "-Wall" level. 2022-12-03 14:50:12 +01:00
a1d8935b2b Added DllMain() function to Windows "shared" library (DLL). 2022-12-03 02:24:58 +01:00
c57fce910e Small tweak to default load factor. 2022-12-02 16:28:52 +01:00
5eca7d7f17 Improved time source for test programs. 2022-12-02 15:16:54 +01:00
466a502adf Optimized hash computation. 2022-12-02 14:50:37 +01:00
89a93098d8 Small improvement to hash computation. 2022-12-02 01:40:50 +01:00
0e9434d939 Tweak the hash computation using an application-defined "seed" value. 2022-12-01 23:44:45 +01:00
3c513a66fc Fixed a warning. 2022-12-01 20:04:30 +01:00
bcd47ebe64 Updated README file. 2022-12-01 19:04:15 +01:00
b61e89cc5f Updated README file. 2022-12-01 18:37:11 +01:00
19a1c2ba47 Small code clean-up. 2022-12-01 16:53:36 +01:00
80d18e0fdb Some code clean-up. 2022-12-01 16:47:11 +01:00
40b4e2d5af Improved Makefiles to build the "shared" library (DLL). 2022-12-01 16:26:47 +01:00
82b16fb608 Added support for 16-Bit data types. 2022-12-01 16:06:12 +01:00
7c21bea6c2 Small improvement to hash-map tests. 2022-11-30 21:45:39 +01:00
4f2a13217c Simplified Makefiles. 2022-11-30 21:04:36 +01:00
58fdfcb573 Improved hash-map tests. 2022-11-30 20:42:52 +01:00
cb898fc8a6 Added separate test project for hash-map. 2022-11-30 16:41:14 +01:00
b49e1497bf Refactored the Makefiles. 2022-11-30 16:15:12 +01:00
3f197143f6 Added example program for hash map. 2022-11-30 15:41:29 +01:00
c4a98bfb48 Re-organized "example" and "test" projects. 2022-11-30 14:43:01 +01:00
aa8d45936c Map support has been implemented. 2022-11-29 21:30:19 +01:00
f431a0731a Added script to generate README file. 2022-11-29 18:10:04 +01:00
dfce864f16 Small correction to README file. 2022-11-29 17:35:03 +01:00
58 changed files with 3658 additions and 393 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@
/**/lib
/**/obj
/.vs
/out

View File

@ -1,16 +1,10 @@
SUBDIRS := libhashset example test
BUILD_ALL := $(patsubst %,build\:%,$(SUBDIRS))
CLEAN_ALL := $(patsubst %,clean\:%,$(SUBDIRS))
.PHONY: all clean $(SUBDIRS)
.PHONY: all clean $(BUILD_ALL) $(CLEAN_ALL)
all clean: $(SUBDIRS)
all: $(BUILD_ALL)
example test: libhashset
clean: $(CLEAN_ALL)
$(BUILD_ALL):
$(MAKE) -C $(patsubst build:%,%,$@)
$(CLEAN_ALL):
$(MAKE) -C $(patsubst clean:%,%,$@) clean
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)

593
README.md
View File

@ -1,11 +1,11 @@
Introduction
============
**LibHashSet** is a simple *hash set* implementation for C99. It uses open addressing and double hashing.
**LibHashSet** is a [*hash set*](https://en.wikipedia.org/wiki/Hash_table) and [*hash map*](https://en.wikipedia.org/wiki/Hash_table) implementation for C99. It uses open addressing and double hashing.
At this time, the *only* types of elements supported are `uint32_t` and `uint64_t`.
At this time, the *only* types of elements supported are `uint16_t`, `uint32_t` and `uint64_t`.
This hash set implementation has been tested to *efficiently* handle several billions of items 😏
This hash set implementation has successfully been tested to *efficiently* handle several billions of items 😏
Getting Started
@ -19,11 +19,11 @@ Here is a simple example of how to use LibHashSet in your application:
int main(void)
{
uint64_t value;
uint64_t item;
uintptr_t cursor = 0U;
/* create new hash set instance */
hash_set64_t* const hash_set = hash_set_create64(0U, -1.0);
hash_set64_t* const hash_set = hash_set_create64(0U, -1.0, 42U);
if (!hash_set)
{
fputs("Allocation has failed!\n", stderr);
@ -47,9 +47,9 @@ int main(void)
printf("Total number of items: %zu\n\n", hash_set_size64(hash_set));
/* print all items in the set */
while (hash_set_iterate64(hash_set, &cursor, &value) == 0)
while (hash_set_iterate64(hash_set, &cursor, &item) == 0)
{
printf("Item: %016llX\n", value);
printf("Item: %016llX\n", item);
}
/* destroy the hash set, when it is no longer needed! */
@ -62,25 +62,35 @@ int main(void)
API Reference
=============
This section describes the LibHashSet programming interface, as declared in the `<hash_set.h>` header file.
This section describes the LibHashSet programming interface. The functions for managing *hash sets* are declared in `<hash_set.h>`, whereas the functions for managing to *hash maps* are declared in `<hash_map.h>`.
LibHashSet supports sets containing values of type `uint32_t` or `uint64_t`. For each value type, separate functions are provided. The functions for `uint32_t`- and `uint64_t`-based hash sets can be distinguished by the suffix `…32` and `…64`, respectively. In the following, the functions are described in their "generic" (`value_t`) form.
LibHashSet supports sets and maps containing elements of different integral types. For each element type, separate functions are provided. The functions for `uint16_t`, `uint32_t` and `uint64_t` can be distinguished by the suffix `…16`, `…32` and `…64`, respectively. In the following, the functions are described in their "generic" form.
***Note:*** On Microsoft Windows, when using LibHashSet as a "shared" library (DLL), the macro `HASHSET_DLL` must be defined *before* including `<hash_set.h>`! This is **not** required or allowed when using the "static" library.
***Note:*** On Microsoft Windows (Visual C++), when using LibHashSet as a "shared" library (DLL file), the macro `HASHSET_DLL` must be defined *before* including the `<hash_set.h>` or `<hash_map.h>` header files!
Types
-----
### hash_set_t
A `struct` that represents a hash set instance. Instances can be allocated and de-allocated via the [hash_set_create()](#hash_set_create) and [hash_set_destroy()](#hash_set_destroy) functions, respectively.
A `struct` that represents a LibHashSet *hash set* instance. Hash set instances can be allocated and de-allocated via the [hash_set_create()](#hash_set_create) and [hash_set_destroy()](#hash_set_destroy) functions, respectively.
***Note:*** Application code shall treat this `struct` as opaque!
***Note:*** Application code shall treat this `struct` as opaque. The internals may change in future versions!
```C
typedef struct _hash_set hash_set_t;
```
### hash_map_t
A `struct` that represents a LibHashSet *hash map* instance. Hash map instances can be allocated and de-allocated via the [hash_map_create()](#hash_map_create) and [hash_map_destroy()](#hash_map_destroy) functions, respectively.
***Note:*** Application code shall treat this `struct` as opaque! The internals may change in future versions!
```C
typedef struct _hash_map hash_map_t;
```
Globals
-------
@ -103,8 +113,10 @@ extern const char *const HASHSET_BUILD_DATE;
extern const char *const HASHSET_BUILD_TIME;
```
Functions
---------
Set Functions
-------------
This section describes all functions for managing `hash_set_t` instances.
### hash_set_create()
@ -113,17 +125,21 @@ Allocates a new hash set instance. The new hash set instance is empty initially.
```C
hash_set_t *hash_set_create(
const size_t initial_capacity,
const double load_factor
const double load_factor,
const uint64_t seed
);
```
#### Parameters
* `initial_capacity`
The initial capacity of the hash set (number of values). The given value will be rounded to the next power of two. If the number of values (keys) to be inserted into the hash set can be estimated beforehand, then the initial capacity should be adjusted accordingly to avoid unnecessary re-allocations. In any case, the hash set will be able to grow dynamically as needed. If this parameter is set to *zero*, the the *default* initial capacity (8192) is used.
The initial capacity of the hash set (number of items). The given count will be rounded to the next power of two. If the number of items to be inserted into the hash set can be estimated beforehand, then the initial capacity should be adjusted accordingly to avoid unnecessary re-allocations. In any case, the hash set will be able to grow dynamically as needed. If this parameter is set to *zero*, the the *default* initial capacity (8192) is used.
* `load_factor`
The load factor to be applied to the hash set. The given value will be clipped to the **0.1** to **1.0** range. Generally, the default load factor (0.8) offers a good trade-off between performance and memory usage. Higher values decrease the memory overhead, but may increase the time required for insert/lookup operations when the hash set is almost completely filled. If this parameter is less than or equal to *zero*, the *default* load factor is used.
The load factor to be applied to the hash set. The given load factor will be clipped to the **0.1** to **1.0** range. Generally, the default load factor (0.75) offers a good trade-off between performance and memory usage. Higher load factors decrease the memory overhead, but also may increase the time required for insert, lookup and remove operations. If this parameter is less than or equal to *zero*, the *default* load factor is used.
* `seed`
The "seed" value that is used to tweak the internal hash computation. The application should set this parameter to a value that is hard to predict and that is unlikely to repeat (e.g., a high-resolution timer is suitable here).
#### Return value
@ -149,14 +165,14 @@ void hash_set_destroy(
### hash_set_insert()
Tries to insert the given value into the hash set. The operation fails, if the set already contains the given value.
Tries to insert the given item into the hash set. The operation fails, if the set already contains the given item.
***Note:*** If the value is actually inserted, then the hash set *may* need to grow.
***Note:*** If the item is actually inserted, then the hash set *may* need to grow.
```C
errno_t hash_set_insert(
hash_set_t *const instance,
const value_t value
const value_t item
);
```
@ -165,8 +181,8 @@ errno_t hash_set_insert(
* `instance`
A pointer to the hash set instance to be modified, as returned by the [hash_set_create()](#hash_set_create) function.
* `value`
The value (key) to be inserted into the hash set.
* `item`
The item to be inserted into the hash set.
#### Return value
@ -176,24 +192,27 @@ On success, this function returns *zero*. On error, the appropriate error code i
An invalid argument was given, e.g. `instance` was set to `NULL`.
* `EEXIST`
The given value (key) was *not* inserted into the hash set (again), because that value was already present.
The given item was *not* inserted into the hash set (again), because it was already present.
* `ENOMEM`
The value could *not* be inserted, because the required amount of memory could *not* be allocated.
The set failed to grow, because the required amount of memory could *not* be allocated (out of memory).
* `EFBIG`
The set needs to grow, but doing so would exceed the maximum size supported by the underlying system.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_set_remove()
Tries to remove the given value from the hash set. The operation fails, if the set does *not* contain the given value.
Tries to remove the given item from the hash set. The operation fails, if the set does *not* contain the given item.
***Note:*** If the value is actually removed, then the hash set *may* shrink.
***Note:*** If the item is actually removed, then the hash set *may* shrink.
```C
errno_t hash_set_remove(
hash_set_t *const instance,
const value_t value
const value_t item
);
```
@ -202,8 +221,8 @@ errno_t hash_set_remove(
* `instance`
A pointer to the hash set instance to be modified, as returned by the [hash_set_create()](#hash_set_create) function.
* `value`
The value (key) to be removed from the hash set.
* `item`
The item to be removed from the hash set.
#### Return value
@ -213,7 +232,7 @@ On success, this function returns *zero*. On error, the appropriate error code i
An invalid argument was given, e.g. `instance` was set to `NULL`.
* `ENOENT`
The given value (key) could *not* be removed from the hash set, because *no* such value was present.
The given item could *not* be removed from the hash set, because *no* such item was present.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
@ -247,12 +266,12 @@ On success, this function returns *zero*. On error, the appropriate error code i
### hash_set_contains()
Tests whether the hash set contains a value. The operation fails, if the set does *not* contain the given value.
Tests whether the hash set contains an item. The operation fails, if the set does *not* contain the given item.
```C
errno_t hash_set_contains(
const hash_set_t *const instance,
const value_t value
const value_t item
);
```
@ -261,8 +280,8 @@ errno_t hash_set_contains(
* `instance`
A pointer to the hash set instance to be examined, as returned by the [hash_set_create()](#hash_set_create) function.
* `value`
The value (key) to be searched in the hash set.
* `item`
The item to be searched in the hash set.
#### Return value
@ -272,24 +291,24 @@ On success, this function returns *zero*. On error, the appropriate error code i
An invalid argument was given, e.g. `instance` was set to `NULL`.
* `ENOENT`
The hash set does *not* contain the specified value (key).
The hash set does *not* contain the specified item.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_set_iterate()
Iterates through the values stored in the hash set. The elements are iterated in **no** particular order.
Iterates through the items stored in the hash set. The elements are iterated in **no** particular order.
This function returns one value at a time. It should be called repeatedly, until the end of the set is encountered.
This function returns one item at a time. It should be called *repeatedly*, until the end of the set is encountered.
***Warning:*** The result is undefined, if the set is modified while the iteration is in progress!
***Warning:*** The result is *undefined*, if the set is modified while the iteration is in progress!
```C
errno_t hash_set_iterate(
const hash_set_t *const instance,
uintptr_t *const cursor,
value_t *const value
size_t *const cursor,
value_t *const item
);
```
@ -299,12 +318,12 @@ errno_t hash_set_iterate(
A pointer to the hash set instance to be examined, as returned by the [hash_set_create()](#hash_set_create) function.
* `cursor`
A pointer to a variable of type `uintptr_t` where the current iterator state (position) is saved.
A pointer to a variable of type `size_t` where the current iterator state (position) is saved.
This variable **must** be initialized to the value `0U`, by the calling application, prior to the the *first* invocation!
Each invocation will update the value of `*cursor`; the value **shall not** be altered by the application.
Each invocation will update the value of `*cursor`. This value **shall not** be altered by the application.
* `value`
A pointer to a variable of type `uint32_t` or `uint64_t` where the next value in the set is stored on success.
* `item`
A pointer to a variable of type `value_t` where the next item in the set is stored on success.
The content of the variable should be considered *undefined*, if the invocation has failed.
#### Return value
@ -315,14 +334,14 @@ On success, this function returns *zero*. On error, the appropriate error code i
An invalid argument was given, e.g. `instance` was set to `NULL`.
* `ENOENT`
No more values. The end of the set has been encountered.
No more items. The end of the set has been encountered.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_set_size()
Returns the current number of values in the hash set.
Returns the current number of (distinct) items in the hash set.
```C
size_t hash_set_size(
@ -337,7 +356,7 @@ size_t hash_set_size(
#### Return value
This function returns the number of values in the hash set.
This function returns the number of (distinct) items in the hash set.
### hash_set_info()
@ -391,7 +410,7 @@ Dump the current status and content of all "slots" of the hash set.
```C
errno_t hash_set_dump(
const hash_set_t *const instance,
int (*callback)(const size_t index, const char status, const value_t value)
const hash_map_callback_t callback
);
```
@ -400,16 +419,19 @@ errno_t hash_set_dump(
* `instance`
A pointer to the hash set instance to be examined, as returned by the [hash_set_create()](#hash_set_create) function.
* `capacity`
A pointer to the callback function that will be invoked once for every "slot" of the hash set.
* `callback`
A pointer to the callback function that will be invoked once for every "slot" in the hash set.
The callback function is defined as follows:
```C
int callback(
typedef int (*hash_map_callback_t)(
const size_t index,
const char status,
const value_t key,
const value_t value
);
```
##### Parameters
* `index`
@ -421,8 +443,8 @@ errno_t hash_set_dump(
- `'v'` &ndash; the slot is *valid*
- `'d'` &ndash; the slot is *deleted*
* `value`
The value that is stored at the current "slot" index.
* `item`
The item that is stored at the current "slot" index.
##### Return value
@ -441,12 +463,473 @@ On success, this function returns *zero*. On error, the appropriate error code i
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
Map Functions
-------------
This section describes all functions for managing `hash_map_t` instances.
### hash_map_create()
Allocates a new hash map instance. The new hash map instance is empty initially.
```C
hash_map_t *hash_map_create(
const size_t initial_capacity,
const double load_factor,
const uint64_t seed
);
```
#### Parameters
* `initial_capacity`
The initial capacity of the hash map. The given count will be rounded to the next power of two. If the number of key-value pairs to be inserted into the hash map can be estimated beforehand, then the initial capacity should be adjusted accordingly to avoid unnecessary re-allocations. In any case, the hash map will be able to grow dynamically as needed. If this parameter is map to *zero*, the the *default* initial capacity (8192) is used.
* `load_factor`
The load factor to be applied to the hash map. The given load factor will be clipped to the **0.1** to **1.0** range. Generally, the default load factor (0.75) offers a good trade-off between performance and memory usage. Higher load factors decrease the memory overhead, but also may increase the time required for insert, lookup and remove operations. If this parameter is less than or equal to *zero*, the *default* load factor is used.
* `seed`
The "seed" value that is used to tweak the internal hash computation. The application should set this parameter to a value that is hard to predict and that is unlikely to repeat (e.g., a high-resolution timer is suitable here).
#### Return value
On success, this function returns a pointer to a new hash map instance. On error, a `NULL` pointer is returned.
***Note:*** To avoid a memory leak, the returned pointer must be de-allocated by the application using the [hash_map_destroy()](#hash_map_destroy) function, as soon as the instance is *not* needed anymore!
### hash_map_destroy()
De-allocates an existing hash map instance. All key-value pairs in the hash map are discarded.
```C
void hash_map_destroy(
hash_map_t *instance
);
```
#### Parameters
* `instance`
A pointer to the hash map instance that is to be destroyed, as returned by the [hash_map_create()](#hash_map_create) function.
***Note:*** The given pointer is *invalidated* by this function, and it **must not** be used afterwards!
### hash_map_insert()
Tries to insert the given key-value pair into the hash map.
***Note:*** If the key is actually inserted, then the hash map *may* need to grow.
```C
errno_t hash_map_insert(
hash_map_t *const instance,
const value_t key,
const value_t value,
const int update
);
```
#### Parameters
* `instance`
A pointer to the hash map instance to be modified, as returned by the [hash_map_create()](#hash_map_create) function.
* `key`
The key to be inserted into the hash map.
* `value`
The value to be associated with the given key.
* `update`
If the map already contains the specified key, then if this parameter is *non-zero*, the value associated with the existing key will be updated; otherwise, the value currently associated with key remains unchanged.
#### Return value
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
* `EINVAL`
An invalid argument was given, e.g. `instance` was map to `NULL`.
* `EEXIST`
The given key was *not* inserted into the hash map (again), because it was already present.
Nonetheless, if `update` was non-zero, the value associated with the existing key has been updated.
* `ENOMEM`
The map failed to grow, because the required amount of memory could *not* be allocated (out of memory).
* `EFBIG`
The map needs to grow, but doing so would exceed the maximum size supported by the underlying system.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_map_remove()
Tries to remove the given key from the hash map. The operation fails, if the map does *not* contain the given key.
The value associated with the removed key is discarded.
***Note:*** If the key is actually removed, then the hash map *may* shrink.
```C
errno_t hash_map_remove(
hash_map_t *const instance,
const value_t key,
value_t *const value
);
```
#### Parameters
* `instance`
A pointer to the hash map instance to be modified, as returned by the [hash_map_create()](#hash_map_create) function.
* `key`
The key to be removed from the hash map.
* `value`
A pointer to a variable of type `value_t` where the value that was associated with the deleted key is stored.
The content of the variable should be considered *undefined*, if the key could *not* be removed.
***Note:*** This parameter can be set to `NULL`, in which case the value will *not* be reported to the application.
#### Return value
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
* `EINVAL`
An invalid argument was given, e.g. `instance` was map to `NULL`.
* `ENOENT`
The given key could *not* be removed from the hash map, because *no* such key was present.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_map_clear()
Discards *all* key-value pairs from the hash map at once.
```C
errno_t hash_map_clear(
hash_map_t *const instance
);
```
#### Parameters
* `instance`
A pointer to the hash map instance to be modified, as returned by the [hash_map_create()](#hash_map_create) function.
#### Return value
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
* `EINVAL`
An invalid argument was given, e.g. `instance` was map to `NULL`.
* `EAGAIN`
The hash map was *not* cleared, because it already was empty. Please try again later!
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_map_contains()
Tests whether the hash map contains a key. The operation fails, if the map does *not* contain the given key.
```C
errno_t hash_map_contains(
const hash_map_t *const instance,
const value_t key
);
```
#### Parameters
* `instance`
A pointer to the hash map instance to be examined, as returned by the [hash_map_create()](#hash_map_create) function.
* `key`
The key to be searched in the hash map.
#### Return value
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
* `EINVAL`
An invalid argument was given, e.g. `instance` was map to `NULL`.
* `ENOENT`
The hash map does *not* contain the specified key.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_map_get()
Retrieves the value that is associated with the given key. The operation fails, if the map does *not* contain the key.
```C
errno_t hash_map_get(
const hash_map_t *const instance,
const value_t key,
value_t *const value
);
```
#### Parameters
* `instance`
A pointer to the hash map instance to be examined, as returned by the [hash_map_create()](#hash_map_create) function.
* `key`
The key to be searched in the hash map.
* `value`
A pointer to a variable of type `value_t` where the value associated with the key is stored on success.
The content of the variable should be considered *undefined*, if the invocation has failed.
#### Return value
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
* `EINVAL`
An invalid argument was given, e.g. `instance` was map to `NULL`.
* `ENOENT`
The hash map does *not* contain the specified key.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_map_iterate()
Iterates through the key-value pairs stored in the hash map. The entries are iterated in **no** particular order.
This function returns one key-value pair at a time. It should be called *repeatedly*, until the end of the map is encountered.
***Warning:*** The result is *undefined*, if the map is modified while the iteration is in progress!
```C
errno_t hash_map_iterate(
const hash_map_t *const instance,
size_t *const cursor,
value_t *const key,
value_t *const value
);
```
#### Parameters
* `instance`
A pointer to the hash map instance to be examined, as returned by the [hash_map_create()](#hash_map_create) function.
* `cursor`
A pointer to a variable of type `size_t` where the current iterator state (position) is saved.
This variable **must** be initialized to the value `0U`, by the calling application, prior to the the *first* invocation!
Each invocation will update the value of `*cursor`. This value **shall not** be altered by the application.
* `key`
A pointer to a variable of type `value_t` where the next key in the map is stored on success.
The content of the variable should be considered *undefined*, if the invocation has failed.
* `value`
A pointer to a variable of type `value_t` where the next value in the map is stored on success.
The content of the variable should be considered *undefined*, if the invocation has failed.
#### Return value
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
* `EINVAL`
An invalid argument was given, e.g. `instance` was map to `NULL`.
* `ENOENT`
No more entries. The end of the map has been encountered.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_map_size()
Returns the current number of (distinct) keys in the hash map.
```C
size_t hash_map_size(
const hash_map_t *const instance
);
```
#### Parameters
* `instance`
A pointer to the hash map instance to be examined, as returned by the [hash_map_create()](#hash_map_create) function.
#### Return value
This function returns the number of (distinct) keys in the hash map.
### hash_map_info()
Returns technical information about the hash map.
```C
errno_t hash_map_info(
const hash_map_t *const instance,
size_t *const capacity,
size_t *const valid,
size_t *const deleted,
size_t *const limit
);
```
#### Parameters
* `instance`
A pointer to the hash map instance to be examined, as returned by the [hash_map_create()](#hash_map_create) function.
* `capacity`
A pointer to a variable of type `size_t` where the current total *capacity* of the hash map is stored.
This value will always be greater than or equal to the sum of the *valid* and *deleted* entries.
* `valid`
A pointer to a variable of type `size_t` where the current number of *valid* entries in the hash map is stored.
This value is equivalent to the return value of the [hash_map_size()](#hash_map_size) function.
* `deleted`
A pointer to a variable of type `size_t` where the current number of *deleted* entries in the hash map is stored.
For technical reasons, entires are *not* removed from the map immediately, but are marked as "deleted".
* `limit`
A pointer to a variable of type `size_t` where the current "grow" *limit* of the hash map is stored.
The hash map is grown automatically, as soon as the sum of the *valid* and *deleted* entries exceeds this limit.
#### Return value
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
* `EINVAL`
An invalid argument was given, e.g. `instance` was map to `NULL`.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
### hash_map_dump()
Dump the current status and content of all "slots" of the hash map.
```C
errno_t hash_map_dump(
const hash_map_t *const instance,
const hash_map_callback_t callback
);
```
#### Parameters
* `instance`
A pointer to the hash map instance to be examined, as returned by the [hash_map_create()](#hash_map_create) function.
* `callback`
A pointer to the callback function that will be invoked once for every "slot" in the hash map.
The callback function is defined as follows:
```C
typedef int (*hash_map_callback_t)(
const size_t index,
const char status,
const value_t key,
const value_t value
);
```
##### Parameters
* `index`
The index of the current "slot" within the hash map.
* `status`
Indicates the status of the current "slot":
- `'u'` &ndash; the slot is *unused*
- `'v'` &ndash; the slot is *valid*
- `'d'` &ndash; the slot is *deleted*
* `key`
The key that is stored at the current "slot" index.
* `value`
The value that is stored at the current "slot" index.
##### Return value
If the function returns a *non-zero* value, the iteration continues; otherwise it is cancelled.
#### Return value
On success, this function returns *zero*. On error, the appropriate error code is returned. Possible error codes include:
* `EINVAL`
An invalid argument was given, e.g. `instance` was map to `NULL`.
* `ECANCELED`
The operation was cancelled by the calling application.
* `EFAULT`
Something else went wrong. This usually indicates an internal error and is *not* supposed to happen.
Thread Safety
-------------
LibHashSet is ***thread-safe***, in the sense that all public functions operate *exclusively* on the given `hash_set_t` instance; there is **no** implicit shared "global" state. This means that **no** synchronization is required in multi-threaded applications, provided that each `hash_set_t` instance is created and accessed only by a *single* thread.
LibHashSet is ***thread-safe***, in the sense that all public functions operate *exclusively* on the given `hash_set_t` or `hash_map_t` instance; there is **no** implicit shared "global" state. This means that **no** synchronization is required in multi-threaded applications, provided that each instance is created and accessed only by a ***single*** thread.
However, LibHashSet does ***nothing*** to synchronize access to a particular `hash_set_t` instance! Consequently, in situations where the *same* `hash_set_t` instance needs to be shared across *multiple* concurrent threads, the calling application is responsible for serializing all access to the "shared" instance, e.g. by using a [*mutex*](https://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_mutex_lock.html) lock!
However, LibHashSet does **nothing** to synchronize access to a particular `hash_set_t` or `hash_map_t` instance! Consequently, in situations where the *same* instance needs to be shared across *multiple* concurrent threads, the calling application is responsible for serializing all access to the "shared" instance, e.g. by using a [*mutex*](https://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_mutex_lock.html) lock!
Source Code
===========
The "official" Git repository is mirrored at:
* `git clone https://github.com/lordmulder/HashSet.git` ([Browse](https://github.com/lordmulder/HashSet))
* `git clone https://gitlab.com/lord_mulder/libhashset.git` ([Browse](https://gitlab.com/lord_mulder/libhashset))
* `git clone https://repo.or.cz/HashSet.git` ([Browse](https://repo.or.cz/HashSet.git))
* `git clone https://punkindrublic.mooo.com:3000/Muldersoft/LibHashSet.git` ([Browse](https://punkindrublic.mooo.com:3000/Muldersoft/LibHashSet))
Build Instructions
==================
This section describes how to build LibHashSet from the source codes.
Windows
-------
On Microsoft Windows, project/solution files are provided to build LibHashSet with [Microsoft Visual Studio](https://visualstudio.microsoft.com/).
LibHashSet also can be built using *GCC* or *Clang* via [MSYS2/Mingw-w64](https://www.msys2.org/) or [Cygwin](https://www.cygwin.com/). Be sure that *GCC* (or *Clang*) and *GNU make* are installed. Then run `make` from the project base directory, in the MSYS2 (or Cygwin) shell!
Linux, &#42;BSD and MacOS X
---------------------------
On Linux, &#42;BSD or MacOS X, building LibHashSet with *GCC* or *Clang* is supported. *GNU make* is required to build.
Simply run `make` (or `gmake`, if on &#42;BSD) from the project base directory. That's it!
### Influential environment variables
The following environment variables can be used to control the build process:
* `CC` &ndash; specifies the C compiler (default is `cc`)
* `STRIP` &ndash; set to a non-zero value in order to *strip* the generated binaries
* `STATIC` &ndash; set to a non-zero value in order to enable *static* linking for the example/test programs
* `FLTO` &ndash; set to a non-zero value in order to enable *link-time optimizer* (`-flto`)
* `DEBUG` &ndash; set to a non-zero value in order to enable "debug" build
* `ASAN` &ndash; set to a non-zero value in order to enable the [address-sanitizer](https://en.wikipedia.org/wiki/AddressSanitizer)
License

66
config.mk Normal file
View File

@ -0,0 +1,66 @@
UNAME := $(strip $(shell uname))
ifeq ($(UNAME),)
$(error Operating system could not be detected!)
endif
DUMPMACHINE := $(strip $(shell $(CC) -dumpmachine))
ifeq ($(DUMPMACHINE),)
$(error C compiler could not be detected!)
endif
ifneq ($(DEBUG),)
XCFLAGS = -Og -g
else
ifneq ($(ASAN),)
XCFLAGS = -O1 -g -fsanitize=address -fno-omit-frame-pointer
XLDFLAGS += -static-libasan
else
XCFLAGS = -Ofast -DNDEBUG
endif
endif
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 ($(firstword $(filter %-mingw32 %-windows-gnu %-cygwin,$(DUMPMACHINE))),)
DLL_LDFLAGS = -shared -Wl,--out-implib,$@.a
EXE_SUFFIX := .exe
DLL_SUFFIX := .dll
ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),)
XLDFLAGS += -Wl,--large-address-aware
endif
else
ifneq ($(findstring -apple-darwin,$(DUMPMACHINE)),)
DLL_LDFLAGS = -dynamiclib
DLL_SUFFIX := .dylib
else
DLL_LDFLAGS = -shared
DLL_SUFFIX := .so
endif
endif
ifneq ($(STATIC),)
XLDFLAGS += -static
endif
ifneq ($(FLTO),)
XCFLAGS += -flto
endif
ifneq ($(STRIP),)
XLDFLAGS += -Wl,--strip-all
DLL_LDFLAGS += -Wl,--strip-all
endif
ifneq ($(firstword $(filter MINGW32_NT-% MINGW64_NT-% CYGWIN_NT-%,$(UNAME))),)
ENV_LDPATH := PATH
else
ifneq ($(firstword $(UNAME)),Darwin)
ENV_LDPATH := LD_LIBRARY_PATH
else
ENV_LDPATH := DYLD_LIBRARY_PATH
endif
endif

1
etc/style/gh-pandoc.min.css vendored Normal file

File diff suppressed because one or more lines are too long

21
etc/utils/build-cygwin.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
set -e
cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.."
mkdir -pv "out/_next/include"
cp -rfv "libhashset/include/"*.h "out/_next/include"
target="$(gcc -dumpmachine)"
echo -e "--------------------------------\n${target}\n--------------------------------"
make CC="gcc" STATIC=1 STRIP=1
rm -rf "out/_next/lib/${target}" "out/_next/bin/${target}"
mkdir -pv "out/_next/lib/${target}" "out/_next/bin/${target}"
cp -rv "libhashset/lib/"* "out/_next/lib/${target}"
for i in example test; do
for j in hash-set hash-map; do
cp -fv "${i}/${j}/bin/${i}-${j}.exe" "out/_next/bin/${target}"
done
done
[ "$(uname -o | tr 'A-Z' 'a-z')" == "cygwin" ] && \
cp -fv "$(which cygwin1.dll)" "out/_next/bin/${target}" || true

46
etc/utils/build-linux.sh Executable file
View File

@ -0,0 +1,46 @@
#!/bin/bash
set -e
cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.."
readonly mode="${1,,}"
if [[ "${mode}" != "gnu" && "${mode}" != "musl" ]]; then
echo "Error: Parameter must be either \"gnu\" or \"musl\" !!!"
exit 1
fi
rm -rf "out"
mkdir -pv "out/include"
cp -rfv "libhashset/include/"*.h "out/include"
case "${mode}" in
gnu)
for cpu in i686 x86_64 aarch64; do
compiler="${cpu}-linux-gnu-gcc"
target="$("${compiler}" -dumpmachine)"
echo -e "--------------------------------\n${target}\n--------------------------------"
make CC="${compiler}" STRIP=1
mkdir -pv "out/lib/${target}" "out/bin/${target}"
cp -rv "libhashset/lib/"* "out/lib/${target}"
for i in example test; do
for j in hash-set hash-map; do
cp -fv "${i}/${j}/bin/${i}-${j}" "out/bin/${target}"
done
done
done
;;
musl)
for cpu in i686 x86_64 arm64; do
compiler="/usr/local/musl/${cpu}/bin/musl-gcc"
target="$("${compiler}" -dumpmachine | sed 's/-gnu/-musl/i')"
echo -e "--------------------------------\n${target}\n--------------------------------"
make CC="${compiler}" STATIC=1 STRIP=1
mkdir -pv "out/lib/${target}" "out/bin/${target}"
cp -rv "libhashset/lib/"* "out/lib/${target}"
for i in example test; do
for j in hash-set hash-map; do
cp -fv "${i}/${j}/bin/${i}-${j}" "out/bin/${target}"
done
done
done
;;
esac

19
etc/utils/build-macos.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/zsh
set -e
cd -- "${0:a:h}/../../"
mkdir -pv "out/include"
cp -rfv "libhashset/include/"*.h "out/include"
for cpu in x86_64 aarch64; do
target="${cpu}-apple-darwin"
echo -e "--------------------------------\n${target}\n--------------------------------"
make CC="cc -target ${target}"
mkdir -pv "out/lib/${target}" "out/bin/${target}"
cp -rv "libhashset/lib/"* "out/lib/${target}"
for i in example test; do
for j in hash-set hash-map; do
cp -fv "${i}/${j}/bin/${i}-${j}" "out/bin/${target}"
done
done
done

View File

@ -0,0 +1,9 @@
@echo off
cd /d "%~dp0..\.."
set "MSYS2_DIR=C:\msys64"
call "%MSYS2_DIR%\msys2_shell.cmd" -mingw32 -no-start -defterm -where "%CD%" -c "./etc/utils/build-cygwin.sh"
call "%MSYS2_DIR%\msys2_shell.cmd" -mingw64 -no-start -defterm -where "%CD%" -c "./etc/utils/build-cygwin.sh"
pause

View File

@ -1,52 +1,8 @@
DUMPMACHINE := $(shell $(CC) -dumpmachine)
SUBDIRS := hash-set hash-map
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
.PHONY: all clean test $(SUBDIRS)
ifneq ($(firstword $(filter %-mingw32 %-cygwin,$(DUMPMACHINE))),)
EXE_SUFFIX := .exe
ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),)
XCFLAGS += -Wl,--large-address-aware
endif
endif
all clean test: $(SUBDIRS)
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)
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)

24
example/hash-map/Makefile Normal file
View File

@ -0,0 +1,24 @@
include ../../config.mk
CFLAGS = -std=c99 -D_DEFAULT_SOURCE -Wall -Wpedantic -I../../libhashset/include $(XCFLAGS)
LDFLAGS = -L../../libhashset/lib -lhashset-1 $(XLDFLAGS)
SRC_PATH := src
BIN_PATH := bin
ALL_PATH := $(SRC_PATH) $(BIN_PATH)
BIN_FILE := $(BIN_PATH)/example-hash-map$(EXE_SUFFIX)
SRC_FILE := $(wildcard $(SRC_PATH)/*.c)
.PHONY: all clean test
all test: clean $(ALL_PATH) $(BIN_FILE)
$(BIN_FILE): $(SRC_FILE)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
$(ALL_PATH):
mkdir -p $@
clean:
rm -vf $(BIN_FILE)

View File

@ -39,26 +39,24 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\input.c" />
<ClCompile Include="src\main.c" />
<ClCompile Include="src\random.c" />
<ClCompile Include="src\tests.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\libhashset\libhashset.vcxproj">
<ClInclude Include="src\input.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\libhashset\libhashset.vcxproj">
<Project>{8cf3bd19-28b1-435d-b719-e00b052dfc3a}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\random.h" />
<ClInclude Include="src\tests.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{0b7abb95-b60f-418b-8386-930b1629058f}</ProjectGuid>
<RootNamespace>hashset-test</RootNamespace>
<ProjectGuid>{C703A94D-2755-40AD-A8D4-C169E14DCF5F}</ProjectGuid>
<RootNamespace>example-hash-map</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
<ProjectName>hashset-test</ProjectName>
<ProjectName>example-hash-map</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -201,11 +199,13 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -217,7 +217,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -234,6 +234,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -243,14 +245,12 @@
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.1</MinimumRequiredVersion>
<LargeAddressAware>true</LargeAddressAware>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -267,6 +267,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -276,8 +278,6 @@
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.1</MinimumRequiredVersion>
<LargeAddressAware>true</LargeAddressAware>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
<PostBuildEvent>
@ -289,11 +289,13 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -304,11 +306,13 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -318,7 +322,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -334,6 +338,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -342,14 +348,12 @@
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.2</MinimumRequiredVersion>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -365,6 +369,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -372,14 +378,12 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -395,6 +399,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -403,8 +409,6 @@
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.2</MinimumRequiredVersion>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
<PostBuildEvent>
@ -416,7 +420,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -432,6 +436,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -439,8 +445,6 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
<PostBuildEvent>

View File

@ -0,0 +1,76 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#include "input.h"
#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0U]))
#define MINIMUM(X,Y) (((X) < (Y)) ? (X) : (Y))
/* ========================================================================= */
/* I/O Functions */
/* ========================================================================= */
static const uint64_t INPUT_KEYS[] =
{
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 const uint64_t INPUT_VALUES[] =
{
UINT64_C(0xE0359D7D27190470), UINT64_C(0x6A8B8F75240A606C), UINT64_C(0x1E0DB534262646E7), UINT64_C(0xFD79E3AA64A2774E), UINT64_C(0x010324B945C7DA9E),
UINT64_C(0x5248593526FDF636), UINT64_C(0x616C6381A68AD5D2), UINT64_C(0x567760F9D1A41240), UINT64_C(0x107AE9902BD79DF3), UINT64_C(0x180565321506BC12),
UINT64_C(0x93C190B7B4C690B7), UINT64_C(0x021CECCD4CC37F4E), UINT64_C(0xA730203BEBF9E4D5), UINT64_C(0x6843C5BFFF5F0029), UINT64_C(0xA049B07E88876973),
UINT64_C(0xAB835AAB4A21CF62), UINT64_C(0x4A167077B6B1B540), UINT64_C(0xF0513939D4BB09C7), UINT64_C(0x171E212B6BFE3CC6), UINT64_C(0x75391B09F3E8073F),
UINT64_C(0x9EA4B0561CF36216), UINT64_C(0xC2E2EAA1763DB240), UINT64_C(0xBE7329DB422CB870), UINT64_C(0x747A0119733A6678), UINT64_C(0x80D47F93E07AEA14),
UINT64_C(0x7C213D7D6C45692E), UINT64_C(0x78D344C281625298), UINT64_C(0xA3702E83B09D09EC), UINT64_C(0x8A2E4CBCB5854C9A), UINT64_C(0x7C5D14775EA29F19),
UINT64_C(0xF8E8367157E71126), UINT64_C(0x1A23EB25A1EB2F5E), UINT64_C(0x3950A676B29C5168), UINT64_C(0x0D841DE0570B4BCD), UINT64_C(0x9D2EFF1E00F0CAA1),
UINT64_C(0x805A7DB68B0BD1E9), UINT64_C(0x257122C35CCA2C4A), UINT64_C(0xA6014DB72C54C6B3), UINT64_C(0x56381789F58629F7), UINT64_C(0x5B73293145C3ECFD),
UINT64_C(0xE38B60A19F9F66DC), UINT64_C(0xCE2F1F9A4F0A2B9C), UINT64_C(0xD7BEB6E08E3D1CAE), UINT64_C(0x94CCEE57F5E987AD), UINT64_C(0x2AE0D325CA31CE67),
UINT64_C(0x296763D4011FE85E), UINT64_C(0x1758779DA1AD3EE9), UINT64_C(0x6D9E6C88EDE24333), UINT64_C(0xAA4D0B75B95D0B87), UINT64_C(0x6C44E1B8BB601769),
UINT64_C(0xF2BCEBD8E7CBE458), UINT64_C(0xEE8AEF528886EB2B), UINT64_C(0x8468C256C2C1ABE8), UINT64_C(0x15D71B47ADF3A068), UINT64_C(0xB3678DEC66A855B2),
UINT64_C(0x47724D7B0DD806E1), UINT64_C(0xE19BF73125B028FD), UINT64_C(0xF1597C7F2C2ED5FF), UINT64_C(0xB22D9DC7FAD6FE0E), UINT64_C(0x4508DB9A9BDB545B),
UINT64_C(0x6450AFC649347952), UINT64_C(0x58D19E1C39A76284), UINT64_C(0x5A3ED68E33B34DB6), UINT64_C(0x0514B87BA3BC46AD), UINT64_C(0xFFE9C5CC1BC8DC3B),
UINT64_C(0xD4342CA8BA80B88F), UINT64_C(0x1E943E872C760875), UINT64_C(0x74B67F3F010A4EE0), UINT64_C(0x5DC7F60598468608), UINT64_C(0x1A8D0AFC0EDBEEDE),
UINT64_C(0xD1C5038CB00E5797), UINT64_C(0x32F54E47C7CDDFF8), UINT64_C(0x9C3BFD89909638CF), UINT64_C(0xF7CEB89A9A5694A8), UINT64_C(0x0B08DBC73FCDCAA8),
UINT64_C(0x3B0A8A70937F2C83), UINT64_C(0xD9336A333909473D), UINT64_C(0x8981D0E8582A159E), UINT64_C(0x1EDB1D67114D0B60), UINT64_C(0xB34F04B1A91FE2C8),
UINT64_C(0xB165B7EAEA63981E), UINT64_C(0xB60C653D40FAEC9E), UINT64_C(0x6D49BC1AA59D15D3), UINT64_C(0x44829E6CD50292F8), UINT64_C(0xDFF648A8A584435D),
UINT64_C(0x3C285E7E252BB536), UINT64_C(0xE559AEF6AAF055CA), UINT64_C(0xDEA7ED70CF4CB9F0), UINT64_C(0xD99AAB38FC839CA2), UINT64_C(0x446AFF8DD57AE1F6),
UINT64_C(0xE41ECE48B14E57C8), UINT64_C(0x35ED1D10689E16F7), UINT64_C(0x94D200DEBFC9A34D), UINT64_C(0x2EBECCABA278C71F), UINT64_C(0x152AB2E31BE7B630),
UINT64_C(0xC0AA1A102A24DBD9), UINT64_C(0x7CCAAA448391C9B1), UINT64_C(0xC7109A86B8AA7A2C), UINT64_C(0x9C42009B6F56CE0A), UINT64_C(0xA3C3AE98F226B08D)
};
int have_more_items(const size_t offset)
{
return offset < MINIMUM(ARRAY_SIZE(INPUT_KEYS), ARRAY_SIZE(INPUT_VALUES));
}
pair_t get_next_item(const size_t offset)
{
if (offset < MINIMUM(ARRAY_SIZE(INPUT_KEYS), ARRAY_SIZE(INPUT_VALUES)))
{
return (pair_t) { INPUT_KEYS[offset], INPUT_VALUES[offset] };
}
return (pair_t) { 0U, 0U };
}

View File

@ -0,0 +1,22 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#ifndef _EXAMPLE_INPUT_INCLUDED
#define _EXAMPLE_INPUT_INCLUDED
#include <stdlib.h>
#include <stdint.h>
typedef struct
{
uint64_t key;
uint64_t value;
}
pair_t;
int have_more_items(const size_t offset);
pair_t get_next_item(const size_t offset);
#endif /*_EXAMPLE_INPUT_INCLUDED*/

View File

@ -0,0 +1,60 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#include <hash_map.h>
#include <stdio.h>
#include <inttypes.h>
#include "input.h"
/* ========================================================================= */
/* MAIN */
/* ========================================================================= */
int main(void)
{
hash_map64_t *hash_map;
uint64_t key, value;
size_t cursor = 0U, offset = 0U;
/* print logo */
printf("LibHashSet Hash-Map Example v%" PRIu16 ".%" PRIu16 ".%" PRIu16 " [%s]\n\n",
HASHSET_VERSION_MAJOR, HASHSET_VERSION_MINOR, HASHSET_VERSION_PATCH, HASHSET_BUILD_DATE);
/* create new hash map instance */
hash_map = hash_map_create64(0U, -1.0, 42U);
if (!hash_map)
{
fputs("Allocation has failed!\n", stderr);
return EXIT_FAILURE;
}
/* add a number of items to the hash map, the map will grow as needed */
puts("Inserting key-value pairs into hash map, please wait...");
while (have_more_items(offset))
{
const pair_t input = get_next_item(offset++);
const errno_t error = hash_map_insert64(hash_map, input.key, input.value, 1);
if (error)
{
fprintf(stderr, "Insert operation failed! (error: %d)\n", error);
return EXIT_FAILURE;
}
}
puts("Done.\n");
/* print total number of items in the hash map */
printf("Total number of entries in the map: %zu\n\n", hash_map_size64(hash_map));
/* print all items in the map */
while (hash_map_iterate64(hash_map, &cursor, &key, &value) == 0)
{
printf("Entry: 0x%016" PRIX64 " -> 0x%016" PRIX64 "\n", key, value);
}
puts("");
/* destroy the hash map, when it is no longer needed! */
hash_map_destroy64(hash_map);
return EXIT_SUCCESS;
}

24
example/hash-set/Makefile Normal file
View File

@ -0,0 +1,24 @@
include ../../config.mk
CFLAGS = -std=c99 -D_DEFAULT_SOURCE -Wall -Wpedantic -I../../libhashset/include $(XCFLAGS)
LDFLAGS = -L../../libhashset/lib -lhashset-1 $(XLDFLAGS)
SRC_PATH := src
BIN_PATH := bin
ALL_PATH := $(SRC_PATH) $(BIN_PATH)
BIN_FILE := $(BIN_PATH)/example-hash-set$(EXE_SUFFIX)
SRC_FILE := $(wildcard $(SRC_PATH)/*.c)
.PHONY: all clean test
all test: clean $(ALL_PATH) $(BIN_FILE)
$(BIN_FILE): $(SRC_FILE)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
$(ALL_PATH):
mkdir -p $@
clean:
rm -vf $(BIN_FILE)

View File

@ -43,20 +43,20 @@
<ClCompile Include="src\main.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\libhashset\libhashset.vcxproj">
<Project>{8cf3bd19-28b1-435d-b719-e00b052dfc3a}</Project>
</ProjectReference>
<ClInclude Include="src\input.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\input.h" />
<ProjectReference Include="..\..\libhashset\libhashset.vcxproj">
<Project>{8cf3bd19-28b1-435d-b719-e00b052dfc3a}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{8FB9B9DE-DC49-4224-892B-589422484766}</ProjectGuid>
<RootNamespace>hashset-example</RootNamespace>
<RootNamespace>example-hash-set</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
<ProjectName>hashset-example</ProjectName>
<ProjectName>example-hash-set</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -199,11 +199,13 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -215,7 +217,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -232,6 +234,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -246,7 +250,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -263,6 +267,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -283,11 +289,13 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -298,11 +306,13 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -312,7 +322,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -328,6 +338,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -341,7 +353,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -357,6 +369,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -369,7 +383,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -385,6 +399,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -404,7 +420,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -420,6 +436,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)\libhashset\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\input.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\input.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -32,7 +32,7 @@ static const uint64_t INPUT_DATA[] =
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),
UINT64_C(0x85CB5DBD53986A64), UINT64_C(0x7C66F5CD3E46FDB7), UINT64_C(0xE863F4436E8BD7F8), UINT64_C(0x82496CD067153344), UINT64_C(0x863F1F732CE3751E)
};
int have_more_items(const size_t offset)

View File

@ -15,16 +15,15 @@
int main(void)
{
hash_set64_t *hash_set;
uint64_t value;
uintptr_t cursor = 0U;
size_t offset = 0U;
uint64_t item;
size_t cursor = 0U, offset = 0U;
/* print logo */
printf("LibHashSet Example v%" PRIu16 ".%" PRIu16 ".%" PRIu16 " [%s]\n\n",
printf("LibHashSet Hash-Set Example v%" PRIu16 ".%" PRIu16 ".%" PRIu16 " [%s]\n\n",
HASHSET_VERSION_MAJOR, HASHSET_VERSION_MINOR, HASHSET_VERSION_PATCH, HASHSET_BUILD_DATE);
/* create new hash set instance */
hash_set = hash_set_create64(0U, -1.0);
hash_set = hash_set_create64(0U, -1.0, 42U);
if (!hash_set)
{
fputs("Allocation has failed!\n", stderr);
@ -48,10 +47,11 @@ int main(void)
printf("Total number of items in the set: %zu\n\n", hash_set_size64(hash_set));
/* print all items in the set */
while (hash_set_iterate64(hash_set, &cursor, &value) == 0)
while (hash_set_iterate64(hash_set, &cursor, &item) == 0)
{
printf("Item: 0x%016" PRIX64 "\n", value);
printf("Item: 0x%016" PRIX64 "\n", item);
}
puts("");
/* destroy the hash set, when it is no longer needed! */
hash_set_destroy64(hash_set);

View File

@ -3,11 +3,19 @@ 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\hash-set-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\test-hash-set.vcxproj", "{0B7ABB95-B60F-418B-8386-930B1629058F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example-hash-map", "example\hash-map\hash-map-example.vcxproj", "{C703A94D-2755-40AD-A8D4-C169E14DCF5F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-hash-map", "test\hash-map\test-hash-map.vcxproj", "{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -22,24 +30,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 +66,70 @@ 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
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Debug|ARM64.ActiveCfg = Debug|ARM64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Debug|ARM64.Build.0 = Debug|ARM64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Debug|x64.ActiveCfg = Debug|x64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Debug|x64.Build.0 = Debug|x64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Debug|x86.ActiveCfg = Debug|Win32
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Debug|x86.Build.0 = Debug|Win32
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Shared|ARM64.ActiveCfg = Shared|ARM64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Shared|ARM64.Build.0 = Shared|ARM64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Shared|x64.ActiveCfg = Shared|x64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Shared|x64.Build.0 = Shared|x64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Shared|x86.ActiveCfg = Shared|Win32
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Shared|x86.Build.0 = Shared|Win32
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Static|ARM64.ActiveCfg = Static|ARM64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Static|ARM64.Build.0 = Static|ARM64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Static|x64.ActiveCfg = Static|x64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Static|x64.Build.0 = Static|x64
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Static|x86.ActiveCfg = Static|Win32
{C703A94D-2755-40AD-A8D4-C169E14DCF5F}.Static|x86.Build.0 = Static|Win32
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Debug|ARM64.ActiveCfg = Debug|ARM64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Debug|ARM64.Build.0 = Debug|ARM64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Debug|x64.ActiveCfg = Debug|x64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Debug|x64.Build.0 = Debug|x64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Debug|x86.ActiveCfg = Debug|Win32
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Debug|x86.Build.0 = Debug|Win32
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Shared|ARM64.ActiveCfg = Shared|ARM64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Shared|ARM64.Build.0 = Shared|ARM64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Shared|x64.ActiveCfg = Shared|x64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Shared|x64.Build.0 = Shared|x64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Shared|x86.ActiveCfg = Shared|Win32
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Shared|x86.Build.0 = Shared|Win32
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Static|ARM64.ActiveCfg = Static|ARM64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Static|ARM64.Build.0 = Static|ARM64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Static|x64.ActiveCfg = Static|x64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Static|x64.Build.0 = Static|x64
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.Static|x86.ActiveCfg = Static|Win32
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}.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}
{C703A94D-2755-40AD-A8D4-C169E14DCF5F} = {1EFCA710-2528-41D7-B757-F4615301DCA2}
{903FEC5F-92A1-4EE0-A6E7-47B31742DA68} = {42437750-05E3-4DB6-AADA-FB44E73729B0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DC8E0EA3-7ABA-4BA8-B2E1-D9A43934BA40}
EndGlobalSection

View File

@ -1,24 +1,6 @@
DUMPMACHINE := $(shell $(CC) -dumpmachine)
include ../config.mk
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
endif
endif
CFLAGS = -std=c99 -D_DEFAULT_SOURCE -Wpedantic -Iinclude $(XCFLAGS)
CFLAGS = -std=c99 -D_DEFAULT_SOURCE -Wall -Wpedantic -Iinclude -fPIC $(XCFLAGS)
SRC_PATH := src
OBJ_PATH := obj
@ -28,15 +10,19 @@ ALL_PATH := $(SRC_PATH) $(OBJ_PATH) $(LIB_PATH)
SRC_FILE := $(wildcard $(SRC_PATH)/*.c)
OBJ_FILE := $(addprefix $(OBJ_PATH)/,$(patsubst %.c,%.o,$(notdir $(SRC_FILE))))
LIB_FILE := $(LIB_PATH)/libhashset-1.a
DLL_FILE := $(LIB_PATH)/libhashset-1$(DLL_SUFFIX)
.PHONY: all build clean
.PHONY: all build clean test
all: clean build
all test: clean build
build: $(ALL_PATH) $(LIB_FILE)
build: $(ALL_PATH) $(LIB_FILE) $(DLL_FILE)
$(LIB_FILE): $(OBJ_FILE)
$(AR) rcs $@ $(OBJ_FILE)
$(AR) rcs $@ $(filter-out $(OBJ_PATH)/dll%,$^)
$(DLL_FILE): $(OBJ_FILE)
$(CC) $(CFLAGS) $(DLL_LDFLAGS) -o $@ $^
$(OBJ_FILE):
$(CC) $(CFLAGS) -c $(SRC_PATH)/$(patsubst %.o,%.c,$(notdir $@)) -o $@
@ -45,4 +31,4 @@ $(ALL_PATH):
mkdir -p $@
clean:
rm -vf $(LIB_FILE) $(OBJ_PATH)/*.o
rm -vf $(LIB_FILE) $(DLL_FILE) $(DLL_FILE).a $(OBJ_PATH)/*.o

View File

@ -0,0 +1,114 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#ifndef _LIBHASHSET_MAP_INCLUDED
#define _LIBHASHSET_MAP_INCLUDED
#include <stdlib.h>
#include <stdint.h>
#if defined(_MSC_VER) && defined(HASHSET_DLL)
# ifdef _HASHSET_EXPORTS
# define HASHSET_API extern __declspec(dllexport)
# else
# define HASHSET_API extern __declspec(dllimport)
# endif
#else
# define HASHSET_API extern
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_LIBHASHSET_ERRNO_DEFINED)
typedef int errno_t;
#define _LIBHASHSET_ERRNO_DEFINED 1
#endif
/* ------------------------------------------------- */
/* Globals */
/* ------------------------------------------------- */
#ifndef _LIBHASHSET_GLOBALS_DEFINED
#define _LIBHASHSET_GLOBALS_DEFINED
HASHSET_API const uint16_t HASHSET_VERSION_MAJOR;
HASHSET_API const uint16_t HASHSET_VERSION_MINOR;
HASHSET_API const uint16_t HASHSET_VERSION_PATCH;
HASHSET_API const char* const HASHSET_BUILD_DATE;
HASHSET_API const char* const HASHSET_BUILD_TIME;
#endif /*_LIBHASHSET_GLOBALS_DEFINED*/
/* ------------------------------------------------- */
/* Types */
/* ------------------------------------------------- */
struct _hash_map16;
struct _hash_map32;
struct _hash_map64;
typedef struct _hash_map16 hash_map16_t;
typedef struct _hash_map32 hash_map32_t;
typedef struct _hash_map64 hash_map64_t;
typedef int (*hash_map_callback16_t)(const size_t index, const char status, const uint16_t key, const uint16_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);
/* ------------------------------------------------- */
/* Functions */
/* ------------------------------------------------- */
HASHSET_API hash_map16_t *hash_map_create16(const size_t initial_capacity, const double load_factor, const uint64_t seed);
HASHSET_API hash_map32_t *hash_map_create32(const size_t initial_capacity, const double load_factor, const uint64_t seed);
HASHSET_API hash_map64_t *hash_map_create64(const size_t initial_capacity, const double load_factor, const uint64_t seed);
HASHSET_API void hash_map_destroy16(hash_map16_t *const instance);
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_insert16(hash_map16_t *const instance, const uint16_t key, const uint16_t value, const int update);
HASHSET_API errno_t hash_map_insert32(hash_map32_t *const instance, const uint32_t key, const uint32_t value, const int update);
HASHSET_API errno_t hash_map_insert64(hash_map64_t *const instance, const uint64_t key, const uint64_t value, const int update);
HASHSET_API errno_t hash_map_remove16(hash_map16_t *const instance, const uint16_t key, uint16_t *const value);
HASHSET_API errno_t hash_map_remove32(hash_map32_t *const instance, const uint32_t key, uint32_t *const value);
HASHSET_API errno_t hash_map_remove64(hash_map64_t *const instance, const uint64_t key, uint64_t *const value);
HASHSET_API errno_t hash_map_clear16(hash_map16_t *const instance);
HASHSET_API errno_t hash_map_clear32(hash_map32_t *const instance);
HASHSET_API errno_t hash_map_clear64(hash_map64_t *const instance);
HASHSET_API errno_t hash_map_contains16(const hash_map16_t *const instance, const uint16_t key);
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_get16(const hash_map16_t *const instance, const uint16_t key, uint16_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_iterate16(const hash_map16_t *const instance, size_t *const cursor, uint16_t *const key, uint16_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_size16(const hash_map16_t* const instance);
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);
HASHSET_API errno_t hash_map_info16(const hash_map16_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_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_dump16(const hash_map16_t *const instance, const hash_map_callback16_t callback);
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
}
#endif
#endif /*_LIBHASHSET_MAP_INCLUDED*/

View File

@ -3,13 +3,13 @@
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#ifndef _LIBHASHSET_INCLUDED
#define _LIBHASHSET_INCLUDED
#ifndef _LIBHASHSET_SET_INCLUDED
#define _LIBHASHSET_SET_INCLUDED
#include <stdlib.h>
#include <stdint.h>
#if defined(_WIN32) && defined(HASHSET_DLL)
#if defined(_MSC_VER) && defined(HASHSET_DLL)
# ifdef _HASHSET_EXPORTS
# define HASHSET_API extern __declspec(dllexport)
# else
@ -23,10 +23,18 @@
extern "C" {
#endif
#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_ERRNO_T_DEFINED)
#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_LIBHASHSET_ERRNO_DEFINED)
typedef int errno_t;
#define _LIBHASHSET_ERRNO_DEFINED 1
#endif
/* ------------------------------------------------- */
/* Globals */
/* ------------------------------------------------- */
#ifndef _LIBHASHSET_GLOBALS_DEFINED
#define _LIBHASHSET_GLOBALS_DEFINED
HASHSET_API const uint16_t HASHSET_VERSION_MAJOR;
HASHSET_API const uint16_t HASHSET_VERSION_MINOR;
HASHSET_API const uint16_t HASHSET_VERSION_PATCH;
@ -34,43 +42,69 @@ HASHSET_API const uint16_t HASHSET_VERSION_PATCH;
HASHSET_API const char *const HASHSET_BUILD_DATE;
HASHSET_API const char *const HASHSET_BUILD_TIME;
#endif /*_LIBHASHSET_GLOBALS_DEFINED*/
/* ------------------------------------------------- */
/* Types */
/* ------------------------------------------------- */
struct _hash_set16;
struct _hash_set32;
struct _hash_set64;
typedef struct _hash_set16 hash_set16_t;
typedef struct _hash_set32 hash_set32_t;
typedef struct _hash_set64 hash_set64_t;
HASHSET_API hash_set32_t *hash_set_create32(const size_t initial_capacity, const double load_factor);
HASHSET_API hash_set64_t *hash_set_create64(const size_t initial_capacity, const double load_factor);
typedef int (*hash_set_callback16_t)(const size_t index, const char status, const uint16_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);
/* ------------------------------------------------- */
/* Functions */
/* ------------------------------------------------- */
HASHSET_API hash_set16_t *hash_set_create16(const size_t initial_capacity, const double load_factor, const uint64_t seed);
HASHSET_API hash_set32_t *hash_set_create32(const size_t initial_capacity, const double load_factor, const uint64_t seed);
HASHSET_API hash_set64_t *hash_set_create64(const size_t initial_capacity, const double load_factor, const uint64_t seed);
HASHSET_API void hash_set_destroy16(hash_set16_t *const instance);
HASHSET_API void hash_set_destroy32(hash_set32_t *const instance);
HASHSET_API void hash_set_destroy64(hash_set64_t *const instance);
HASHSET_API errno_t hash_set_insert32(hash_set32_t *const instance, const uint32_t value);
HASHSET_API errno_t hash_set_insert64(hash_set64_t *const instance, const uint64_t value);
HASHSET_API errno_t hash_set_insert16(hash_set16_t *const instance, const uint16_t item);
HASHSET_API errno_t hash_set_insert32(hash_set32_t *const instance, const uint32_t item);
HASHSET_API errno_t hash_set_insert64(hash_set64_t *const instance, const uint64_t item);
HASHSET_API errno_t hash_set_remove32(hash_set32_t *const instance, const uint32_t value);
HASHSET_API errno_t hash_set_remove64(hash_set64_t *const instance, const uint64_t value);
HASHSET_API errno_t hash_set_remove16(hash_set16_t *const instance, const uint16_t item);
HASHSET_API errno_t hash_set_remove32(hash_set32_t *const instance, const uint32_t item);
HASHSET_API errno_t hash_set_remove64(hash_set64_t *const instance, const uint64_t item);
HASHSET_API errno_t hash_set_clear16(hash_set16_t *const instance);
HASHSET_API errno_t hash_set_clear32(hash_set32_t *const instance);
HASHSET_API errno_t hash_set_clear64(hash_set64_t *const instance);
HASHSET_API errno_t hash_set_contains32(const hash_set32_t *const instance, const uint32_t value);
HASHSET_API errno_t hash_set_contains64(const hash_set64_t *const instance, const uint64_t value);
HASHSET_API errno_t hash_set_contains16(const hash_set16_t *const instance, const uint16_t item);
HASHSET_API errno_t hash_set_contains32(const hash_set32_t *const instance, const uint32_t item);
HASHSET_API errno_t hash_set_contains64(const hash_set64_t *const instance, const uint64_t item);
HASHSET_API errno_t hash_set_iterate32(const hash_set32_t *const instance, uintptr_t *const cursor, uint32_t *const value);
HASHSET_API errno_t hash_set_iterate64(const hash_set64_t *const instance, uintptr_t *const cursor, uint64_t *const value);
HASHSET_API errno_t hash_set_iterate16(const hash_set16_t *const instance, size_t *const cursor, uint16_t *const item);
HASHSET_API errno_t hash_set_iterate32(const hash_set32_t *const instance, size_t *const cursor, uint32_t *const item);
HASHSET_API errno_t hash_set_iterate64(const hash_set64_t *const instance, size_t *const cursor, uint64_t *const item);
HASHSET_API size_t hash_set_size16(const hash_set16_t *const instance);
HASHSET_API size_t hash_set_size32(const hash_set32_t *const instance);
HASHSET_API size_t hash_set_size64(const hash_set64_t *const instance);
HASHSET_API errno_t hash_set_info16(const hash_set16_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_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 value));
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 value));
HASHSET_API errno_t hash_set_dump16(const hash_set16_t *const instance, const hash_set_callback16_t callback);
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
}
#endif
#endif /* _LIBHASHSET_INCLUDED */
#endif /*_LIBHASHSET_SET_INCLUDED*/

View File

@ -39,11 +39,25 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\hash_map.h" />
<ClInclude Include="include\hash_set.h" />
<ClInclude Include="src\common.h" />
<ClInclude Include="src\generic.h" />
<ClInclude Include="src\generic_hash_map.h" />
<ClInclude Include="src\generic_hash_set.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\dll_main.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Static|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="src\hash_map_16.c" />
<ClCompile Include="src\hash_map_32.c" />
<ClCompile Include="src\hash_map_64.c" />
<ClCompile Include="src\hash_set_16.c" />
<ClCompile Include="src\hash_set_32.c" />
<ClCompile Include="src\hash_set_64.c" />
<ClCompile Include="src\version.c" />
@ -205,12 +219,14 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AdditionalIncludeDirectories>$(ProjectDir)\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>
@ -220,7 +236,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -238,6 +254,8 @@
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
<AdditionalIncludeDirectories>$(ProjectDir)\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>
@ -252,7 +270,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -270,6 +288,8 @@
<AdditionalIncludeDirectories>$(ProjectDir)\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_DLL;HASHSET_DLL;_HASHSET_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -285,12 +305,14 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AdditionalIncludeDirectories>$(ProjectDir)\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>
@ -300,12 +322,14 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AdditionalIncludeDirectories>$(ProjectDir)\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>
@ -315,7 +339,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -332,6 +356,8 @@
<ControlFlowGuard>false</ControlFlowGuard>
<AdditionalIncludeDirectories>$(ProjectDir)\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>
@ -346,7 +372,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -363,6 +389,8 @@
<ControlFlowGuard>false</ControlFlowGuard>
<AdditionalIncludeDirectories>$(ProjectDir)\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>
@ -377,7 +405,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -394,6 +422,8 @@
<ControlFlowGuard>false</ControlFlowGuard>
<AdditionalIncludeDirectories>$(ProjectDir)\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -409,7 +439,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
@ -426,6 +456,8 @@
<ControlFlowGuard>false</ControlFlowGuard>
<AdditionalIncludeDirectories>$(ProjectDir)\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View File

@ -21,7 +21,13 @@
<ClInclude Include="src\common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\generic.h">
<ClInclude Include="src\generic_hash_set.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\hash_map.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\generic_hash_map.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
@ -35,5 +41,20 @@
<ClCompile Include="src\hash_set_32.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\hash_map_64.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\hash_map_32.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\hash_map_16.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\hash_set_16.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\dll_main.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -30,7 +30,9 @@ typedef int bool_t;
static const size_t MINIMUM_CAPACITY = 128U;
static const size_t DEFAULT_CAPACITY = 8192U;
static const double DEFAULT_LOADFCTR = 0.8;
static const double DEFAULT_LOADFCTR = 0.75;
#define SEED UINT32_C(0x6A09E667)
/* ------------------------------------------------- */
/* Utilities */
@ -44,6 +46,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 */
/* ------------------------------------------------- */
@ -101,7 +106,7 @@ static FORCE_INLINE size_t next_pow2(const size_t target)
/* Hash function */
/* ------------------------------------------------- */
static FORCE_INLINE void hash_update(uint64_t* const hash, uint64_t value)
static FORCE_INLINE void hash_update(uint64_t *const hash, uint64_t value)
{
do
{
@ -111,9 +116,15 @@ static FORCE_INLINE void hash_update(uint64_t* const hash, uint64_t value)
while (value >>= CHAR_BIT);
}
static INLINE uint64_t hash_compute(const uint64_t i, const uint64_t value)
static INLINE uint64_t hash_initialize(const uint64_t seed)
{
uint64_t hash = UINT64_C(14695981039346656037);
hash_update(&hash, seed);
return hash;
}
static INLINE uint64_t hash_compute(uint64_t hash, const uint64_t i, const uint64_t value)
{
hash_update(&hash, i);
hash_update(&hash, value);
return hash;
@ -132,17 +143,17 @@ static INLINE void zero_memory(void *const addr, const size_t count, const size_
/* Flags */
/* ------------------------------------------------- */
static INLINE bool_t get_flag(const uint8_t *const flags, const size_t index)
static FORCE_INLINE bool_t get_flag(const uint8_t *const flags, const size_t index)
{
return (flags[index / 8U] >> (index % 8U)) & UINT8_C(1);
}
static INLINE void set_flag(uint8_t *const flags, const size_t index)
static FORCE_INLINE void set_flag(uint8_t *const flags, const size_t index)
{
flags[index / 8U] |= UINT8_C(1) << (index % 8U);
}
static INLINE void clear_flag(uint8_t *const flags, const size_t index)
static FORCE_INLINE void clear_flag(uint8_t *const flags, const size_t index)
{
flags[index / 8U] &= ~(UINT8_C(1) << (index % 8U));
}

30
libhashset/src/dll_main.c Normal file
View File

@ -0,0 +1,30 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#if defined(__GNUC__)
# pragma GCC diagnostic ignored "-Wpedantic"
#elif defined(_MSC_VER)
# pragma warning(disable: 4100)
#endif
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN 1
#include <Windows.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#endif /*_WIN32*/

View File

@ -0,0 +1,445 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#ifndef _LIBHASHSET_GENERIC_MAP_INCLUDED
#define _LIBHASHSET_GENERIC_MAP_INCLUDED
#include "common.h"
#ifndef NAME_SUFFIX
#error NAME_SUFFIX must be defined!
#endif
#define DECLARE(X) CONCAT(X,NAME_SUFFIX)
/* ------------------------------------------------- */
/* Data types */
/* ------------------------------------------------- */
typedef struct
{
value_t key;
value_t value;
}
entry_t;
typedef struct DECLARE(_hash_map_data)
{
entry_t *entries;
uint8_t *used, *deleted;
size_t capacity;
}
hash_data_t;
struct DECLARE(_hash_map)
{
double load_factor;
size_t valid, deleted, limit;
uint64_t basis;
hash_data_t data;
};
/* ------------------------------------------------- */
/* Allocation */
/* ------------------------------------------------- */
static INLINE bool_t alloc_data(hash_data_t *const data, const size_t capacity)
{
zero_memory(data, 1U, sizeof(hash_data_t));
data->entries = (entry_t*) calloc(capacity, sizeof(entry_t));
if (!data->entries)
{
return FALSE;
}
data->used = (uint8_t*) calloc(div_ceil(capacity, 8U), sizeof(uint8_t));
if (!data->used)
{
SAFE_FREE(data->entries);
return FALSE;
}
data->deleted = (uint8_t*) calloc(div_ceil(capacity, 8U), sizeof(uint8_t));
if (!data->deleted)
{
SAFE_FREE(data->used);
SAFE_FREE(data->entries);
return FALSE;
}
data->capacity = capacity;
return TRUE;
}
static INLINE void free_data(hash_data_t *const data)
{
if (data)
{
SAFE_FREE(data->entries);
SAFE_FREE(data->used);
SAFE_FREE(data->deleted);
data->capacity = 0U;
}
}
/* ------------------------------------------------- */
/* Set functions */
/* ------------------------------------------------- */
#define INDEX(X) ((size_t)((X) % data->capacity))
static INLINE bool_t find_slot(const hash_data_t *const data, const uint64_t basis, const value_t key, size_t *const index_out, bool_t *const reused_out)
{
size_t index;
bool_t is_saved = FALSE;
uint64_t loop = 0U;
for (index = INDEX(hash_compute(basis, loop, key)); get_flag(data->used, index); index = INDEX(hash_compute(basis, ++loop, key)))
{
if (get_flag(data->deleted, index))
{
if (!is_saved)
{
SAFE_SET(index_out, index);
SAFE_SET(reused_out, TRUE);
is_saved = TRUE;
}
}
else
{
if (data->entries[index].key == key)
{
SAFE_SET(index_out, index);
SAFE_SET(reused_out, FALSE);
return TRUE;
}
}
}
if (!is_saved)
{
SAFE_SET(index_out, index);
SAFE_SET(reused_out, FALSE);
}
return FALSE;
}
static INLINE void put_entry(hash_data_t *const data, const size_t index, const value_t key, const value_t value, const bool_t reusing)
{
entry_t *const entry = &data->entries[index];
entry->key = key;
entry->value = value;
if (reusing)
{
assert(get_flag(data->used, index));
clear_flag(data->deleted, index);
}
else
{
assert(!get_flag(data->deleted, index));
set_flag(data->used, index);
}
}
static INLINE size_t compute_limit(const size_t capacity, const double load_factor)
{
size_t limit = round_sz(capacity * load_factor);
while (capacity && (limit >= capacity))
{
limit = safe_decr(limit);
}
return limit;
}
static INLINE errno_t rebuild_map(hash_map_t *const instance, const size_t new_capacity)
{
size_t k, index = SIZE_MAX;
hash_data_t temp;
if (new_capacity < instance->valid)
{
return EINVAL;
}
if (!alloc_data(&temp, new_capacity))
{
return ENOMEM;
}
for (k = 0U; k < instance->data.capacity; ++k)
{
if (IS_VALID(instance->data, k))
{
const entry_t entry = instance->data.entries[k];
if (find_slot(&temp, instance->basis, entry.key, &index, NULL))
{
free_data(&temp);
return EFAULT; /*this should never happen!*/
}
put_entry(&temp, index, entry.key, entry.value, FALSE);
}
}
free_data(&instance->data);
instance->data = temp;
instance->limit = compute_limit(instance->data.capacity, instance->load_factor);
instance->deleted = 0U;
return 0;
}
/* ========================================================================= */
/* PUBLIC FUNCTIONS */
/* ========================================================================= */
hash_map_t *DECLARE(hash_map_create)(const size_t initial_capacity, const double load_factor, const uint64_t seed)
{
hash_map_t *instance = (hash_map_t*) calloc(1U, sizeof(hash_map_t));
if (!instance)
{
return NULL;
}
if (!alloc_data(&instance->data, (initial_capacity > 0U) ? next_pow2(initial_capacity) : DEFAULT_CAPACITY))
{
SAFE_FREE(instance);
return NULL;
}
instance->load_factor = (load_factor > DBL_EPSILON) ? BOUND(0.125, load_factor, 1.0) : DEFAULT_LOADFCTR;
instance->basis = hash_initialize(seed);
instance->limit = compute_limit(instance->data.capacity, instance->load_factor);
return instance;
}
void DECLARE(hash_map_destroy)(hash_map_t *instance)
{
if (instance)
{
free_data(&instance->data);
zero_memory(instance, 1U, sizeof(hash_map_t));
SAFE_FREE(instance);
}
}
errno_t DECLARE(hash_map_insert)(hash_map_t *const instance, const value_t key, const value_t value, const bool_t update)
{
size_t index = SIZE_MAX;
bool_t slot_reused;
if ((!instance) || (!instance->data.entries))
{
return EINVAL;
}
if (find_slot(&instance->data, instance->basis, key, &index, &slot_reused))
{
if (update)
{
instance->data.entries[index].value = value;
}
return EEXIST;
}
if ((!slot_reused) && (safe_add(instance->valid, instance->deleted) >= instance->limit))
{
if (instance->data.capacity < SIZE_MAX)
{
const errno_t error = rebuild_map(instance, safe_times2(instance->data.capacity));
if (error)
{
return error;
}
if (find_slot(&instance->data, instance->basis, key, &index, &slot_reused))
{
return EFAULT;
}
}
else
{
return EFBIG; /*can not grow any futher!*/
}
}
put_entry(&instance->data, index, key, value, slot_reused);
instance->valid = safe_incr(instance->valid);
if (slot_reused)
{
instance->deleted = safe_decr(instance->deleted);
}
return 0;
}
errno_t DECLARE(hash_map_contains)(const hash_map_t *const instance, const value_t key)
{
if ((!instance) || (!instance->data.entries))
{
return EINVAL;
}
return (instance->valid && find_slot(&instance->data, instance->basis, key, NULL, NULL)) ? 0 : ENOENT;
}
errno_t DECLARE(hash_map_get)(const hash_map_t *const instance, const value_t key, value_t *const value)
{
size_t index;
if ((!instance) || (!instance->data.entries))
{
return EINVAL;
}
if (!find_slot(&instance->data, instance->basis, key, &index, NULL))
{
return ENOENT;
}
*value = instance->data.entries[index].value;
return 0;
}
errno_t DECLARE(hash_map_remove)(hash_map_t *const instance, const value_t key, value_t *const value)
{
size_t index;
if ((!instance) || (!instance->data.entries))
{
return EINVAL;
}
if ((!instance->valid) || (!find_slot(&instance->data, instance->basis, key, &index, NULL)))
{
return ENOENT;
}
SAFE_SET(value, instance->data.entries[index].value);
set_flag(instance->data.deleted, index);
instance->deleted = safe_incr(instance->deleted);
instance->valid = safe_decr(instance->valid);
if (!instance->valid)
{
return DECLARE(hash_map_clear)(instance);
}
if (instance->deleted > (instance->limit / 2U))
{
const size_t min_capacity = next_pow2(round_sz(safe_incr(instance->valid) / instance->load_factor));
const errno_t error = rebuild_map(instance, (instance->data.capacity > min_capacity) ? min_capacity : instance->data.capacity);
if (error && (error != ENOMEM))
{
return error;
}
}
return 0;
}
errno_t DECLARE(hash_map_clear)(hash_map_t *const instance)
{
if ((!instance) || (!instance->data.entries))
{
return EINVAL;
}
if (instance->valid || instance->deleted)
{
const size_t count = div_ceil(instance->data.capacity, 8U);
instance->valid = instance->deleted = 0U;
zero_memory(instance->data.used, count, sizeof(uint8_t));
zero_memory(instance->data.deleted, count, sizeof(uint8_t));
}
else
{
return EAGAIN;
}
if (instance->data.capacity > MINIMUM_CAPACITY)
{
const errno_t error = rebuild_map(instance, MINIMUM_CAPACITY);
if (error && (error != ENOMEM))
{
return error;
}
}
return 0;
}
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;
if ((!instance) || (!cursor) || (*cursor >= SIZE_MAX) || (!instance->data.entries))
{
return EINVAL;
}
for (index = *cursor; index < instance->data.capacity; ++index)
{
if (IS_VALID(instance->data, index))
{
const entry_t* const entntry = &instance->data.entries[index];
SAFE_SET(key, entntry->key);
SAFE_SET(value, entntry->value);
*cursor = index + 1U;
return 0;
}
}
*cursor = SIZE_MAX;
return ENOENT;
}
size_t DECLARE(hash_map_size)(const hash_map_t *const instance)
{
return instance ? instance->valid : 0U;
}
errno_t DECLARE(hash_map_info)(const hash_map_t *const instance, size_t *const capacity, size_t *const valid, size_t *const deleted, size_t *const limit)
{
if ((!instance) || (!instance->data.entries))
{
return EINVAL;
}
SAFE_SET(capacity, instance->data.capacity);
SAFE_SET(valid, instance->valid);
SAFE_SET(deleted,instance->deleted);
SAFE_SET(limit, instance->limit);
return 0;
}
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.entries) || (!callback))
{
return EINVAL;
}
for (index = 0U; index < instance->data.capacity; ++index)
{
const entry_t* const entntry = &instance->data.entries[index];
if (!callback(index, get_flag(instance->data.used, index) ? (get_flag(instance->data.deleted, index) ? 'd' : 'v') : 'u', entntry->key, entntry->value))
{
return ECANCELED;
}
}
return 0;
}
#endif /*_LIBHASHSET_GENERIC_MAP_INCLUDED*/

View File

@ -3,8 +3,8 @@
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#ifndef _LIBHASHSET_GENERIC_INCLUDED
#define _LIBHASHSET_GENERIC_INCLUDED
#ifndef _LIBHASHSET_GENERIC_SET_INCLUDED
#define _LIBHASHSET_GENERIC_SET_INCLUDED
#include "common.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)
{
value_t *values;
value_t *items;
uint8_t *used, *deleted;
size_t capacity;
}
@ -33,6 +30,7 @@ struct DECLARE(_hash_set)
{
double load_factor;
size_t valid, deleted, limit;
uint64_t basis;
hash_data_t data;
};
@ -44,8 +42,8 @@ static INLINE bool_t alloc_data(hash_data_t *const data, const size_t capacity)
{
zero_memory(data, 1U, sizeof(hash_data_t));
data->values = (value_t*) calloc(capacity, sizeof(value_t));
if (!data->values)
data->items = (value_t*) calloc(capacity, sizeof(value_t));
if (!data->items)
{
return FALSE;
}
@ -53,7 +51,7 @@ static INLINE bool_t alloc_data(hash_data_t *const data, const size_t capacity)
data->used = (uint8_t*) calloc(div_ceil(capacity, 8U), sizeof(uint8_t));
if (!data->used)
{
SAFE_FREE(data->values);
SAFE_FREE(data->items);
return FALSE;
}
@ -61,7 +59,7 @@ static INLINE bool_t alloc_data(hash_data_t *const data, const size_t capacity)
if (!data->deleted)
{
SAFE_FREE(data->used);
SAFE_FREE(data->values);
SAFE_FREE(data->items);
return FALSE;
}
@ -73,7 +71,7 @@ static INLINE void free_data(hash_data_t *const data)
{
if (data)
{
SAFE_FREE(data->values);
SAFE_FREE(data->items);
SAFE_FREE(data->used);
SAFE_FREE(data->deleted);
data->capacity = 0U;
@ -86,13 +84,13 @@ 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 value_t value, size_t *const index_out, bool_t *const reused_out)
static INLINE bool_t find_slot(const hash_data_t *const data, const uint64_t basis, const value_t item, size_t *const index_out, bool_t *const reused_out)
{
uint64_t loop = 0U;
bool_t is_saved = FALSE;
size_t index;
bool_t is_saved = FALSE;
uint64_t loop = 0U;
for (index = INDEX(hash_compute(loop, value)); get_flag(data->used, index); index = INDEX(hash_compute(++loop, value)))
for (index = INDEX(hash_compute(basis, loop, item)); get_flag(data->used, index); index = INDEX(hash_compute(basis, ++loop, item)))
{
if (get_flag(data->deleted, index))
{
@ -105,7 +103,7 @@ static INLINE bool_t find_slot(const hash_data_t *const data, const value_t valu
}
else
{
if (data->values[index] == value)
if (data->items[index] == item)
{
SAFE_SET(index_out, index);
SAFE_SET(reused_out, FALSE);
@ -123,9 +121,10 @@ static INLINE bool_t find_slot(const hash_data_t *const data, const value_t valu
return FALSE;
}
static INLINE void put_value(hash_data_t *const data, const size_t index, const value_t value, 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->values[index] = value;
data->items[index] = item;
if (reusing)
{
assert(get_flag(data->used, index));
@ -152,7 +151,7 @@ static INLINE size_t compute_limit(const size_t capacity, const double load_fact
static INLINE errno_t rebuild_set(hash_set_t *const instance, const size_t new_capacity)
{
size_t k, index;
size_t k, index = SIZE_MAX;
hash_data_t temp;
if (new_capacity < instance->valid)
@ -169,13 +168,13 @@ static INLINE errno_t rebuild_set(hash_set_t *const instance, const size_t new_c
{
if (IS_VALID(instance->data, k))
{
const value_t value = instance->data.values[k];
if (find_slot(&temp, value, &index, NULL))
const value_t item = instance->data.items[k];
if (find_slot(&temp, instance->basis, item, &index, NULL))
{
free_data(&temp);
return EFAULT; /*this should never happen!*/
}
put_value(&temp, index, value, FALSE);
put_item(&temp, index, item, FALSE);
}
}
@ -191,9 +190,9 @@ static INLINE errno_t rebuild_set(hash_set_t *const instance, const size_t new_c
/* PUBLIC FUNCTIONS */
/* ========================================================================= */
hash_set_t *DECLARE(hash_set_create)(const size_t initial_capacity, const double load_factor)
hash_set_t *DECLARE(hash_set_create)(const size_t initial_capacity, const double load_factor, const uint64_t seed)
{
hash_set_t* instance = (hash_set_t*) calloc(1U, sizeof(hash_set_t));
hash_set_t *instance = (hash_set_t*) calloc(1U, sizeof(hash_set_t));
if (!instance)
{
return NULL;
@ -206,6 +205,7 @@ hash_set_t *DECLARE(hash_set_create)(const size_t initial_capacity, const double
}
instance->load_factor = (load_factor > DBL_EPSILON) ? BOUND(0.125, load_factor, 1.0) : DEFAULT_LOADFCTR;
instance->basis = hash_initialize(seed);
instance->limit = compute_limit(instance->data.capacity, instance->load_factor);
return instance;
@ -221,35 +221,42 @@ void DECLARE(hash_set_destroy)(hash_set_t *instance)
}
}
errno_t DECLARE(hash_set_insert)(hash_set_t *const instance, const value_t value)
errno_t DECLARE(hash_set_insert)(hash_set_t *const instance, const value_t item)
{
size_t index;
size_t index = SIZE_MAX;
bool_t slot_reused;
if ((!instance) || (!instance->data.values))
if ((!instance) || (!instance->data.items))
{
return EINVAL;
}
if (find_slot(&instance->data, value, &index, &slot_reused))
if (find_slot(&instance->data, instance->basis, item, &index, &slot_reused))
{
return EEXIST;
}
if ((!slot_reused) && (safe_add(instance->valid, instance->deleted) >= instance->limit))
{
if (instance->data.capacity < SIZE_MAX)
{
const errno_t error = rebuild_set(instance, safe_times2(instance->data.capacity));
if (error)
{
return error;
}
if (find_slot(&instance->data, value, &index, &slot_reused))
if (find_slot(&instance->data, instance->basis, item, &index, &slot_reused))
{
return EFAULT;
}
}
else
{
return EFBIG; /*can not grow any futher!*/
}
}
put_value(&instance->data, index, value, slot_reused);
put_item(&instance->data, index, item, slot_reused);
instance->valid = safe_incr(instance->valid);
if (slot_reused)
@ -260,26 +267,26 @@ errno_t DECLARE(hash_set_insert)(hash_set_t *const instance, const value_t value
return 0;
}
errno_t DECLARE(hash_set_contains)(const hash_set_t *const instance, const value_t value)
errno_t DECLARE(hash_set_contains)(const hash_set_t *const instance, const value_t item)
{
if ((!instance) || (!instance->data.values))
if ((!instance) || (!instance->data.items))
{
return EINVAL;
}
return (instance->valid && find_slot(&instance->data, value, NULL, NULL)) ? 0 : ENOENT;
return (instance->valid && find_slot(&instance->data, instance->basis, item, NULL, NULL)) ? 0 : ENOENT;
}
errno_t DECLARE(hash_set_remove)(hash_set_t *const instance, const value_t value)
errno_t DECLARE(hash_set_remove)(hash_set_t *const instance, const value_t item)
{
size_t index;
if ((!instance) || (!instance->data.values))
if ((!instance) || (!instance->data.items))
{
return EINVAL;
}
if ((!instance->valid) || (!find_slot(&instance->data, value, &index, NULL)))
if ((!instance->valid) || (!find_slot(&instance->data, instance->basis, item, &index, NULL)))
{
return ENOENT;
}
@ -308,7 +315,7 @@ errno_t DECLARE(hash_set_remove)(hash_set_t *const instance, const value_t value
errno_t DECLARE(hash_set_clear)(hash_set_t *const instance)
{
if ((!instance) || (!instance->data.values))
if ((!instance) || (!instance->data.items))
{
return EINVAL;
}
@ -337,29 +344,26 @@ 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, uintptr_t *const cursor, value_t *const value)
errno_t DECLARE(hash_set_iterate)(const hash_set_t *const instance, size_t *const cursor, value_t *const item)
{
size_t index;
if ((!instance) || (!cursor) || (*cursor >= SIZE_MAX) || (!instance->data.values))
if ((!instance) || (!cursor) || (*cursor >= SIZE_MAX) || (!instance->data.items))
{
return EINVAL;
}
for (index = (size_t)(*cursor); index < instance->data.capacity; ++index)
for (index = *cursor; index < instance->data.capacity; ++index)
{
if (IS_VALID(instance->data, index))
{
if (value)
{
*value = instance->data.values[index];
}
*cursor = (uintptr_t)(index + 1U);
SAFE_SET(item, instance->data.items[index]);
*cursor = index + 1U;
return 0;
}
}
*cursor = (uintptr_t)SIZE_MAX;
*cursor = SIZE_MAX;
return ENOENT;
}
@ -370,43 +374,31 @@ size_t DECLARE(hash_set_size)(const hash_set_t *const instance)
errno_t DECLARE(hash_set_info)(const hash_set_t *const instance, size_t *const capacity, size_t *const valid, size_t *const deleted, size_t *const limit)
{
if ((!instance) || (!instance->data.values))
if ((!instance) || (!instance->data.items))
{
return EINVAL;
}
if (capacity)
{
*capacity = instance->data.capacity;
}
if (valid)
{
*valid = instance->valid;
}
if (deleted)
{
*deleted = instance->deleted;
}
if (limit)
{
*limit = instance->limit;
}
SAFE_SET(capacity, instance->data.capacity);
SAFE_SET(valid, instance->valid);
SAFE_SET(deleted, instance->deleted);
SAFE_SET(limit, instance->limit);
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 value_t value))
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.values))
if ((!instance) || (!instance->data.items) || (!callback))
{
return EINVAL;
}
for (index = 0U; index < instance->data.capacity; ++index)
{
if (!callback(index, get_flag(instance->data.used, index) ? (get_flag(instance->data.deleted, index) ? 'd' : 'v') : 'u', instance->data.values[index]))
if (!callback(index, get_flag(instance->data.used, index) ? (get_flag(instance->data.deleted, index) ? 'd' : 'v') : 'u', instance->data.items[index]))
{
return ECANCELED;
}
@ -415,4 +407,4 @@ HASHSET_API errno_t DECLARE(hash_set_dump)(const hash_set_t *const instance, int
return 0;
}
#endif /* _LIBHASHSET_GENERIC_INCLUDED */
#endif /*_LIBHASHSET_GENERIC_SET_INCLUDED*/

View File

@ -0,0 +1,13 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#include <hash_map.h>
#define NAME_SUFFIX 16
typedef hash_map16_t hash_map_t;
typedef hash_map_callback16_t hash_map_callback_t;
typedef uint16_t value_t;
#include "generic_hash_map.h"

View File

@ -0,0 +1,13 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#include <hash_map.h>
#define NAME_SUFFIX 32
typedef hash_map32_t hash_map_t;
typedef hash_map_callback32_t hash_map_callback_t;
typedef uint32_t value_t;
#include "generic_hash_map.h"

View File

@ -0,0 +1,13 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#include <hash_map.h>
#define NAME_SUFFIX 64
typedef hash_map64_t hash_map_t;
typedef hash_map_callback64_t hash_map_callback_t;
typedef uint64_t value_t;
#include "generic_hash_map.h"

View File

@ -0,0 +1,13 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#include <hash_set.h>
#define NAME_SUFFIX 16
typedef hash_set16_t hash_set_t;
typedef hash_set_callback16_t hash_set_callback_t;
typedef uint16_t value_t;
#include "generic_hash_set.h"

View File

@ -4,10 +4,10 @@
/******************************************************************************/
#include <hash_set.h>
#include "common.h"
#define NAME_SUFFIX 32
typedef hash_set32_t hash_set_t;
typedef hash_set_callback32_t hash_set_callback_t;
typedef uint32_t value_t;
#include "generic.h"
#include "generic_hash_set.h"

View File

@ -7,6 +7,7 @@
#define NAME_SUFFIX 64
typedef hash_set64_t hash_set_t;
typedef hash_set_callback64_t hash_set_callback_t;
typedef uint64_t value_t;
#include "generic.h"
#include "generic_hash_set.h"

View File

@ -6,8 +6,8 @@
#include <hash_set.h>
const uint16_t HASHSET_VERSION_MAJOR = UINT16_C(1);
const uint16_t HASHSET_VERSION_MINOR = UINT16_C(1);
const uint16_t HASHSET_VERSION_MINOR = UINT16_C(2);
const uint16_t HASHSET_VERSION_PATCH = UINT16_C(0);
const char* const HASHSET_BUILD_DATE = __DATE__;
const char* const HASHSET_BUILD_TIME = __TIME__;
const char *const HASHSET_BUILD_DATE = __DATE__;
const char *const HASHSET_BUILD_TIME = __TIME__;

13
mk-docs.cmd Normal file
View File

@ -0,0 +1,13 @@
@echo off
cd /d "%~dp0"
if "%PANDODC_PATH%"=="" (
set "PANDODC_PATH=c:\Program Files (x86)\Pandoc"
)
echo on
"%PANDODC_PATH%\pandoc.exe" -o "%CD%\README.html" --self-contained --metadata title="LibHashSet" --toc --toc-depth=3 --css etc\style\gh-pandoc.min.css "%CD%\README.md"
@echo off
echo.
pause

View File

@ -1,52 +1,8 @@
DUMPMACHINE := $(shell $(CC) -dumpmachine)
SUBDIRS := hash-set hash-map
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
.PHONY: all clean test $(SUBDIRS)
ifneq ($(firstword $(filter %-mingw32 %-cygwin,$(DUMPMACHINE))),)
EXE_SUFFIX := .exe
ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),)
XCFLAGS += -Wl,--large-address-aware
endif
endif
all clean test: $(SUBDIRS)
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)
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)

27
test/hash-map/Makefile Normal file
View File

@ -0,0 +1,27 @@
include ../../config.mk
CFLAGS = -std=c99 -D_DEFAULT_SOURCE -Wall -Wpedantic -I../../libhashset/include -I../shared/include $(XCFLAGS)
LDFLAGS = -L../../libhashset/lib -lhashset-1 $(XLDFLAGS)
SRC_PATH := src
BIN_PATH := bin
ALL_PATH := $(SRC_PATH) $(BIN_PATH)
BIN_FILE := $(BIN_PATH)/test-hash-map$(EXE_SUFFIX)
SRC_FILE := $(wildcard $(SRC_PATH)/*.c) $(wildcard ../shared/src/*.c)
.PHONY: all clean test
all: clean $(ALL_PATH) $(BIN_FILE)
$(BIN_FILE): $(SRC_FILE)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
$(ALL_PATH):
mkdir -p $@
test: all
env $(ENV_LDPATH)="$(realpath .):$(realpath ../../libhashset/lib)$(if $($(ENV_LDPATH)),:$($(ENV_LDPATH)))" ./$(BIN_FILE)
clean:
rm -vf $(BIN_FILE)

57
test/hash-map/src/main.c Normal file
View File

@ -0,0 +1,57 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#include "tests.h"
#include "../../shared/include/time_in.h"
#include <stdio.h>
#include <inttypes.h>
#define RUN_TEST_CASE(X) do \
{ \
if (test_function_##X(hash_set) != EXIT_SUCCESS) \
{ \
goto failure; \
} \
} \
while(0)
/* ========================================================================= */
/* MAIN */
/* ========================================================================= */
int main(void)
{
hash_map64_t *hash_set;
uint64_t clk_begin, clk_end;
printf("LibHashSet Hash-Map Test v%" PRIu16 ".%" PRIu16 ".%" PRIu16 " [%s]\n\n",
HASHSET_VERSION_MAJOR, HASHSET_VERSION_MINOR, HASHSET_VERSION_PATCH, HASHSET_BUILD_DATE);
clk_begin = clock_query();
hash_set = hash_map_create64(0U, -1.0, clock_query());
if (!hash_set)
{
puts("Allocation has failed!");
return EXIT_FAILURE;
}
RUN_TEST_CASE(1);
RUN_TEST_CASE(2);
RUN_TEST_CASE(3);
RUN_TEST_CASE(4);
hash_map_destroy64(hash_set);
clk_end = clock_query();
printf("Tests completed successfully [%.2f].\n\n", (clk_end - clk_begin) / ((double)clock_frequency()));
return EXIT_SUCCESS;
failure:
hash_map_destroy64(hash_set);
puts("\nSomething went wrong !!!\n");
return EXIT_FAILURE;
}

442
test/hash-map/src/tests.c Normal file
View File

@ -0,0 +1,442 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#include "tests.h"
#include <random_in.h>
#include <stdio.h>
#include <inttypes.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#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_map_info64(hash_map, &capacity, &valid, &deleted, &limit)) \
{ \
fprintf(stdout, "[MAP %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 TEST_SIZE 499979U
int test_function_1(hash_map64_t *const hash_map)
{
size_t r, j, cursor, capacity, valid, deleted, limit;
uint64_t key, value, *test_data;
uint8_t spinner = 0U, *test_key1, *test_key2;
random_t random;
random_init(&random);
test_key1 = (uint8_t*) malloc(TEST_SIZE * sizeof(uint8_t));
if (!test_key1)
{
abort(); /*malloc has failed!*/
}
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(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)
{
size_t rnd;
do
{
rnd = random_next(&random) % TEST_SIZE;
}
while (test_key1[rnd]);
INVERT(test_key1[rnd]);
}
for (j = 0U; j < TEST_SIZE; ++j)
{
if (test_key1[j])
{
const errno_t error = hash_map_insert64(hash_map, j, test_data[j] = random_next(&random), 1);
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_map, 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_map, &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_map, 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_map, j, NULL);
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_map, j);
if (error != ENOENT)
{
printf("Contains operation has failed! (error: %d)\n", error);
return EXIT_FAILURE;
}
}
if (hash_map_size64(hash_map) != 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_map)
{
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_map, j, test_val[j] = random_next(&random), 1);
if (error)
{
printf("Insert operation has failed! (error: %d)\n", error);
return EXIT_FAILURE;
}
if (!(++spinner & 0x0F))
{
PRINT_SET_INFO(2);
}
}
}
for (j = 0U; j < TEST_SIZE; ++j)
{
if (test_key[j])
{
const errno_t error = hash_map_insert64(hash_map, j, test_val[j] = random_next(&random), 1);
if (error != EEXIST)
{
printf("Insert operation has failed! (error: %d)\n", error);
return EXIT_FAILURE;
}
if (!(++spinner & 0x0F))
{
PRINT_SET_INFO(2);
}
}
}
for (j = 0U; j < TEST_SIZE; ++j)
{
if (test_key[j])
{
if (!hash_map_get64(hash_map, 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_map))
{
puts("Failed to clear the map!");
return EXIT_FAILURE;
}
}
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_map)
{
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_map, rnd, VALUE(rnd), 1);
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_map, &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_map))
{
puts("Clear operation has failed!");
return EXIT_FAILURE;
}
}
PRINT_SET_INFO(3);
puts("---------");
return EXIT_SUCCESS;
}
/* ========================================================================= */
/* TEST #4 */
/* ========================================================================= */
#define LIMIT (((uint64_t)UINT32_MAX) >> 3)
int test_function_4(hash_map64_t *const hash_map)
{
size_t capacity, valid, deleted, limit;
uint64_t key;
uint8_t spinner = 0U;
clock_t last_update = clock();
for (key = 0U; key < LIMIT; ++key)
{
const errno_t error = hash_map_insert64(hash_map, key, VALUE(key), 1);
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 (key = 0U; key < LIMIT; ++key)
{
const errno_t error = hash_map_remove64(hash_map, key, NULL);
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_map_size64(hash_map) != 0U)
{
puts("Invalid size!");
return EXIT_FAILURE;
}
PRINT_SET_INFO(4);
puts("---------");
return EXIT_SUCCESS;
}

16
test/hash-map/src/tests.h Normal file
View File

@ -0,0 +1,16 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#ifndef _TEST_TESTS_INCLUDED
#define _TEST_TESTS_INCLUDED
#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);
int test_function_4(hash_map64_t *const hash_set);
#endif /*_TEST_TESTS_INCLUDED*/

View File

@ -0,0 +1,476 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Shared|ARM64">
<Configuration>Shared</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Shared|Win32">
<Configuration>Shared</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Shared|x64">
<Configuration>Shared</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Static|ARM64">
<Configuration>Static</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Static|Win32">
<Configuration>Static</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Static|x64">
<Configuration>Static</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\shared\src\random_in.c" />
<ClCompile Include="..\shared\src\time_in.c" />
<ClCompile Include="src\main.c" />
<ClCompile Include="src\tests.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\shared\include\random_in.h" />
<ClInclude Include="..\shared\include\time_in.h" />
<ClInclude Include="src\tests.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\libhashset\libhashset.vcxproj">
<Project>{8cf3bd19-28b1-435d-b719-e00b052dfc3a}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{903FEC5F-92A1-4EE0-A6E7-47B31742DA68}</ProjectGuid>
<RootNamespace>test-hash-map</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
<ProjectName>test-hash-map</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Static|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LargeAddressAware>true</LargeAddressAware>
<MinimumRequiredVersion>5.1</MinimumRequiredVersion>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.1</MinimumRequiredVersion>
<LargeAddressAware>true</LargeAddressAware>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;HASHSET_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.1</MinimumRequiredVersion>
<LargeAddressAware>true</LargeAddressAware>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
<PostBuildEvent>
<Command>copy /B /Y /N "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" "$(TargetDir)libhashset-1.dll"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>cp "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" -&gt; "$(TargetDir)libhashset-1.dll"</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<MinimumRequiredVersion>5.2</MinimumRequiredVersion>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|x64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.2</MinimumRequiredVersion>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;HASHSET_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.2</MinimumRequiredVersion>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
<PostBuildEvent>
<Command>copy /B /Y /N "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" "$(TargetDir)libhashset-1.dll"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>cp "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" -&gt; "$(TargetDir)libhashset-1.dll"</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;HASHSET_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
<PostBuildEvent>
<Command>copy /B /Y /N "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" "$(TargetDir)libhashset-1.dll"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>cp "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" -&gt; "$(TargetDir)libhashset-1.dll"</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\tests.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\shared\src\random_in.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\shared\src\time_in.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\tests.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\shared\include\random_in.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\shared\include\time_in.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

27
test/hash-set/Makefile Normal file
View File

@ -0,0 +1,27 @@
include ../../config.mk
CFLAGS = -std=c99 -D_DEFAULT_SOURCE -Wall -Wpedantic -I../../libhashset/include -I../shared/include $(XCFLAGS)
LDFLAGS = -L../../libhashset/lib -lhashset-1 $(XLDFLAGS)
SRC_PATH := src
BIN_PATH := bin
ALL_PATH := $(SRC_PATH) $(BIN_PATH)
BIN_FILE := $(BIN_PATH)/test-hash-set$(EXE_SUFFIX)
SRC_FILE := $(wildcard $(SRC_PATH)/*.c) $(wildcard ../shared/src/*.c)
.PHONY: all clean test
all: clean $(ALL_PATH) $(BIN_FILE)
$(BIN_FILE): $(SRC_FILE)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
$(ALL_PATH):
mkdir -p $@
test: all
env $(ENV_LDPATH)="$(realpath .):$(realpath ../../libhashset/lib)$(if $($(ENV_LDPATH)),:$($(ENV_LDPATH)))" ./$(BIN_FILE)
clean:
rm -vf $(BIN_FILE)

View File

@ -4,6 +4,8 @@
/******************************************************************************/
#include "tests.h"
#include "../../shared/include/time_in.h"
#include <stdio.h>
#include <inttypes.h>
@ -23,11 +25,14 @@ while(0)
int main(void)
{
hash_set64_t *hash_set;
uint64_t clk_begin, clk_end;
printf("LibHashSet Test v%" PRIu16 ".%" PRIu16 ".%" PRIu16 " [%s]\n\n",
printf("LibHashSet Hash-Set Test v%" PRIu16 ".%" PRIu16 ".%" PRIu16 " [%s]\n\n",
HASHSET_VERSION_MAJOR, HASHSET_VERSION_MINOR, HASHSET_VERSION_PATCH, HASHSET_BUILD_DATE);
hash_set = hash_set_create64(0U, -1.0);
clk_begin = clock_query();
hash_set = hash_set_create64(0U, -1.0, clock_query());
if (!hash_set)
{
puts("Allocation has failed!");
@ -40,11 +45,13 @@ int main(void)
RUN_TEST_CASE(4);
hash_set_destroy64(hash_set);
puts("Tests completed successfully.");
clk_end = clock_query();
printf("Tests completed successfully [%.2f].\n\n", (clk_end - clk_begin) / ((double)clock_frequency()));
return EXIT_SUCCESS;
failure:
hash_set_destroy64(hash_set);
puts("\nSomething went wrong !!!");
puts("\nSomething went wrong !!!\n");
return EXIT_FAILURE;
}

View File

@ -4,7 +4,7 @@
/******************************************************************************/
#include "tests.h"
#include "random.h"
#include <random_in.h>
#include <stdio.h>
#include <inttypes.h>
@ -26,7 +26,7 @@
{\
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); \
fprintf(stdout, "[SET %d/%d] capacity: %010zu, valid: %010zu, deleted: %010zu, limit: %010zu\n", (X), TEST_COUNT, capacity, valid, deleted, limit); \
fflush(stdout); \
} \
} \
@ -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;
}
@ -101,7 +101,7 @@ int test_function_1(hash_set64_t *const hash_set)
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)
if (error != (((i != 3167U) && (i != 9887U) && (i != 387083U)) ? 0 : ENOENT))
{
printf("Contains operation has failed! (error: %d)\n", error);
return EXIT_FAILURE;
@ -180,10 +180,9 @@ int test_function_1(hash_set64_t *const hash_set)
int test_function_2(hash_set64_t *const hash_set)
{
size_t r, j, capacity, valid, deleted, limit;
size_t r, j, cursor, capacity, valid, deleted, limit;
uint64_t value;
uint8_t spinner = 0U, *test1, *test2;
uintptr_t cursor;
random_t random;
random_init(&random);
@ -315,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;
}
}

View File

@ -0,0 +1,476 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Shared|ARM64">
<Configuration>Shared</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Shared|Win32">
<Configuration>Shared</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Shared|x64">
<Configuration>Shared</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Static|ARM64">
<Configuration>Static</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Static|Win32">
<Configuration>Static</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Static|x64">
<Configuration>Static</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\shared\src\random_in.c" />
<ClCompile Include="..\shared\src\time_in.c" />
<ClCompile Include="src\main.c" />
<ClCompile Include="src\tests.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\shared\include\random_in.h" />
<ClInclude Include="..\shared\include\time_in.h" />
<ClInclude Include="src\tests.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\libhashset\libhashset.vcxproj">
<Project>{8cf3bd19-28b1-435d-b719-e00b052dfc3a}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{0b7abb95-b60f-418b-8386-930b1629058f}</ProjectGuid>
<RootNamespace>test-hash-set</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
<ProjectName>test-hash-set</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Static|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)\obj\$(PlatformToolset)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LargeAddressAware>true</LargeAddressAware>
<MinimumRequiredVersion>5.1</MinimumRequiredVersion>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.1</MinimumRequiredVersion>
<LargeAddressAware>true</LargeAddressAware>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|Win32'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;HASHSET_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.1</MinimumRequiredVersion>
<LargeAddressAware>true</LargeAddressAware>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
<PostBuildEvent>
<Command>copy /B /Y /N "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" "$(TargetDir)libhashset-1.dll"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>cp "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" -&gt; "$(TargetDir)libhashset-1.dll"</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<MinimumRequiredVersion>5.2</MinimumRequiredVersion>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|x64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.2</MinimumRequiredVersion>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|ARM64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|x64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;HASHSET_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<MinimumRequiredVersion>5.2</MinimumRequiredVersion>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
<PostBuildEvent>
<Command>copy /B /Y /N "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" "$(TargetDir)libhashset-1.dll"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>cp "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" -&gt; "$(TargetDir)libhashset-1.dll"</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Shared|ARM64'">
<ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;HASHSET_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>$(SolutionDir)libhashset\include;$(ProjectDir)..\shared\include</AdditionalIncludeDirectories>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4464;4710;4711;4820;5045</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<DelayLoadDLLs>advapi32.dll</DelayLoadDLLs>
<AdditionalDependencies>delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent />
<PostBuildEvent>
<Command>copy /B /Y /N "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" "$(TargetDir)libhashset-1.dll"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>cp "$(SolutionDir)lib\$(PlatformToolset)\$(Platform)\$(Configuration)\libhashset-1.dll" -&gt; "$(TargetDir)libhashset-1.dll"</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\tests.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\shared\src\random_in.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\shared\src\time_in.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\tests.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\shared\include\random_in.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\shared\include\time_in.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,15 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#ifndef _TEST_TIME_INCLUDED
#define _TEST_TIME_INCLUDED
#include <stdlib.h>
#include <stdint.h>
uint64_t clock_query(void);
uint64_t clock_frequency(void);
#endif /*_TEST_TIME_INCLUDED*/

View File

@ -3,11 +3,14 @@
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#include "random.h"
#include "../include/random_in.h"
#include <string.h>
#ifndef _WIN32
# include <unistd.h>
# if defined(__APPLE__) && defined(__MACH__)
# include <sys/random.h>
# endif
#endif
#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0U]))

45
test/shared/src/time_in.c Normal file
View File

@ -0,0 +1,45 @@
/******************************************************************************/
/* HashSet for C99, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#include "../include/time_in.h"
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN 1
# include <Windows.h>
#else
# include <time.h>
#endif
uint64_t clock_query(void)
{
#ifdef _WIN32
LARGE_INTEGER counter;
if (QueryPerformanceCounter(&counter))
{
return counter.QuadPart;
}
#else
struct timespec spec;
if (!clock_gettime(CLOCK_MONOTONIC, &spec))
{
return (((uint64_t)spec.tv_sec) * UINT64_C(1000000)) + (((uint64_t)spec.tv_nsec) / UINT64_C(10000));
}
#endif
abort();
}
uint64_t clock_frequency(void)
{
#ifdef _WIN32
LARGE_INTEGER frequency;
if (QueryPerformanceFrequency(&frequency))
{
return frequency.QuadPart;
}
abort();
#else
return UINT64_C(1000000);
#endif
}