hash = gm_create_hash (gm_hash_compare_strings, gm_hash_hash_string, 0, 0, 0, 0);
As another example,
hash = gm_create_hash (gm_hash_compare_ints, gm_hash_hash_int, sizeof (int), sizeof (struct my_big_struct), 100, 0);
ints as keys and returns pointers to copies of the inserted structures. All storage for the keys and data is automatically managed by the hash table. In this case, all pointers to hash keys and data passed by GM to the client will point to GM-managed buffers. This function also preallocates enough storage for 100 hash entries, guaranteeing that at least 100 key/data pairs can be inserted in the table if the hash table creation succeeds.The automatic storage management option of GM not only is convenient, but also is extremely space efficient for keys and data no larger than a pointer, because when keys and data are no larger than a pointer, GM automatically stores them in the space reserved for the pointer to the key or data, rather than allocating a separate buffer.
Note that all keys and data buffers are referred to by pointers, not by value. This allows keys and data buffers of arbitrary size to be used. As a special (but common) case, however, one may wish to use pointers as keys directly, rather than use what they point to. In this special case, use the following initialization, and pass the keys (pointers) directly to the API, rather than the usual references to the keys.
hash = gm_create_hash (gm_hash_compare_ptrs, gm_hash_hash_ptr, 0, DATA_LEN, MIN_CNT, FLAGS);
Some day the GM hash table API may be extended, but the current API is as follows:
The parameters are as follows:
GM_CLIENT_COMPARE The function used to compare keys and may be any of gm_hash_compare_ints(), gm_hash_compare_longs(), gm_hash_compare_ptrs(), gm_hash_compare_strings(), or may be a client-defined function.
GM_CLIENT_HASH The function to be used to hash keys and may be any of gm_hash_hash_int(), gm_hash_hash_long(), gm_hash_hash_ptr(), gm_hash_hash_string(), or may be a client-defined function.
KEY_LEN specifies the length of the keys to be used for the hash table, or `0' if the keys should not be copied into GM-managed buffers.
DATA_LEN specifies the length of the data to be stored in the hash table, or `0' if the data should not be copied into GM-managed buffers.
MIN_CNT specifies the number of entries for which storage should be preallocated.
FLAGS should be `0' because no flags are currently defined.
Because marks need not be initialized before use, they can actually be used to determine if other objects have been initialized. This is done by putting a mark in the object, and adding the mark to a "mark set of marks in initialized objects" once the object has been initialized. This is similar to one common use of "magic numbers" for debugging purposes, except that it is immune to the possibility that the uninitialized magic number contained the magic number before initialization, so such marks can be used for non-debugging purposes. Therefore, marks can be used in ways that magic numbers cannot.
Marks have a nice set of properties that each mark in a mark set has a unique value and if this value is corrupted, then the mark is implicitly removed from the mark set. This makes marks useful for detecting memory corruption, and are less prone to false negatives than are magic numbers, which proliferate copies of a single value.
Finally, marks are location-dependent. This means that if a mark is copied, the copy will not be a member of the mark set.
The following APIs are provided:
1.4.4