1262395Sbapt/* Copyright (c) 2013, Vsevolod Stakhov 2262395Sbapt * All rights reserved. 3262395Sbapt * 4262395Sbapt * Redistribution and use in source and binary forms, with or without 5262395Sbapt * modification, are permitted provided that the following conditions are met: 6262395Sbapt * * Redistributions of source code must retain the above copyright 7262395Sbapt * notice, this list of conditions and the following disclaimer. 8262395Sbapt * * Redistributions in binary form must reproduce the above copyright 9262395Sbapt * notice, this list of conditions and the following disclaimer in the 10262395Sbapt * documentation and/or other materials provided with the distribution. 11262395Sbapt * 12262395Sbapt * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY 13262395Sbapt * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14262395Sbapt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15262395Sbapt * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 16262395Sbapt * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17262395Sbapt * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18262395Sbapt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 19262395Sbapt * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20262395Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21262395Sbapt * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22262395Sbapt */ 23262395Sbapt 24262395Sbapt#include "ucl_hash.h" 25262395Sbapt#include "utlist.h" 26262395Sbapt 27262395Sbaptucl_hash_t* 28262395Sbaptucl_hash_create (void) 29262395Sbapt{ 30262395Sbapt ucl_hash_t *new; 31262395Sbapt 32262395Sbapt new = UCL_ALLOC (sizeof (ucl_hash_t)); 33262395Sbapt if (new != NULL) { 34262395Sbapt new->buckets = NULL; 35262395Sbapt } 36262395Sbapt return new; 37262395Sbapt} 38262395Sbapt 39262395Sbaptvoid ucl_hash_destroy (ucl_hash_t* hashlin, ucl_hash_free_func *func) 40262395Sbapt{ 41262395Sbapt ucl_hash_node_t *elt, *tmp; 42262395Sbapt 43262395Sbapt HASH_ITER (hh, hashlin->buckets, elt, tmp) { 44262395Sbapt HASH_DELETE (hh, hashlin->buckets, elt); 45262395Sbapt if (func) { 46262395Sbapt func (elt->data); 47262395Sbapt } 48262395Sbapt UCL_FREE (sizeof (ucl_hash_node_t), elt); 49262395Sbapt } 50262395Sbapt UCL_FREE (sizeof (ucl_hash_t), hashlin); 51262395Sbapt} 52262395Sbapt 53262395Sbaptvoid 54262395Sbaptucl_hash_insert (ucl_hash_t* hashlin, ucl_object_t *obj, const char *key, unsigned keylen) 55262395Sbapt{ 56262395Sbapt ucl_hash_node_t *node; 57262395Sbapt 58262395Sbapt node = UCL_ALLOC (sizeof (ucl_hash_node_t)); 59262395Sbapt node->data = obj; 60262395Sbapt HASH_ADD_KEYPTR (hh, hashlin->buckets, key, keylen, node); 61262395Sbapt} 62262395Sbapt 63262395Sbaptvoid* 64262395Sbaptucl_hash_iterate (ucl_hash_t *hashlin, ucl_hash_iter_t *iter) 65262395Sbapt{ 66262395Sbapt ucl_hash_node_t *elt = *iter; 67262395Sbapt 68262395Sbapt if (elt == NULL) { 69262395Sbapt if (hashlin == NULL || hashlin->buckets == NULL) { 70262395Sbapt return NULL; 71262395Sbapt } 72262395Sbapt elt = hashlin->buckets; 73262395Sbapt if (elt == NULL) { 74262395Sbapt return NULL; 75262395Sbapt } 76262395Sbapt } 77262395Sbapt else if (elt == hashlin->buckets) { 78262395Sbapt return NULL; 79262395Sbapt } 80262395Sbapt 81262395Sbapt *iter = elt->hh.next ? elt->hh.next : hashlin->buckets; 82262395Sbapt return elt->data; 83262395Sbapt} 84262395Sbapt 85262395Sbaptbool 86262395Sbaptucl_hash_iter_has_next (ucl_hash_iter_t iter) 87262395Sbapt{ 88262395Sbapt ucl_hash_node_t *elt = iter; 89262395Sbapt 90262395Sbapt return (elt == NULL || elt->hh.prev != NULL); 91262395Sbapt} 92262395Sbapt 93262395Sbapt 94262395Sbaptucl_object_t* 95262395Sbaptucl_hash_search (ucl_hash_t* hashlin, const char *key, unsigned keylen) 96262395Sbapt{ 97262395Sbapt ucl_hash_node_t *found; 98262395Sbapt 99262395Sbapt if (hashlin == NULL) { 100262395Sbapt return NULL; 101262395Sbapt } 102262395Sbapt HASH_FIND (hh, hashlin->buckets, key, keylen, found); 103262395Sbapt 104262395Sbapt if (found) { 105262395Sbapt return found->data; 106262395Sbapt } 107262395Sbapt return NULL; 108262395Sbapt} 109262395Sbapt 110262395Sbaptvoid 111262395Sbaptucl_hash_delete (ucl_hash_t* hashlin, ucl_object_t *obj) 112262395Sbapt{ 113262395Sbapt ucl_hash_node_t *found; 114262395Sbapt 115262395Sbapt HASH_FIND (hh, hashlin->buckets, obj->key, obj->keylen, found); 116262395Sbapt 117262395Sbapt if (found) { 118262395Sbapt HASH_DELETE (hh, hashlin->buckets, found); 119262395Sbapt } 120262395Sbapt} 121