universe@549: /* universe@549: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. universe@549: * universe@549: * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. universe@549: * universe@549: * Redistribution and use in source and binary forms, with or without universe@549: * modification, are permitted provided that the following conditions are met: universe@549: * universe@549: * 1. Redistributions of source code must retain the above copyright universe@549: * notice, this list of conditions and the following disclaimer. universe@549: * universe@549: * 2. Redistributions in binary form must reproduce the above copyright universe@549: * notice, this list of conditions and the following disclaimer in the universe@549: * documentation and/or other materials provided with the distribution. universe@549: * universe@549: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" universe@549: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE universe@549: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE universe@549: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE universe@549: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR universe@549: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF universe@549: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS universe@549: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN universe@549: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) universe@549: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE universe@549: * POSSIBILITY OF SUCH DAMAGE. universe@549: */ universe@549: /** universe@563: * \file hash_map.h universe@563: * \brief Hash map implementation. universe@549: * \author Mike Becker universe@549: * \author Olaf Wintermann universe@549: * \copyright 2-Clause BSD License universe@549: */ universe@549: universe@549: #ifndef UCX_HASH_MAP_H universe@549: #define UCX_HASH_MAP_H universe@549: universe@549: #include "map.h" universe@549: universe@549: #ifdef __cplusplus universe@549: extern "C" { universe@549: #endif universe@549: universe@549: /** Internal structure for an element of a hash map. */ universe@658: struct cx_hash_map_element_s; universe@549: universe@550: /** universe@550: * Internal structure for a hash map. universe@550: */ universe@550: struct cx_hash_map_s { universe@550: /** universe@550: * Base structure for maps. universe@550: */ universe@550: struct cx_map_s base; universe@550: /** universe@550: * The buckets of this map, each containing a linked list of elements. universe@550: */ universe@550: struct cx_hash_map_element_s **buckets; universe@550: /** universe@550: * The number of buckets. universe@550: */ universe@550: size_t bucket_count; universe@550: }; universe@550: universe@549: universe@549: /** universe@550: * Creates a new hash map with the specified number of buckets. universe@550: * universe@550: * If \p buckets is zero, an implementation defined default will be used. universe@550: * universe@677: * If \p item_size is CX_STORE_POINTERS, the created map will be created as if universe@669: * cxMapStorePointers() was called immediately after creation. universe@669: * universe@559: * @note Iterators provided by this hash map implementation provide the remove operation. universe@738: * The index value of an iterator is incremented when the iterator advanced without removal. universe@559: * In other words, when the iterator is finished, \c index==size . universe@549: * universe@549: * @param allocator the allocator to use universe@658: * @param itemsize the size of one element universe@549: * @param buckets the initial number of buckets in this hash map universe@549: * @return a pointer to the new hash map universe@549: */ universe@550: __attribute__((__nonnull__, __warn_unused_result__)) universe@549: CxMap *cxHashMapCreate( universe@691: CxAllocator const *allocator, universe@658: size_t itemsize, universe@549: size_t buckets universe@549: ); universe@549: universe@549: /** universe@696: * Creates a new hash map with a default number of buckets. universe@696: * universe@696: * If \p item_size is CX_STORE_POINTERS, the created map will be created as if universe@696: * cxMapStorePointers() was called immediately after creation. universe@696: * universe@696: * @note Iterators provided by this hash map implementation provide the remove operation. universe@738: * The index value of an iterator is incremented when the iterator advanced without removal. universe@696: * In other words, when the iterator is finished, \c index==size . universe@696: * universe@696: * @param itemsize the size of one element universe@696: * @return a pointer to the new hash map universe@696: */ universe@696: #define cxHashMapCreateSimple(itemsize) \ universe@696: cxHashMapCreate(cxDefaultAllocator, itemsize, 0) universe@696: universe@696: /** universe@549: * Increases the number of buckets, if necessary. universe@549: * universe@562: * The load threshold is \c 0.75*buckets. If the element count exceeds the load universe@562: * threshold, the map will be rehashed. Otherwise, no action is performed and universe@549: * this function simply returns 0. universe@549: * universe@549: * The rehashing process ensures, that the number of buckets is at least universe@562: * 2.5 times the element count. So there is enough room for additional universe@549: * elements without the need of another soon rehashing. universe@549: * universe@562: * You can use this function after filling a map to increase access performance. universe@549: * universe@549: * @note If the specified map is not a hash map, the behavior is undefined. universe@549: * universe@549: * @param map the map to rehash universe@549: * @return zero on success, non-zero if a memory allocation error occurred universe@549: */ universe@549: __attribute__((__nonnull__)) universe@562: int cxMapRehash(CxMap *map); universe@549: universe@549: universe@549: #ifdef __cplusplus universe@549: } // extern "C" universe@549: #endif universe@549: universe@549: #endif // UCX_HASH_MAP_H