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@549: * \file map.h universe@549: * \brief Interface for map implementations. universe@549: * \author Mike Becker universe@549: * \author Olaf Wintermann universe@549: * \version 3.0 universe@549: * \copyright 2-Clause BSD License universe@549: */ universe@549: universe@549: #ifndef UCX_MAP_H universe@549: #define UCX_MAP_H universe@549: universe@549: #include "common.h" universe@549: #include "allocator.h" universe@549: #include "iterator.h" universe@563: #include "hash_key.h" universe@549: universe@549: #ifdef __cplusplus universe@549: extern "C" { universe@549: #endif universe@549: universe@549: /** Type for the UCX map. */ universe@549: typedef struct cx_map_s CxMap; universe@549: universe@549: /** Type for a map entry. */ universe@549: typedef struct cx_map_entry_s CxMapEntry; universe@549: universe@549: /** Type for map class definitions. */ universe@549: typedef struct cx_map_class_s cx_map_class; universe@549: universe@549: /** Structure for the UCX map. */ universe@549: struct cx_map_s { universe@549: /** The map class definition. */ universe@549: cx_map_class *cl; universe@549: /** An allocator that is used for the map elements. */ universe@549: CxAllocator *allocator; universe@549: /** The number of elements currently stored. */ universe@549: size_t size; universe@549: // TODO: elemsize + a flag if values shall be copied to the map universe@549: }; universe@549: universe@549: /** universe@549: * The class definition for arbitrary maps. universe@549: */ universe@549: struct cx_map_class_s { universe@549: /** universe@549: * Deallocates the entire memory. universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: void (*destructor)(struct cx_map_s *map); universe@549: universe@549: /** universe@549: * Removes all elements. universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: void (*clear)(struct cx_map_s *map); universe@549: universe@549: /** universe@549: * Add or overwrite an element. universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: int (*put)( universe@549: CxMap *map, universe@563: CxHashKey key, universe@550: void *value universe@549: ); universe@549: universe@549: /** universe@549: * Returns an element. universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@549: void *(*get)( universe@549: CxMap const *map, universe@563: CxHashKey key universe@549: ); universe@549: universe@549: /** universe@549: * Removes an element. universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@549: void *(*remove)( universe@550: CxMap *map, universe@563: CxHashKey key universe@549: ); universe@549: universe@549: /** universe@549: * Iterator over the key/value pairs. universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@551: CxIterator (*iterator)(CxMap *map); universe@549: universe@549: /** universe@549: * Iterator over the keys. universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@551: CxIterator (*iterator_keys)(CxMap *map); universe@549: universe@549: /** universe@549: * Iterator over the values. universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@551: CxIterator (*iterator_values)(CxMap *map); universe@549: }; universe@549: universe@549: /** universe@549: * A map entry. universe@549: */ universe@549: struct cx_map_entry_s { universe@549: /** universe@551: * A pointer to the key. universe@549: */ universe@563: CxHashKey const *key; universe@549: /** universe@551: * A pointer to the value. universe@549: */ universe@551: void *value; universe@549: }; universe@549: universe@549: universe@549: /** universe@549: * Deallocates the memory of the specified map. universe@549: * universe@549: * @param map the map to be destroyed universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: static inline void cxMapDestroy(CxMap *map) { universe@549: // TODO: likely to add auto-free feature for contents in the future universe@549: map->cl->destructor(map); universe@549: } universe@549: universe@549: universe@549: /** universe@549: * Clears a map by removing all elements. universe@549: * universe@549: * @param map the map to be cleared universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: static inline void cxMapClear(CxMap *map) { universe@549: map->cl->clear(map); universe@549: } universe@549: universe@549: /** universe@549: * Puts a key/value-pair into the map. universe@549: * universe@549: * @param map the map universe@549: * @param key the key universe@549: * @param value the value universe@549: * @return 0 on success, non-zero value on failure universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: static inline int cxMapPut( universe@549: CxMap *map, universe@563: CxHashKey key, universe@550: void *value universe@549: ) { universe@549: return map->cl->put(map, key, value); universe@549: } universe@549: universe@549: /** universe@549: * Retrieves a value by using a key. universe@549: * universe@549: * @param map the map universe@549: * @param key the key universe@549: * @return the value universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@553: static inline void *cxMapGet( universe@549: CxMap const *map, universe@563: CxHashKey key universe@549: ) { universe@549: return map->cl->get(map, key); universe@549: } universe@549: universe@549: /** universe@549: * Removes a key/value-pair from the map by using the key. universe@549: * universe@549: * @param map the map universe@549: * @param key the key universe@549: * @return the removed value universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@553: static inline void *cxMapRemove( universe@549: CxMap *map, universe@563: CxHashKey key universe@549: ) { universe@549: return map->cl->remove(map, key); universe@549: } universe@549: universe@549: // TODO: set-like map operations (union, intersect, difference) universe@549: universe@549: /** universe@549: * Creates a value iterator for a map. universe@549: * universe@549: * \note An iterator iterates over all elements successively. Therefore the order universe@549: * highly depends on the map implementation and may change arbitrarily when the contents change. universe@549: * universe@549: * @param map the map to create the iterator for universe@549: * @return an iterator for the currently stored values universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@551: static inline CxIterator cxMapIteratorValues(CxMap *map) { universe@549: return map->cl->iterator_values(map); universe@549: } universe@549: universe@549: /** universe@549: * Creates a key iterator for a map. universe@549: * universe@564: * The elements of the iterator are keys of type CxHashKey. universe@555: * universe@549: * \note An iterator iterates over all elements successively. Therefore the order universe@549: * highly depends on the map implementation and may change arbitrarily when the contents change. universe@549: * universe@549: * @param map the map to create the iterator for universe@549: * @return an iterator for the currently stored keys universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@551: static inline CxIterator cxMapIteratorKeys(CxMap *map) { universe@549: return map->cl->iterator_keys(map); universe@549: } universe@549: universe@549: /** universe@549: * Creates an iterator for a map. universe@549: * universe@555: * The elements of the iterator are key/value pairs of type CxMapEntry. universe@549: * universe@549: * \note An iterator iterates over all elements successively. Therefore the order universe@549: * highly depends on the map implementation and may change arbitrarily when the contents change. universe@549: * universe@549: * @param map the map to create the iterator for universe@555: * @return an iterator for the currently stored entries universe@549: * @see cxMapIteratorKeys() universe@549: * @see cxMapIteratorValues() universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@551: static inline CxIterator cxMapIterator(CxMap *map) { universe@549: return map->cl->iterator(map); universe@549: } universe@549: universe@549: #ifdef __cplusplus universe@549: } universe@549: #endif universe@549: universe@549: #endif // UCX_MAP_H