ucx/map.h

Thu, 15 Oct 2015 14:21:38 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 15 Oct 2015 14:21:38 +0200
changeset 208
262c7be94eba
parent 206
58b77eb51afd
child 209
4f02199d8aae
permissions
-rw-r--r--

added convenience function ucx_map_free_contents()

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2015 Olaf Wintermann. All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  */
    29 /**
    30  * @file map.h
    31  * 
    32  * Hash map implementation.
    33  * 
    34  * This implementation uses murmur hash 2 and separate chaining with linked
    35  * lists.
    36  * 
    37  * @author Mike Becker
    38  * @author Olaf Wintermann
    39  */
    41 #ifndef UCX_MAP_H
    42 #define	UCX_MAP_H
    44 #include "ucx.h"
    45 #include "string.h"
    46 #include "allocator.h"
    47 #include <stdio.h>
    49 #ifdef	__cplusplus
    50 extern "C" {
    51 #endif
    53 /**
    54  * Loop statement for UCX maps.
    55  * 
    56  * The <code>key</code> variable is implicitly defined, but the
    57  * <code>value</code> variable must be already declared as type information
    58  * cannot be inferred.
    59  * 
    60  * @param key the variable name for the key
    61  * @param value the variable name for the value
    62  * @param iter an UcxMapIterator
    63  * @see ucx_map_iterator()
    64  */
    65 #define UCX_MAP_FOREACH(key,value,iter) \
    66         for(UcxKey key;ucx_map_iter_next(&iter,&key, (void**)&value);)
    68 /** Type for the UCX map. @see UcxMap */
    69 typedef struct UcxMap          UcxMap;
    71 /** Type for a key of an UcxMap. @see UcxKey */
    72 typedef struct UcxKey          UcxKey;
    74 /** Type for an element of an UcxMap. @see UcxMapElement */
    75 typedef struct UcxMapElement   UcxMapElement;
    77 /** Type for an iterator over an UcxMap. @see UcxMapIterator */
    78 typedef struct UcxMapIterator  UcxMapIterator;
    80 /** Structure for the UCX map. */
    81 struct UcxMap {
    82     /** An allocator that is used for the map elements. */
    83     UcxAllocator  *allocator;
    84     /** The array of map element lists. */
    85     UcxMapElement **map;
    86     /** The size of the map is the length of the element list array. */
    87     size_t        size;
    88     /** The count of elements currently stored in this map. */
    89     size_t        count;
    90 };
    92 /** Structure for a key of an UcxMap. */
    93 struct UcxKey {
    94     /** The key data. */
    95     void   *data;
    96     /** The length of the key data. */
    97     size_t len;
    98     /** The hash value of the key data. */
    99     int    hash;
   100 };
   102 /** Structure for an element of an UcxMap. */
   103 struct UcxMapElement {
   104     /** The value data. */
   105     void          *data;
   107     /** A pointer to the next element in the current list. */
   108     UcxMapElement *next;
   110     /** The corresponding key. */
   111     UcxKey        key;
   112 };
   114 /** Structure for an iterator over an UcxMap. */
   115 struct UcxMapIterator {
   116     /** The map to iterate over. */
   117     UcxMap        *map;
   119     /** The current map element. */
   120     UcxMapElement *cur;
   122     /**
   123      * The current index of the element list array.
   124      * <b>Attention: </b> this is <b>NOT</b> the element index! Do <b>NOT</b>
   125      * manually iterate over the map by increasing this index. Use
   126      * ucx_map_iter_next().
   127      * @see UcxMap.map*/
   128     size_t        index;
   129 };
   131 /**
   132  * Creates a new hash map with the specified size.
   133  * @param size the size of the hash map
   134  * @return a pointer to the new hash map
   135  */
   136 UcxMap *ucx_map_new(size_t size);
   138 /**
   139  * Creates a new hash map with the specified size using an UcxAllocator.
   140  * @param allocator the allocator to use
   141  * @param size the size of the hash map
   142  * @return a pointer to the new hash map
   143  */
   144 UcxMap *ucx_map_new_a(UcxAllocator *allocator, size_t size);
   146 /**
   147  * Frees a hash map.
   148  * 
   149  * <b>Note:</b> the contents are <b>not</b> freed, use ucx_map_free_content()
   150  * before calling this function to achieve that.
   151  * 
   152  * @param map the map to be freed
   153  * @see ucx_map_free_content()
   154  */
   155 void ucx_map_free(UcxMap *map);
   157 /**
   158  * Frees the contents of a hash map.
   159  * 
   160  * This is a convenience function that iterates over the map and passes all
   161  * values to the standard library free() function.
   162  * 
   163  * You must ensure, that it is valid to pass each value in the map to free().
   164  * 
   165  * You should free or clear the map afterwards, as the contents will be invalid.
   166  * 
   167  * @param map for which the contents shall be freed
   168  * @see ucx_map_free()
   169  * @see ucx_map_clear()
   170  */
   171 void ucx_map_free_content(UcxMap *map);
   173 /**
   174  * Clears a hash map.
   175  * 
   176  * <b>Note:</b> the contents are <b>not</b> freed, use ucx_map_free_content()
   177  * before calling this function to achieve that.
   178  * 
   179  * @param map the map to be cleared
   180  * @see ucx_map_free_content()
   181  */
   182 void ucx_map_clear(UcxMap *map);
   185 /**
   186  * Copies contents from a map to another map using a copy function.
   187  * 
   188  * <b>Note:</b> The destination map does not need to be empty. However, if it
   189  * contains data with keys that are also present in the source map, the contents
   190  * are overwritten.
   191  * 
   192  * @param from the source map
   193  * @param to the destination map
   194  * @param fnc the copy function or <code>NULL</code> if the pointer address
   195  * shall be copied
   196  * @param data additional data for the copy function
   197  * @return 0 on success or a non-zero value on memory allocation errors
   198  */
   199 int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to,
   200         copy_func fnc, void *data);
   202 /**
   203  * Clones the map and rehashes if necessary.
   204  * 
   205  * <b>Note:</b> In contrast to ucx_map_rehash() the load factor is irrelevant.
   206  * This function <i>always</i> ensures a new UcxMap.size of at least
   207  * 2.5*UcxMap.count.
   208  * 
   209  * @param map the map to clone
   210  * @param fnc the copy function to use or <code>NULL</code> if the new and
   211  * the old map shall share the data pointers
   212  * @param data additional data for the copy function
   213  * @return the cloned map
   214  * @see ucx_map_copy()
   215  */
   216 UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data);
   218 /**
   219  * Increases size of the hash map, if necessary.
   220  * 
   221  * The load value is 0.75*UcxMap.size. If the element count exceeds the load
   222  * value, the map needs to be rehashed. Otherwise no action is performed and
   223  * this function simply returns 0.
   224  * 
   225  * The rehashing process ensures, that the UcxMap.size is at least
   226  * 2.5*UcxMap.count. So there is enough room for additional elements without
   227  * the need of another soon rehashing.
   228  * 
   229  * You can use this function to dramatically increase access performance.
   230  * 
   231  * @param map the map to rehash
   232  * @return 1, if a memory allocation error occurred, 0 otherwise
   233  */
   234 int ucx_map_rehash(UcxMap *map);
   236 /**
   237  * Puts a key/value-pair into the map.
   238  * 
   239  * @param map the map
   240  * @param key the key
   241  * @param value the value
   242  * @return 0 on success, non-zero value on failure
   243  */
   244 int ucx_map_put(UcxMap *map, UcxKey key, void *value);
   246 /**
   247  * Retrieves a value by using a key.
   248  * 
   249  * @param map the map
   250  * @param key the key
   251  * @return the value
   252  */
   253 void* ucx_map_get(UcxMap *map, UcxKey key);
   255 /**
   256  * Removes a key/value-pair from the map by using the key.
   257  * 
   258  * @param map the map
   259  * @param key the key
   260  * @return the removed value
   261  */
   262 void* ucx_map_remove(UcxMap *map, UcxKey key);
   264 /**
   265  * Shorthand for putting data with a sstr_t key into the map.
   266  * @param map the map
   267  * @param key the key
   268  * @param value the value
   269  * @return 0 on success, non-zero value on failure
   270  * @see ucx_map_put()
   271  */
   272 #define ucx_map_sstr_put(map, key, value) \
   273     ucx_map_put(map, ucx_key(key.ptr, key.length), (void*)value)
   275 /**
   276  * Shorthand for putting data with a C string key into the map.
   277  * @param map the map
   278  * @param key the key
   279  * @param value the value
   280  * @return 0 on success, non-zero value on failure
   281  * @see ucx_map_put()
   282  */
   283 #define ucx_map_cstr_put(map, key, value) \
   284     ucx_map_put(map, ucx_key((void*)key, strlen(key)), (void*)value)
   286 /**
   287  * Shorthand for putting data with an integer key into the map.
   288  * @param map the map
   289  * @param key the key
   290  * @param value the value
   291  * @return 0 on success, non-zero value on failure
   292  * @see ucx_map_put()
   293  */
   294 #define ucx_map_int_put(map, key, value) \
   295     ucx_map_put(map, ucx_key((void*)&key, sizeof(key)), (void*)value)
   297 /**
   298  * Shorthand for getting data from the map with a sstr_t key.
   299  * @param map the map
   300  * @param key the key
   301  * @return the value
   302  * @see ucx_map_get()
   303  */
   304 #define ucx_map_sstr_get(map, key) \
   305     ucx_map_get(map, ucx_key(key.ptr, key.length))
   307 /**
   308  * Shorthand for getting data from the map with a C string key.
   309  * @param map the map
   310  * @param key the key
   311  * @return the value
   312  * @see ucx_map_get()
   313  */
   314 #define ucx_map_cstr_get(map, key) \
   315     ucx_map_get(map, ucx_key((void*)key, strlen(key)))
   317 /**
   318  * Shorthand for getting data from the map with an integer key.
   319  * @param map the map
   320  * @param key the key
   321  * @return the value
   322  * @see ucx_map_get()
   323  */
   324 #define ucx_map_int_get(map, key) \
   325     ucx_map_get(map, ucx_key((void*)&key, sizeof(int)))
   327 /**
   328  * Shorthand for removing data from the map with a sstr_t key.
   329  * @param map the map
   330  * @param key the key
   331  * @return the removed value
   332  * @see ucx_map_remove()
   333  */
   334 #define ucx_map_sstr_remove(map, key) \
   335     ucx_map_remove(map, ucx_key(key.ptr, key.length))
   337 /**
   338  * Shorthand for removing data from the map with a C string key.
   339  * @param map the map
   340  * @param key the key
   341  * @return the removed value
   342  * @see ucx_map_remove()
   343  */
   344 #define ucx_map_cstr_remove(map, key) \
   345     ucx_map_remove(map, ucx_key((void*)key, strlen(key)))
   347 /**
   348  * Shorthand for removing data from the map with an integer key.
   349  * @param map the map
   350  * @param key the key
   351  * @return the removed value
   352  * @see ucx_map_remove()
   353  */
   354 #define ucx_map_int_remove(map, key) \
   355     ucx_map_remove(map, ucx_key((void*)&key, sizeof(key)))
   357 /**
   358  * Creates an UcxKey based on the given data.
   359  * 
   360  * This function implicitly computes the hash.
   361  * 
   362  * @param data the data for the key
   363  * @param len the length of the data
   364  * @return an UcxKey with implicitly computed hash
   365  * @see ucx_hash()
   366  */
   367 UcxKey ucx_key(void *data, size_t len);
   369 /**
   370  * Computes a murmur hash-2.
   371  * 
   372  * @param data the data to hash
   373  * @param len the length of the data
   374  * @return the murmur hash-2 of the data
   375  */
   376 int ucx_hash(const char *data, size_t len);
   378 /**
   379  * Creates an iterator for a map.
   380  * 
   381  * <b>Note:</b> An UcxMapIterator iterates over all elements in all element
   382  * lists successively. Therefore the order highly depends on the key hashes and
   383  * may vary under different map sizes. So generally you may <b>NOT</b> rely on
   384  * the iteration order.
   385  * 
   386  * <b>Note:</b> The iterator is <b>NOT</b> initialized. You need to call
   387  * ucx_map_iter_next() at least once before accessing any information. However,
   388  * it is not recommended to access the fields of an UcxMapIterator directly.
   389  * 
   390  * @param map the map to create the iterator for
   391  * @return an iterator initialized on the first element of the
   392  * first element list
   393  * @see ucx_map_iter_next()
   394  */
   395 UcxMapIterator ucx_map_iterator(UcxMap *map);
   397 /**
   398  * Proceeds to the next element of the map (if any).
   399  * 
   400  * Subsequent calls on the same iterator proceed to the next element and
   401  * store the key/value-pair into the memory specified as arguments of this
   402  * function.
   403  * 
   404  * If no further elements are found, this function returns zero and leaves the
   405  * last found key/value-pair in memory.
   406  * 
   407  * @param iterator the iterator to use
   408  * @param key a pointer to the memory where to store the key
   409  * @param value a pointer to the memory where to store the value
   410  * @return 1, if another element was found, 0 if all elements has been processed
   411  * @see ucx_map_iterator()
   412  */
   413 int ucx_map_iter_next(UcxMapIterator *iterator, UcxKey *key, void **value);
   416 #ifdef	__cplusplus
   417 }
   418 #endif
   420 #endif	/* UCX_MAP_H */

mercurial