|
C Container Collection (CCC)
|
The Flat Hash Map Interface. More...


Go to the source code of this file.
The Flat Hash Map Interface.
A Flat Hash Map stores elements in a contiguous buffer and allows the user to retrieve them by key in amortized O(1). Elements in the table may be copied and moved, especially when rehashing occurs, so no pointer stability is available in this implementation.
A flat hash map requires the user to provide a pointer to the map, a type, a key field, a hash function, and a key three way comparator function. The hasher should be well tailored to the key being stored in the table to prevent collisions. Good variety in the upper bits of the hashed value will also result in faster performance. Currently, the flat hash map does not offer any default hash functions or hash strengthening algorithms so strong hash functions should be obtained by the user for the data set.
The current implementation will seek to use the best platform specific Single Instruction Multiple Data (SIMD) or Single Register Multiple Data (SRMD) instructions available. However, if for any reason the user wishes to use the most portable Single Register Multiple Data fallback implementation, there are many options.
If building this library separately to include its library file, add the flag to the build (and read INSTALL.md for more details).
If an install location other than the release folder is desired don't forget to add the install prefix.
If this library is being built as part of your project then define the flag as part of your configuration.
Or, add the flag to your CMakePresets.json.
Or, enable on a per target basis in your CMakeLists.txt.
Or finally, just define it before including the flat hash map header.
To shorten names in the interface, define the following preprocessor directive at the top of your file. The CCC_ prefix may then be omitted for only this container.
All types and functions can then be written without the CCC_ prefix.
Initialization Interface | |
Initialize the container with memory, callbacks, and permissions. When a fixed size map is required that will not have allocation permission, the user must declare the type name and size of the map they will use. | |
| #define | CCC_flat_hash_map_declare_fixed_map(fixed_map_type_name, type_name, capacity) |
| Declare a fixed size map type for use in the stack, heap, or data segment. Does not return a value. | |
| #define | CCC_flat_hash_map_fixed_capacity(fixed_map_type_name) CCC_private_flat_hash_map_fixed_capacity(fixed_map_type_name) |
| Obtain the capacity previously chosen for the fixed size map type. | |
| #define | CCC_flat_hash_map_initialize(map_pointer, type_name, key_field, hash, compare, allocate, context_data, capacity) |
| Initialize a map with a Buffer of types at compile time or runtime. | |
| #define | CCC_flat_hash_map_from(key_field, hash, compare, allocate, context_data, optional_capacity, array_compound_literal...) |
| Initialize a dynamic map at runtime from an initializer list. | |
| #define | CCC_flat_hash_map_with_capacity(type_name, key_field, hash, compare, allocate, context_data, capacity) |
| Initialize a dynamic map at runtime with at least the specified capacity. | |
| CCC_Result | CCC_flat_hash_map_copy (CCC_Flat_hash_map *destination, CCC_Flat_hash_map const *source, CCC_Allocator *allocate) |
| Copy the map at source to destination. | |
| CCC_Result | CCC_flat_hash_map_reserve (CCC_Flat_hash_map *map, size_t to_add, CCC_Allocator *allocate) |
| Reserve space required to add a specified number of elements to the map. If the current capacity is sufficient, do nothing. | |
Entry Interface | |
Obtain and operate on container entries for efficient queries when non-trivial control flow is needed. | |
| #define | CCC_flat_hash_map_entry_wrap(map_pointer, key_pointer) |
| Obtains an entry for the provided key in the table for future use. | |
| #define | CCC_flat_hash_map_and_modify_with(map_entry_pointer, type_name, closure_over_T...) |
| Modify an Occupied entry with a closure over user type T. | |
| #define | CCC_flat_hash_map_or_insert_with(map_entry_pointer, type_compound_literal...) |
| lazily insert the desired key value into the entry if it is Vacant. | |
| #define | CCC_flat_hash_map_insert_entry_with(map_entry_pointer, type_compound_literal...) |
| write the contents of the compound literal type_compound_literal to a slot. | |
| #define | CCC_flat_hash_map_swap_entry_wrap(map_pointer, type_pointer) |
| Invariantly inserts the key value wrapping out_handle. | |
| #define | CCC_flat_hash_map_remove_entry_wrap(map_entry_pointer) |
| Remove the entry from the table if Occupied. | |
| #define | CCC_flat_hash_map_try_insert_wrap(map_pointer, type_pointer) |
| Attempts to insert the key value wrapping key_val_array_pointer. | |
| #define | CCC_flat_hash_map_try_insert_with(map_pointer, key, type_compound_literal...) |
| lazily insert type_compound_literal into the map at key if key is absent. | |
| #define | CCC_flat_hash_map_insert_or_assign_wrap(map_pointer, type_pointer) |
| Invariantly inserts or overwrites a user struct into the table. | |
| #define | CCC_flat_hash_map_insert_or_assign_with(map_pointer, key, type_compound_literal...) |
| Inserts a new key value pair or overwrites the existing entry. | |
| #define | CCC_flat_hash_map_remove_key_value_wrap(map_pointer, type_output_pointer) |
| Removes the key value in the map storing the old value, if present, in the struct containing out_array_pointer provided by the user. | |
| CCC_Flat_hash_map_entry | CCC_flat_hash_map_entry (CCC_Flat_hash_map *map, void const *key) |
| Obtains an entry for the provided key in the table for future use. | |
| CCC_Flat_hash_map_entry * | CCC_flat_hash_map_and_modify (CCC_Flat_hash_map_entry *entry, CCC_Type_modifier *modify) |
| Modifies the provided entry if it is Occupied. | |
| CCC_Flat_hash_map_entry * | CCC_flat_hash_map_and_modify_context (CCC_Flat_hash_map_entry *entry, CCC_Type_modifier *modify, void *context) |
| Modifies the provided entry if it is Occupied. | |
| void * | CCC_flat_hash_map_or_insert (CCC_Flat_hash_map_entry const *entry, void const *type) |
| Inserts the struct with handle elem if the entry is Vacant. | |
| void * | CCC_flat_hash_map_insert_entry (CCC_Flat_hash_map_entry const *entry, void const *type) |
| Inserts the provided entry invariantly. | |
| CCC_Entry | CCC_flat_hash_map_swap_entry (CCC_Flat_hash_map *map, void *type_output) |
| Invariantly inserts the key value wrapping out_handle. | |
| CCC_Entry | CCC_flat_hash_map_remove_entry (CCC_Flat_hash_map_entry const *entry) |
| Remove the entry from the table if Occupied. | |
| CCC_Entry | CCC_flat_hash_map_try_insert (CCC_Flat_hash_map *map, void const *type) |
| Attempts to insert the key value wrapping key_val_handle. | |
| CCC_Entry | CCC_flat_hash_map_insert_or_assign (CCC_Flat_hash_map *map, void const *type) |
| Invariantly inserts or overwrites a user struct into the table. | |
| CCC_Entry | CCC_flat_hash_map_remove_key_value (CCC_Flat_hash_map *map, void *type_output) |
| Removes the key value in the map storing the old value, if present, in the struct containing out_handle provided by the user. | |
| void * | CCC_flat_hash_map_unwrap (CCC_Flat_hash_map_entry const *entry) |
| Unwraps the provided entry to obtain a view into the table element. | |
| CCC_Tribool | CCC_flat_hash_map_occupied (CCC_Flat_hash_map_entry const *entry) |
| Returns the Vacant or Occupied status of the entry. | |
| CCC_Tribool | CCC_flat_hash_map_insert_error (CCC_Flat_hash_map_entry const *entry) |
| Provides the status of the entry should an insertion follow. | |
| CCC_Entry_status | CCC_flat_hash_map_entry_status (CCC_Flat_hash_map_entry const *entry) |
| Obtain the entry status from a container entry. | |
Container Types | |
Types available in the container interface. | |
| typedef struct CCC_Flat_hash_map | CCC_Flat_hash_map |
| A container for storing key-value structures defined by the user in a contiguous buffer. | |
| typedef union CCC_Flat_hash_map_entry_wrap | CCC_Flat_hash_map_entry |
| A container specific entry used to implement the Entry Interface. | |
Membership Interface | |
Test membership or obtain references to stored user types directly. | |
| CCC_Tribool | CCC_flat_hash_map_contains (CCC_Flat_hash_map const *map, void const *key) |
| Searches the table for the presence of key. | |
| void * | CCC_flat_hash_map_get_key_value (CCC_Flat_hash_map const *map, void const *key) |
| Returns a reference into the table at entry key. | |
Deallocation Interface | |
Destroy the container. | |
| CCC_Result | CCC_flat_hash_map_clear (CCC_Flat_hash_map *map, CCC_Type_destructor *destroy) |
| Frees all slots in the table for use without affecting capacity. | |
| CCC_Result | CCC_flat_hash_map_clear_and_free (CCC_Flat_hash_map *map, CCC_Type_destructor *destroy) |
| Frees all slots in the table and frees the underlying buffer. | |
| CCC_Result | CCC_flat_hash_map_clear_and_free_reserve (CCC_Flat_hash_map *map, CCC_Type_destructor *destroy, CCC_Allocator *allocate) |
| Frees all slots in the table and frees the underlying Buffer that was previously dynamically reserved with the reserve function. | |
Iterator Interface | |
Obtain and manage iterators over the container. | |
| void * | CCC_flat_hash_map_begin (CCC_Flat_hash_map const *map) |
| Obtains a pointer to the first element in the table. | |
| void * | CCC_flat_hash_map_next (CCC_Flat_hash_map const *map, void const *type_iterator) |
| Advances the iterator to the next occupied table slot. | |
| void * | CCC_flat_hash_map_end (CCC_Flat_hash_map const *map) |
| Check the current iterator against the end for loop termination. | |
State Interface | |
Obtain the container state. | |
| CCC_Tribool | CCC_flat_hash_map_is_empty (CCC_Flat_hash_map const *map) |
| Returns the size status of the table. | |
| CCC_Count | CCC_flat_hash_map_count (CCC_Flat_hash_map const *map) |
| Returns the count of table occupied slots. | |
| CCC_Count | CCC_flat_hash_map_capacity (CCC_Flat_hash_map const *map) |
| Return the full capacity of the backing storage. | |
| CCC_Tribool | CCC_flat_hash_map_validate (CCC_Flat_hash_map const *map) |
| Validation of invariants for the hash table. | |
| #define CCC_flat_hash_map_and_modify_with | ( | map_entry_pointer, | |
| type_name, | |||
| closure_over_T... | |||
| ) |
Modify an Occupied entry with a closure over user type T.
| [in] | map_entry_pointer | a pointer to the obtained entry. |
| [in] | type_name | the name of the user type stored in the container. |
| [in] | closure_over_T | the code to be run on the reference to user type T, if Occupied. This may be a semicolon separated list of statements to execute on T or a section of code wrapped in braces {code here} which may be preferred for formatting. |
Note that any code written is only evaluated if the entry is Occupied and the container can deliver the user type T. This means any function calls are lazily evaluated in the closure scope.
| #define CCC_flat_hash_map_declare_fixed_map | ( | fixed_map_type_name, | |
| type_name, | |||
| capacity | |||
| ) |
Declare a fixed size map type for use in the stack, heap, or data segment. Does not return a value.
| [in] | fixed_map_type_name | the user chosen name of the fixed sized map. |
| [in] | type_name | the type the user plans to store in the map. It may have a key and value field as well as any additional fields. For set-like behavior, wrap a field in a struct/union (e.g. union int_node {int e;};). |
| [in] | capacity | the power of two capacity for the map. |
Once the location for the fixed size map is chosen–stack, heap, or data segment–provide a pointer to the map for the initialization macro.
Similarly, a fixed size map can be used on the stack.
The CCC_flat_hash_map_fixed_capacity macro can be used to obtain the previously provided capacity when declaring the fixed map type. Finally, one could allocate a fixed size map on the heap; however, it is usually better to initialize a dynamic map and use the CCC_flat_hash_map_reserve function for such a use case.
This macro is not needed when a dynamic resizing flat hash map is needed. For dynamic maps, simply pass NULL and 0 capacity to the initialization macro.
| #define CCC_flat_hash_map_entry_wrap | ( | map_pointer, | |
| key_pointer | |||
| ) |
Obtains an entry for the provided key in the table for future use.
| [in] | map_pointer | the hash table to be searched. |
| [in] | key_pointer | the key used to search the table matching the stored key type. |
An entry is a search result that provides either an Occupied or Vacant entry in the table. An occupied entry signifies that the search was successful. A Vacant entry means the search was not successful but we now have a handle to where in the table such an element should be inserted.
An entry is most often passed in a functional style to subsequent calls in the Entry Interface.
| #define CCC_flat_hash_map_fixed_capacity | ( | fixed_map_type_name | ) | CCC_private_flat_hash_map_fixed_capacity(fixed_map_type_name) |
Obtain the capacity previously chosen for the fixed size map type.
| [in] | fixed_map_type_name | the name of a previously declared map. |
| #define CCC_flat_hash_map_from | ( | key_field, | |
| hash, | |||
| compare, | |||
| allocate, | |||
| context_data, | |||
| optional_capacity, | |||
| array_compound_literal... | |||
| ) |
Initialize a dynamic map at runtime from an initializer list.
| [in] | key_field | the field of the struct used for key storage. |
| [in] | hash | the CCC_Key_hasher function provided by the user. |
| [in] | compare | the CCC_Key_comparator the user intends to use. |
| [in] | allocate | the required allocation function. |
| [in] | context_data | context data that is needed for hashing or comparison. |
| [in] | optional_capacity | optionally specify the capacity of the map if different from the size of the compound literal array initializer. If the capacity is greater than the size of the compound literal array initializer, it is respected and the capacity is reserved. If the capacity is less than the size of the compound array initializer, the compound literal array initializer size is set as the capacity. Therefore, 0 is valid if one is not concerned with the size of the underlying reservation. |
| [in] | array_compound_literal | a list of key value pairs of the type intended to be stored in the map, using array compound literal initialization syntax (e.g (struct My_type[]){{.k = 0, .v 0}, {.k = 1, .v = 1}}). |
Initialize a dynamic hash table at run time. This example requires no context data for initialization.
Only dynamic maps may be initialized this way due the inability of the hash map to protect its invariants from user error at compile time.
| #define CCC_flat_hash_map_initialize | ( | map_pointer, | |
| type_name, | |||
| key_field, | |||
| hash, | |||
| compare, | |||
| allocate, | |||
| context_data, | |||
| capacity | |||
| ) |
Initialize a map with a Buffer of types at compile time or runtime.
| [in] | map_pointer | a pointer to a fixed map allocation or NULL. |
| [in] | type_name | the name of the user defined type stored in the map. |
| [in] | key_field | the field of the struct used for key storage. |
| [in] | hash | the CCC_Key_hasher function provided by the user. |
| [in] | compare | the CCC_Key_comparator the user intends to use. |
| [in] | allocate | the allocation function for resizing or NULL if no resizing is allowed. |
| [in] | context_data | context data that is needed for hashing or comparison. |
| [in] | capacity | the capacity of a fixed size map or 0. |
Initialize a static fixed size hash map at compile time that has no allocation permission or context data needed.
Initialize a dynamic hash table at compile time with allocation permission and no context data. Use the same type as the previous example.
Initialization at runtime is also possible. Stack-based or dynamic maps are identical to the provided examples. Omit static in a runtime context.
| #define CCC_flat_hash_map_insert_entry_with | ( | map_entry_pointer, | |
| type_compound_literal... | |||
| ) |
write the contents of the compound literal type_compound_literal to a slot.
| [in] | map_entry_pointer | a pointer to the obtained entry. |
| [in] | type_compound_literal | the compound literal to write to a new slot. |
| #define CCC_flat_hash_map_insert_or_assign_with | ( | map_pointer, | |
| key, | |||
| type_compound_literal... | |||
| ) |
Inserts a new key value pair or overwrites the existing entry.
| [in] | map_pointer | the pointer to the flat hash map. |
| [in] | key | the key to be searched in the table. |
| [in] | type_compound_literal | the compound literal specifying the value. |
Note that for brevity and convenience the user need not write the key to the lazy value compound literal as well. This function ensures the key in the compound literal matches the searched key.
| #define CCC_flat_hash_map_insert_or_assign_wrap | ( | map_pointer, | |
| type_pointer | |||
| ) |
Invariantly inserts or overwrites a user struct into the table.
| [in] | map_pointer | a pointer to the flat hash map. |
| [in] | type_pointer | the complete key and value type to be inserted. |
Note that this function can be used when the old user type is not needed but the information regarding its presence is helpful.
| #define CCC_flat_hash_map_or_insert_with | ( | map_entry_pointer, | |
| type_compound_literal... | |||
| ) |
lazily insert the desired key value into the entry if it is Vacant.
| [in] | map_entry_pointer | a pointer to the obtained entry. |
| [in] | type_compound_literal | the compound literal to construct in place if the entry is Vacant. |
Note that if the compound literal uses any function calls to generate values or other data, such functions will not be called if the entry is Occupied.
| #define CCC_flat_hash_map_remove_entry_wrap | ( | map_entry_pointer | ) |
Remove the entry from the table if Occupied.
| [in] | map_entry_pointer | a pointer to the table entry. |
| #define CCC_flat_hash_map_remove_key_value_wrap | ( | map_pointer, | |
| type_output_pointer | |||
| ) |
Removes the key value in the map storing the old value, if present, in the struct containing out_array_pointer provided by the user.
| [in] | map_pointer | the pointer to the flat hash map. |
| [out] | type_output_pointer | the complete key and value type to be removed |
Note that this function may write to the struct containing the second parameter and wraps it in an entry to provide information about the old value.
| #define CCC_flat_hash_map_swap_entry_wrap | ( | map_pointer, | |
| type_pointer | |||
| ) |
Invariantly inserts the key value wrapping out_handle.
| [in] | map_pointer | the pointer to the flat hash map. |
| [out] | type_pointer | the complete key and value type to be inserted. |
Note that this function may write to the struct containing the second parameter and wraps it in an entry to provide information about the old value.
| #define CCC_flat_hash_map_try_insert_with | ( | map_pointer, | |
| key, | |||
| type_compound_literal... | |||
| ) |
lazily insert type_compound_literal into the map at key if key is absent.
| [in] | map_pointer | a pointer to the flat hash map. |
| [in] | key | the direct key r-value. |
| [in] | type_compound_literal | the compound literal specifying the value. |
int and you pass a size_t variable to the key argument, you will overwrite adjacent bytes of your struct.Note that for brevity and convenience the user need not write the key to the lazy value compound literal as well. This function ensures the key in the compound literal matches the searched key.
| #define CCC_flat_hash_map_try_insert_wrap | ( | map_pointer, | |
| type_pointer | |||
| ) |
Attempts to insert the key value wrapping key_val_array_pointer.
| [in] | map_pointer | the pointer to the flat hash map. |
| [in] | type_pointer | the complete key and value type to be inserted. |
| #define CCC_flat_hash_map_with_capacity | ( | type_name, | |
| key_field, | |||
| hash, | |||
| compare, | |||
| allocate, | |||
| context_data, | |||
| capacity | |||
| ) |
Initialize a dynamic map at runtime with at least the specified capacity.
| [in] | type_name | the name of the type being stored in the map. |
| [in] | key_field | the field of the struct used for key storage. |
| [in] | hash | the CCC_Key_hasher function provided by the user. |
| [in] | compare | the CCC_Key_comparator the user intends to use. |
| [in] | allocate | the required allocation function. |
| [in] | context_data | context data that is needed for hashing or comparison. |
| [in] | capacity | the desired capacity for the map. A capacity of 0 results in an argument error and is a no-op after the map is initialized empty. |
Initialize a dynamic hash table at run time. This example requires no context data for initialization.
Only dynamic maps may be initialized this way as it simply combines the steps of initialization and reservation.
| typedef struct CCC_Flat_hash_map CCC_Flat_hash_map |
A container for storing key-value structures defined by the user in a contiguous buffer.
A flat hash map can be initialized on the stack, heap, or data segment at runtime or compile time.
| typedef union CCC_Flat_hash_map_entry_wrap CCC_Flat_hash_map_entry |
A container specific entry used to implement the Entry Interface.
The Entry Interface offers efficient search and subsequent insertion, deletion, or value update based on the needs of the user.
| CCC_Flat_hash_map_entry * CCC_flat_hash_map_and_modify | ( | CCC_Flat_hash_map_entry * | entry, |
| CCC_Type_modifier * | modify | ||
| ) |
Modifies the provided entry if it is Occupied.
| [in] | entry | the entry obtained from an entry function or macro. |
| [in] | modify | an update function in which the context argument is unused. |
This function is intended to make the function chaining in the Entry Interface more succinct if the entry will be modified in place based on its own value without the need of the context argument a CCC_Type_modifier can provide.
| CCC_Flat_hash_map_entry * CCC_flat_hash_map_and_modify_context | ( | CCC_Flat_hash_map_entry * | entry, |
| CCC_Type_modifier * | modify, | ||
| void * | context | ||
| ) |
Modifies the provided entry if it is Occupied.
| [in] | entry | the entry obtained from an entry function or macro. |
| [in] | modify | an update function that requires context data. |
| [in] | context | context data required for the update. |
This function makes full use of a CCC_Type_modifier capability, meaning a complete CCC_update object will be passed to the update function callback.
| void * CCC_flat_hash_map_begin | ( | CCC_Flat_hash_map const * | map | ) |
Obtains a pointer to the first element in the table.
| [in] | map | the table to iterate through. |
Iteration starts from index 0 by capacity of the table so iteration order is not obvious to the user, nor should any specific order be relied on.
| CCC_Count CCC_flat_hash_map_capacity | ( | CCC_Flat_hash_map const * | map | ) |
Return the full capacity of the backing storage.
| [in] | map | the hash table. |
| CCC_Result CCC_flat_hash_map_clear | ( | CCC_Flat_hash_map * | map, |
| CCC_Type_destructor * | destroy | ||
| ) |
Frees all slots in the table for use without affecting capacity.
| [in] | map | the table to be cleared. |
| [in] | destroy | the destructor for each element. NULL can be passed if no maintenance is required on the elements in the table before their slots are forfeit. |
If NULL is passed as the destructor function time is O(1), else O(capacity).
| CCC_Result CCC_flat_hash_map_clear_and_free | ( | CCC_Flat_hash_map * | map, |
| CCC_Type_destructor * | destroy | ||
| ) |
Frees all slots in the table and frees the underlying buffer.
| [in] | map | the table to be cleared. |
| [in] | destroy | the destructor for each element. NULL can be passed if no maintenance is required on the elements in the table before their slots are forfeit. |
| CCC_Result CCC_flat_hash_map_clear_and_free_reserve | ( | CCC_Flat_hash_map * | map, |
| CCC_Type_destructor * | destroy, | ||
| CCC_Allocator * | allocate | ||
| ) |
Frees all slots in the table and frees the underlying Buffer that was previously dynamically reserved with the reserve function.
| [in] | map | the table to be cleared. |
| [in] | destroy | the destructor for each element. NULL can be passed if no maintenance is required on the elements in the table before their slots are forfeit. |
| [in] | allocate | the required allocation function to provide to a dynamically reserved map. Any context data provided upon initialization will be passed to the allocation function when called. |
This function covers the edge case of reserving a dynamic capacity for a map at runtime but denying the map allocation permission to resize. This can help prevent a map from growing untree due to internal decisions about rehashes and resizing. The user in this case knows the map does not have allocation permission and therefore no further memory will be dedicated to the map.
However, to free the map in such a case this function must be used because the map has no ability to free itself. Just as the allocation function is required to reserve memory so to is it required to free memory.
This function will work normally if called on a map with allocation permission however the normal CCC_flat_hash_map_clear_and_free is sufficient for that use case.
| CCC_Tribool CCC_flat_hash_map_contains | ( | CCC_Flat_hash_map const * | map, |
| void const * | key | ||
| ) |
Searches the table for the presence of key.
| [in] | map | the flat hash table to be searched. |
| [in] | key | pointer to the key matching the key type of the user struct. |
| CCC_Result CCC_flat_hash_map_copy | ( | CCC_Flat_hash_map * | destination, |
| CCC_Flat_hash_map const * | source, | ||
| CCC_Allocator * | allocate | ||
| ) |
Copy the map at source to destination.
| [in] | destination | the initialized destination for the copy of the source map. |
| [in] | source | the initialized source of the map. |
| [in] | allocate | the optional allocation function if resizing is needed. |
Note that there are two ways to copy data from source to destination: provide sufficient memory and pass NULL as allocate, or allow the copy function to take care of allocation for the copy.
Manual memory management with no allocation function provided.
The above requires destination capacity be greater than or equal to source capacity. Here is memory management handed over to the copy function.
The above allows destination to have a capacity less than that of the source as long as copy has been provided an allocation function to resize destination. Note that this would still work if copying to a destination that the user wants as a fixed size map.
The above sets up destination with fixed size while source is a dynamic map. Because an allocation function is provided, the destination is resized once for the copy and retains its fixed size after the copy is complete. This would require the user to manually free the underlying Buffer at destination eventually if this method is used. Usually it is better to allocate the memory with the reserve function if maps with one-time allocation requirements are used.
These options allow users to stay consistent across containers with their memory management strategies.
| CCC_Count CCC_flat_hash_map_count | ( | CCC_Flat_hash_map const * | map | ) |
Returns the count of table occupied slots.
| [in] | map | the hash table. |
| void * CCC_flat_hash_map_end | ( | CCC_Flat_hash_map const * | map | ) |
Check the current iterator against the end for loop termination.
| [in] | map | the table being iterated upon. |
| CCC_Flat_hash_map_entry CCC_flat_hash_map_entry | ( | CCC_Flat_hash_map * | map, |
| void const * | key | ||
| ) |
Obtains an entry for the provided key in the table for future use.
| [in] | map | the hash table to be searched. |
| [in] | key | the key used to search the table matching the stored key type. |
An entry is a search result that provides either an Occupied or Vacant entry in the table. An occupied entry signifies that the search was successful. A Vacant entry means the search was not successful but we now have a handle to where in the table such an element should be inserted.
An entry is rarely useful on its own. It should be passed in a functional style to subsequent calls in the Entry Interface.
| CCC_Entry_status CCC_flat_hash_map_entry_status | ( | CCC_Flat_hash_map_entry const * | entry | ) |
Obtain the entry status from a container entry.
| [in] | entry | a pointer to the entry. |
Note that this function can be useful for debugging or if more detailed messages are needed for logging purposes. See CCC_entry_status_message() in ccc/types.h for more information on detailed entry statuses.
| void * CCC_flat_hash_map_get_key_value | ( | CCC_Flat_hash_map const * | map, |
| void const * | key | ||
| ) |
Returns a reference into the table at entry key.
| [in] | map | the flat hash map to search. |
| [in] | key | the key to search matching stored key type. |
| void * CCC_flat_hash_map_insert_entry | ( | CCC_Flat_hash_map_entry const * | entry, |
| void const * | type | ||
| ) |
Inserts the provided entry invariantly.
| [in] | entry | the entry returned from a call obtaining an entry. |
| [in] | type | the complete key and value type to be inserted. |
This method can be used when the old value in the table does not need to be preserved. See the regular insert method if the old value is of interest. If an error occurs during the insertion process due to memory limitations or a search error NULL is returned. Otherwise insertion should not fail.
| CCC_Tribool CCC_flat_hash_map_insert_error | ( | CCC_Flat_hash_map_entry const * | entry | ) |
Provides the status of the entry should an insertion follow.
| [in] | entry | the entry from a query to the table via function or macro. |
Table resizing occurs upon calls to entry functions/macros or when trying to insert a new element directly. This is to provide stable entries from the time they are obtained to the time they are used in functions they are passed to (i.e. the idiomatic or_insert(entry(...)...)).
However, if a Vacant entry is returned and then a subsequent insertion function is used, it will not work if resizing has failed and the return of those functions will indicate such a failure. One can also confirm an insertion error will occur from an entry with this function. For example, leaving this function in an assert for debug builds can be a helpful sanity check.
| CCC_Entry CCC_flat_hash_map_insert_or_assign | ( | CCC_Flat_hash_map * | map, |
| void const * | type | ||
| ) |
Invariantly inserts or overwrites a user struct into the table.
| [in] | map | a pointer to the flat hash map. |
| [in] | type | the complete key and value type to be inserted. |
Note that this function can be used when the old user type is not needed but the information regarding its presence is helpful.
| CCC_Tribool CCC_flat_hash_map_is_empty | ( | CCC_Flat_hash_map const * | map | ) |
Returns the size status of the table.
| [in] | map | the hash table. |
| void * CCC_flat_hash_map_next | ( | CCC_Flat_hash_map const * | map, |
| void const * | type_iterator | ||
| ) |
Advances the iterator to the next occupied table slot.
| [in] | map | the table being iterated upon. |
| [in] | type_iterator | the previous iterator. |
| CCC_Tribool CCC_flat_hash_map_occupied | ( | CCC_Flat_hash_map_entry const * | entry | ) |
Returns the Vacant or Occupied status of the entry.
| [in] | entry | the entry from a query to the table via function or macro. |
| void * CCC_flat_hash_map_or_insert | ( | CCC_Flat_hash_map_entry const * | entry, |
| void const * | type | ||
| ) |
Inserts the struct with handle elem if the entry is Vacant.
| [in] | entry | the entry obtained via function or macro call. |
| [in] | type | the complete key and value type to be inserted. |
Because this functions takes an entry and inserts if it is Vacant, the only reason NULL shall be returned is when an insertion error will occur, usually due to a resizing memory error. This can happen if the table is not allowed to resize because no allocation function is provided.
| CCC_Entry CCC_flat_hash_map_remove_entry | ( | CCC_Flat_hash_map_entry const * | entry | ) |
Remove the entry from the table if Occupied.
| [in] | entry | a pointer to the table entry. |
| CCC_Entry CCC_flat_hash_map_remove_key_value | ( | CCC_Flat_hash_map * | map, |
| void * | type_output | ||
| ) |
Removes the key value in the map storing the old value, if present, in the struct containing out_handle provided by the user.
| [in] | map | the pointer to the flat hash map. |
| [out] | type_output | the complete key and value type to be removed |
Note that this function may write to the struct containing the second parameter and wraps it in an entry to provide information about the old value.
| CCC_Result CCC_flat_hash_map_reserve | ( | CCC_Flat_hash_map * | map, |
| size_t | to_add, | ||
| CCC_Allocator * | allocate | ||
| ) |
Reserve space required to add a specified number of elements to the map. If the current capacity is sufficient, do nothing.
| [in] | map | a pointer to the hash map. |
| [in] | to_add | the number of elements to add to the map. |
| [in] | allocate | the required allocation function that can be used for resizing. Such a function is provided to cover the case where the user wants a fixed size map but cannot know the size needed until runtime. In this case, the function needs to be provided to allow the single resizing to occur. Any context data provided upon initialization will be passed to the allocation function when called. |
If the map has already been initialized with allocation permission simply provide the same function that was passed upon initialization.
| CCC_Entry CCC_flat_hash_map_swap_entry | ( | CCC_Flat_hash_map * | map, |
| void * | type_output | ||
| ) |
Invariantly inserts the key value wrapping out_handle.
| [in] | map | the pointer to the flat hash map. |
| [out] | type_output | the complete key and value type to be inserted. |
Note that this function may write to the struct containing the second parameter and wraps it in an entry to provide information about the old value.
| CCC_Entry CCC_flat_hash_map_try_insert | ( | CCC_Flat_hash_map * | map, |
| void const * | type | ||
| ) |
Attempts to insert the key value wrapping key_val_handle.
| [in] | map | the pointer to the flat hash map. |
| [in] | type | the complete key and value type to be inserted. |
| void * CCC_flat_hash_map_unwrap | ( | CCC_Flat_hash_map_entry const * | entry | ) |
Unwraps the provided entry to obtain a view into the table element.
| [in] | entry | the entry from a query to the table via function or macro. |
| CCC_Tribool CCC_flat_hash_map_validate | ( | CCC_Flat_hash_map const * | map | ) |
Validation of invariants for the hash table.
| [in] | map | the table to validate. |