documented map.h + changed return value of ucx_map_iter_next()

Mon, 12 Aug 2013 14:39:51 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 12 Aug 2013 14:39:51 +0200
changeset 138
7800811078b8
parent 136
b798f2eed26a
child 139
dddb9348ea42

documented map.h + changed return value of ucx_map_iter_next()

ucx/logging.c file | annotate | diff | comparison | revisions
ucx/logging.h file | annotate | diff | comparison | revisions
ucx/map.c file | annotate | diff | comparison | revisions
ucx/map.h file | annotate | diff | comparison | revisions
ucx/mempool.c file | annotate | diff | comparison | revisions
ucx/test.c file | annotate | diff | comparison | revisions
ucx/test.h file | annotate | diff | comparison | revisions
ucx/utils.h file | annotate | diff | comparison | revisions
     1.1 --- a/ucx/logging.c	Fri Aug 09 15:29:26 2013 +0200
     1.2 +++ b/ucx/logging.c	Mon Aug 12 14:39:51 2013 +0200
     1.3 @@ -64,7 +64,7 @@
     1.4  void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file,
     1.5          const unsigned int line, const char *format, ...) {
     1.6      if (level <= logger->level) {
     1.7 -        const size_t max = 4096; // estimated maximum message length
     1.8 +        const size_t max = 4096; // estimated max. message length (documented)
     1.9          char msg[max];
    1.10          char *text;
    1.11          size_t k = 0;
     2.1 --- a/ucx/logging.h	Fri Aug 09 15:29:26 2013 +0200
     2.2 +++ b/ucx/logging.h	Mon Aug 12 14:39:51 2013 +0200
     2.3 @@ -148,6 +148,9 @@
     2.4   * 
     2.5   * <code>[LEVEL] [TIMESTAMP] [SOURCEFILE]:[LINENO] message</code>
     2.6   * 
     2.7 + * <b>Attention:</b> the message (including automatically generated information)
     2.8 + * <b>MUST NOT</b> exceed the size of 4 KB.
     2.9 + * 
    2.10   * @param logger the logger to use
    2.11   * @param level the level to log on
    2.12   * @param file information about the source file
     3.1 --- a/ucx/map.c	Fri Aug 09 15:29:26 2013 +0200
     3.2 +++ b/ucx/map.c	Mon Aug 12 14:39:51 2013 +0200
     3.3 @@ -89,8 +89,7 @@
     3.4      UcxMapIterator i = ucx_map_iterator(from);
     3.5      void *value;
     3.6      UCX_MAP_FOREACH(key, value, i) {
     3.7 -        int ret = ucx_map_put(to, i.cur->key, fnc ? fnc(value, data) : value);
     3.8 -        if(ret != 0) {
     3.9 +        if (ucx_map_put(to, key, fnc ? fnc(value, data) : value)) {
    3.10              return 1;
    3.11          }
    3.12      }
    3.13 @@ -100,7 +99,7 @@
    3.14  UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data) {
    3.15      size_t bs = (map->count * 5) >> 1;
    3.16      UcxMap *newmap = ucx_map_new(bs > map->size ? bs : map->size);
    3.17 -    if(newmap == NULL) {
    3.18 +    if (!newmap) {
    3.19          return NULL;
    3.20      }
    3.21      ucx_map_copy(map, newmap, fnc, data);
    3.22 @@ -121,7 +120,7 @@
    3.23                  map->allocator->pool,
    3.24                  map->size,
    3.25                  sizeof(UcxMapElement*));
    3.26 -        if(map->map == NULL) {
    3.27 +        if (!map->map) {
    3.28              *map = oldmap;
    3.29              return 1;
    3.30          }
    3.31 @@ -137,7 +136,7 @@
    3.32  int ucx_map_put(UcxMap *map, UcxKey key, void *data) {
    3.33      UcxAllocator *allocator = map->allocator;
    3.34      
    3.35 -    if(key.hash == 0) {
    3.36 +    if (key.hash == 0) {
    3.37          key.hash = ucx_hash((char*)key.data, key.len);
    3.38      }
    3.39  
    3.40 @@ -145,16 +144,16 @@
    3.41      UcxMapElement *restrict elm = map->map[slot];
    3.42      UcxMapElement *restrict prev = NULL;
    3.43  
    3.44 -    while (elm != NULL && elm->key.hash < key.hash) {
    3.45 +    while (elm && elm->key.hash < key.hash) {
    3.46          prev = elm;
    3.47          elm = elm->next;
    3.48      }
    3.49      
    3.50 -    if (elm == NULL || elm->key.hash != key.hash) {
    3.51 +    if (!elm || elm->key.hash != key.hash) {
    3.52          UcxMapElement *e = (UcxMapElement*)allocator->malloc(
    3.53                  allocator->pool,
    3.54                  sizeof(UcxMapElement));
    3.55 -        if(e == NULL) {
    3.56 +        if (!e) {
    3.57              return -1;
    3.58          }
    3.59          e->key.data = NULL;
    3.60 @@ -167,9 +166,9 @@
    3.61          elm = e;
    3.62      }
    3.63      
    3.64 -    if(elm->key.data == NULL) {
    3.65 +    if (!elm->key.data) {
    3.66          void *kd = allocator->malloc(allocator->pool, key.len);
    3.67 -        if (kd == NULL) {
    3.68 +        if (!kd) {
    3.69              return -1;
    3.70          }
    3.71          memcpy(kd, key.data, key.len);
    3.72 @@ -285,31 +284,31 @@
    3.73  int ucx_map_iter_next(UcxMapIterator *i, UcxKey *key, void **elm) {
    3.74      UcxMapElement *e = i->cur;
    3.75      
    3.76 -    if(e == NULL) {
    3.77 +    if (e) {
    3.78 +        e = e->next;
    3.79 +    } else {
    3.80          e = i->map->map[0];
    3.81 -    } else {
    3.82 -        e = e->next;
    3.83      }
    3.84      
    3.85 -    while(i->index < i->map->size) {
    3.86 -        if(e != NULL) {
    3.87 -            if(e->data != NULL) {
    3.88 +    while (i->index < i->map->size) {
    3.89 +        if (e) {
    3.90 +            if (e->data) {
    3.91                  i->cur = e;
    3.92                  *elm = e->data;
    3.93                  *key = e->key;
    3.94 -                return 0;
    3.95 +                return 1;
    3.96              }
    3.97  
    3.98              e = e->next;
    3.99          } else {
   3.100              i->index++;
   3.101              
   3.102 -            if(i->index < i->map->size) {
   3.103 +            if (i->index < i->map->size) {
   3.104                  e = i->map->map[i->index];
   3.105              }
   3.106          }
   3.107      }
   3.108      
   3.109 -    return 1;
   3.110 +    return 0;
   3.111  }
   3.112  
     4.1 --- a/ucx/map.h	Fri Aug 09 15:29:26 2013 +0200
     4.2 +++ b/ucx/map.h	Mon Aug 12 14:39:51 2013 +0200
     4.3 @@ -50,36 +50,74 @@
     4.4  extern "C" {
     4.5  #endif
     4.6  
     4.7 -#define UCX_MAP_FOREACH(key,elm,iter) \
     4.8 -        for(UcxKey key;ucx_map_iter_next(&iter,&key, (void**)&elm)==0;)
     4.9 +/**
    4.10 + * Loop statement for UCX maps.
    4.11 + * 
    4.12 + * The <code>key</code> variable is implicitly defined, but the
    4.13 + * <code>value</code> variable must be already declared as type information
    4.14 + * cannot be inferred.
    4.15 + * 
    4.16 + * @param key the variable name for the key
    4.17 + * @param value the variable name for the value
    4.18 + * @param iter an UcxMapIterator
    4.19 + * @see ucx_map_iterator()
    4.20 + */
    4.21 +#define UCX_MAP_FOREACH(key,value,iter) \
    4.22 +        for(UcxKey key;ucx_map_iter_next(&iter,&key, (void**)&value);)
    4.23  
    4.24 +/** Type for the UCX map. @see UcxMap */
    4.25  typedef struct UcxMap          UcxMap;
    4.26 +/** Type for a key of an UcxMap. @see UcxKey */
    4.27  typedef struct UcxKey          UcxKey;
    4.28 +/** Type for an element of an UcxMap. @see UcxMapElement */
    4.29  typedef struct UcxMapElement   UcxMapElement;
    4.30 +/** Type for an iterator over an UcxMap. @see UcxMapIterator */
    4.31  typedef struct UcxMapIterator  UcxMapIterator;
    4.32  
    4.33 +/** Structure for the UCX map. */
    4.34  struct UcxMap {
    4.35 +    /** An allocator that is used for the map elements. */
    4.36      UcxAllocator  *allocator;
    4.37 +    /** The array of map element lists. */
    4.38      UcxMapElement **map;
    4.39 +    /** The size of the map is the length of the element list array. */
    4.40      size_t        size;
    4.41 +    /** The count of elements currently stored in this map. */
    4.42      size_t        count;
    4.43  };
    4.44  
    4.45 +/** Structure for a key of an UcxMap. */
    4.46  struct UcxKey {
    4.47 +    /** The key data. */
    4.48      void   *data;
    4.49 +    /** The length of the key data. */
    4.50      size_t len;
    4.51 +    /** The hash value of the key data. */
    4.52      int    hash;
    4.53  };
    4.54  
    4.55 +/** Structure for an element of an UcxMap. */
    4.56  struct UcxMapElement {
    4.57 +    /** The value data. */
    4.58      void          *data;
    4.59 +    /** A pointer to the next element in the current list. */
    4.60      UcxMapElement *next;
    4.61 +    /** The corresponding key. */
    4.62      UcxKey        key;
    4.63  };
    4.64  
    4.65 +/** Structure for an iterator over an UcxMap. */
    4.66  struct UcxMapIterator {
    4.67 +    /** The map to iterate over. */
    4.68      UcxMap        *map;
    4.69 +    /** The current map element. */
    4.70      UcxMapElement *cur;
    4.71 +    /**
    4.72 +     * The current index of the element list array.
    4.73 +     * <b>Attention: </b> this is <b>NOT</b> the element index! Do <b>NOT</b>
    4.74 +     * manually iterate over the map by increasing this index. Use
    4.75 +     * ucx_map_iter_next().
    4.76 +     * @see UcxMap.map*/
    4.77      size_t        index;
    4.78  };
    4.79  
    4.80 @@ -108,14 +146,83 @@
    4.81   */
    4.82  void ucx_map_free(UcxMap *map);
    4.83  
    4.84 -/* you cannot clone maps with more than 390 mio entries */
    4.85 +/**
    4.86 + * Copies contents from a map to another map using a copy function.
    4.87 + * 
    4.88 + * <b>Note:</b> The destination map does not need to be empty. However, if it
    4.89 + * contains data with keys that are also present in the source map, the contents
    4.90 + * are overwritten.
    4.91 + * 
    4.92 + * @param from the source map
    4.93 + * @param to the destination map
    4.94 + * @param fnc the copy function or <code>NULL</code> if the pointer address
    4.95 + * shall be copied
    4.96 + * @param data additional data for the copy function
    4.97 + * @return 0 on success or a non-zero value on memory allocation errors
    4.98 + */
    4.99  int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to,
   4.100          copy_func fnc, void *data);
   4.101 +
   4.102 +/**
   4.103 + * Clones the map and rehashes if necessary.
   4.104 + * 
   4.105 + * <b>Note:</b> In contrast to ucx_map_rehash() the load factor is irrelevant.
   4.106 + * This function <i>always</i> ensures a new UcxMap.size of at least
   4.107 + * 2.5*UcxMap.count.
   4.108 + * 
   4.109 + * @param map the map to clone
   4.110 + * @param fnc the copy function to use or <code>NULL</code> if the new and
   4.111 + * the old map shall share the data pointers
   4.112 + * @param data additional data for the copy function
   4.113 + * @return the cloned map
   4.114 + * @see ucx_map_copy()
   4.115 + */
   4.116  UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data);
   4.117 +
   4.118 +/**
   4.119 + * Increases size of the hash map, if necessary.
   4.120 + * 
   4.121 + * The load value is 0.75*UcxMap.size. If the element count exceeds the load
   4.122 + * value, the map needs to be rehashed. Otherwise no action is performed and
   4.123 + * this function simply returns 0.
   4.124 + * 
   4.125 + * The rehashing process ensures, that the UcxMap.size is at least
   4.126 + * 2.5*UcxMap.count. So there is enough room for additional elements without
   4.127 + * the need of another soon rehashing.
   4.128 + * 
   4.129 + * You can use this function to dramatically increase access performance.
   4.130 + * 
   4.131 + * @param map the map to rehash
   4.132 + * @return 1, if a memory allocation error occurred, 0 otherwise
   4.133 + */
   4.134  int ucx_map_rehash(UcxMap *map);
   4.135  
   4.136 -int ucx_map_put(UcxMap *map, UcxKey key, void *data);
   4.137 +/**
   4.138 + * Puts a key/value-pair into the map.
   4.139 + * 
   4.140 + * @param map the map
   4.141 + * @param key the key
   4.142 + * @param value the value
   4.143 + * @return 0 on success, non-zero value on failure
   4.144 + */
   4.145 +int ucx_map_put(UcxMap *map, UcxKey key, void *value);
   4.146 +
   4.147 +/**
   4.148 + * Retrieves a value by using a key.
   4.149 + * 
   4.150 + * @param map the map
   4.151 + * @param key the key
   4.152 + * @return the value
   4.153 + */
   4.154  void* ucx_map_get(UcxMap *map, UcxKey key);
   4.155 +
   4.156 +/**
   4.157 + * Removes a key/value-pair from the map by using the key.
   4.158 + * 
   4.159 + * @param map the map
   4.160 + * @param key the key
   4.161 + * @return the removed value
   4.162 + */
   4.163  void* ucx_map_remove(UcxMap *map, UcxKey key);
   4.164  
   4.165  /**
   4.166 @@ -123,6 +230,7 @@
   4.167   * @param map the map
   4.168   * @param key the key
   4.169   * @param value the value
   4.170 + * @return 0 on success, non-zero value on failure
   4.171   * @see ucx_map_put()
   4.172   */
   4.173  #define ucx_map_sstr_put(map, key, value) \
   4.174 @@ -132,6 +240,7 @@
   4.175   * @param map the map
   4.176   * @param key the key
   4.177   * @param value the value
   4.178 + * @return 0 on success, non-zero value on failure
   4.179   * @see ucx_map_put()
   4.180   */
   4.181  #define ucx_map_cstr_put(map, key, value) \
   4.182 @@ -141,6 +250,7 @@
   4.183   * @param map the map
   4.184   * @param key the key
   4.185   * @param value the value
   4.186 + * @return 0 on success, non-zero value on failure
   4.187   * @see ucx_map_put()
   4.188   */
   4.189  #define ucx_map_int_put(map, key, value) \
   4.190 @@ -151,12 +261,16 @@
   4.191   * Shorthand for getting data from the map with a sstr_t key.
   4.192   * @param map the map
   4.193   * @param key the key
   4.194 + * @return the value
   4.195   * @see ucx_map_get()
   4.196   */
   4.197  #define ucx_map_sstr_get(map, key) \
   4.198      ucx_map_get(map, ucx_key(key.ptr, key.length))
   4.199  /**
   4.200   * Shorthand for getting data from the map with a C string key.
   4.201 + * @param map the map
   4.202 + * @param key the key
   4.203 + * @return the value
   4.204   * @see ucx_map_get()
   4.205   */
   4.206  #define ucx_map_cstr_get(map, key) \
   4.207 @@ -165,6 +279,7 @@
   4.208   * Shorthand for getting data from the map with an integer key.
   4.209   * @param map the map
   4.210   * @param key the key
   4.211 + * @return the value
   4.212   * @see ucx_map_get()
   4.213   */
   4.214  #define ucx_map_int_get(map, key) \
   4.215 @@ -173,6 +288,7 @@
   4.216   * Shorthand for removing data from the map with a sstr_t key.
   4.217   * @param map the map
   4.218   * @param key the key
   4.219 + * @return the removed value
   4.220   * @see ucx_map_remove()
   4.221   */
   4.222  #define ucx_map_sstr_remove(map, key) \
   4.223 @@ -181,6 +297,7 @@
   4.224   * Shorthand for removing data from the map with a C string key.
   4.225   * @param map the map
   4.226   * @param key the key
   4.227 + * @return the removed value
   4.228   * @see ucx_map_remove()
   4.229   */
   4.230  #define ucx_map_cstr_remove(map, key) \
   4.231 @@ -189,18 +306,69 @@
   4.232   * Shorthand for removing data from the map with an integer key.
   4.233   * @param map the map
   4.234   * @param key the key
   4.235 + * @return the removed value
   4.236   * @see ucx_map_remove()
   4.237   */
   4.238  #define ucx_map_int_remove(map, key) \
   4.239      ucx_map_remove(map, ucx_key((void*)&key, sizeof(key)))
   4.240  
   4.241 +/**
   4.242 + * Creates an UcxKey based on the given data.
   4.243 + * 
   4.244 + * This function implicitly computes the hash.
   4.245 + * 
   4.246 + * @param data the data for the key
   4.247 + * @param len the length of the data
   4.248 + * @return an UcxKey with implicitly computed hash
   4.249 + * @see ucx_hash()
   4.250 + */
   4.251  UcxKey ucx_key(void *data, size_t len);
   4.252  
   4.253 +/**
   4.254 + * Computes a murmur hash-2.
   4.255 + * 
   4.256 + * @param data the data to hash
   4.257 + * @param len the length of the data
   4.258 + * @return the murmur hash-2 of the data
   4.259 + */
   4.260  int ucx_hash(const char *data, size_t len);
   4.261  
   4.262 +/**
   4.263 + * Creates an iterator for a map.
   4.264 + * 
   4.265 + * <b>Note:</b> An UcxMapIterator iterates over all elements in all element
   4.266 + * lists successively. Therefore the order highly depends on the key hashes and
   4.267 + * may vary under different map sizes. So generally you may <b>NOT</b> rely on
   4.268 + * the iteration order.
   4.269 + * 
   4.270 + * <b>Note:</b> The iterator is <b>NOT</b> initialized. You need to call
   4.271 + * ucx_map_iter_next() at least once before accessing any information. However,
   4.272 + * it is not recommended to access the fields of an UcxMapIterator directly.
   4.273 + * 
   4.274 + * @param map the map to create the iterator for
   4.275 + * @return an iterator initialized on the first element of the
   4.276 + * first element list
   4.277 + * @see ucx_map_iter_next()
   4.278 + */
   4.279  UcxMapIterator ucx_map_iterator(UcxMap *map);
   4.280  
   4.281 -int ucx_map_iter_next(UcxMapIterator *i, UcxKey *key, void **elm);
   4.282 +/**
   4.283 + * Proceeds to the next element of the map (if any).
   4.284 + * 
   4.285 + * Subsequent calls on the same iterator proceed to the next element and
   4.286 + * store the key/value-pair into the memory specified as arguments of this
   4.287 + * function.
   4.288 + * 
   4.289 + * If no further elements are found, this function returns zero and leaves the
   4.290 + * last found key/value-pair in memory.
   4.291 + * 
   4.292 + * @param iterator the iterator to use
   4.293 + * @param key a pointer to the memory where to store the key
   4.294 + * @param value a pointer to the memory where to store the value
   4.295 + * @return 1, if another element was found, 0 if all elements has been processed
   4.296 + * @see ucx_map_iterator()
   4.297 + */
   4.298 +int ucx_map_iter_next(UcxMapIterator *iterator, UcxKey *key, void **value);
   4.299  
   4.300  
   4.301  #ifdef	__cplusplus
     5.1 --- a/ucx/mempool.c	Fri Aug 09 15:29:26 2013 +0200
     5.2 +++ b/ucx/mempool.c	Mon Aug 12 14:39:51 2013 +0200
     5.3 @@ -36,13 +36,23 @@
     5.4  
     5.5  #include "mempool.h"
     5.6  
     5.7 +/** Capsule for destructible memory chunks. */
     5.8  typedef struct {
     5.9 +    /** The destructor for the memory chunk. */
    5.10      ucx_destructor destructor;
    5.11 +    /**
    5.12 +     * First byte of the memory chunk.
    5.13 +     * Note, that the address <code>&amp;c</code> is also the address
    5.14 +     * of the whole memory chunk.
    5.15 +     */
    5.16      char c;
    5.17  } ucx_memchunk;
    5.18  
    5.19 +/** Capsule for data and its destructor. */
    5.20  typedef struct {
    5.21 +    /** The destructor for the data. */
    5.22      ucx_destructor destructor;
    5.23 +    /** A pointer to the data. */
    5.24      void           *ptr;
    5.25  } ucx_regdestr;
    5.26  
     6.1 --- a/ucx/test.c	Fri Aug 09 15:29:26 2013 +0200
     6.2 +++ b/ucx/test.c	Mon Aug 12 14:39:51 2013 +0200
     6.3 @@ -28,12 +28,6 @@
     6.4  
     6.5  #include "test.h"
     6.6  
     6.7 -    
     6.8 -struct UcxTestList{
     6.9 -    UcxTest test;
    6.10 -    UcxTestList *next;
    6.11 -};
    6.12 -
    6.13  UcxTestSuite* ucx_test_suite_new() {
    6.14      UcxTestSuite* suite = (UcxTestSuite*) malloc(sizeof(UcxTestSuite));
    6.15      if (suite != NULL) {
     7.1 --- a/ucx/test.h	Fri Aug 09 15:29:26 2013 +0200
     7.2 +++ b/ucx/test.h	Mon Aug 12 14:39:51 2013 +0200
     7.3 @@ -90,12 +90,20 @@
     7.4  #define __FUNCTION__ __func__
     7.5  #endif
     7.6  
     7.7 -/** Type for the internal list of test cases. */
     7.8 -typedef struct UcxTestList UcxTestList;
     7.9  /** Type for the UcxTestSuite. */
    7.10  typedef struct UcxTestSuite UcxTestSuite;
    7.11  /** Pointer to a test function. */
    7.12  typedef void(*UcxTest)(UcxTestSuite*,FILE*);
    7.13 +/** Type for the internal list of test cases. */
    7.14 +typedef struct UcxTestList UcxTestList;
    7.15 +
    7.16 +/** Structure for the internal list of test cases. */
    7.17 +struct UcxTestList {
    7.18 +    /** Test case. */
    7.19 +    UcxTest test;
    7.20 +    /** Pointer to the next list element. */
    7.21 +    UcxTestList *next;
    7.22 +};
    7.23  
    7.24  /**
    7.25   * A test suite containing multiple test cases.
    7.26 @@ -119,7 +127,7 @@
    7.27  UcxTestSuite* ucx_test_suite_new();
    7.28  /**
    7.29   * Destroys a test suite.
    7.30 - * @param the test suite to destroy
    7.31 + * @param suite the test suite to destroy
    7.32   */
    7.33  void ucx_test_suite_free(UcxTestSuite* suite);
    7.34  
     8.1 --- a/ucx/utils.h	Fri Aug 09 15:29:26 2013 +0200
     8.2 +++ b/ucx/utils.h	Mon Aug 12 14:39:51 2013 +0200
     8.3 @@ -95,7 +95,7 @@
     8.4   * Compares two real numbers of type float.
     8.5   * @param f1 pointer to float one
     8.6   * @param f2 pointer to float two
     8.7 - * @param if provided: a pointer to precision (default: 1e-6f)
     8.8 + * @param data if provided: a pointer to precision (default: 1e-6f)
     8.9   * @return -1, if *f1 is less than *f2, 0 if both are equal,
    8.10   * 1 if *f1 is greater than *f2
    8.11   */
    8.12 @@ -104,9 +104,9 @@
    8.13  
    8.14  /**
    8.15   * Compares two real numbers of type double.
    8.16 - * @param f1 pointer to double one
    8.17 - * @param f2 pointer to double two
    8.18 -* @param if provided: a pointer to precision (default: 1e-14)
    8.19 + * @param d1 pointer to double one
    8.20 + * @param d2 pointer to double two
    8.21 + * @param data if provided: a pointer to precision (default: 1e-14)
    8.22   * @return -1, if *d1 is less than *d2, 0 if both are equal,
    8.23   * 1 if *d1 is greater than *d2
    8.24   */

mercurial