root/src/hashtable_itr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hashtable_iterator
  2. hashtable_iterator_advance
  3. hashtable_iterator_remove
  4. hashtable_iterator_search

   1 /*
   2  * Copyright (c) 2002, 2004, Christopher Clark
   3  * All rights reserved.
   4  * 
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 
   9  * * Redistributions of source code must retain the above copyright
  10  * notice, this list of conditions and the following disclaimer.
  11  * 
  12  * * 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  * * Neither the name of the original author; nor the names of any contributors
  17  * may be used to endorse or promote products derived from this software
  18  * without specific prior written permission.
  19  * 
  20  * 
  21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
  25  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  29  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32  */
  33 
  34 #include "private/ftdm_core.h"
  35 #include "hashtable.h"
  36 #include "hashtable_private.h"
  37 #include "hashtable_itr.h"
  38 #include <stdlib.h> /* defines NULL */
  39 
  40 /*****************************************************************************/
  41 /* hashtable_iterator    - iterator constructor */
  42 
  43 struct hashtable_itr *
  44 hashtable_iterator(struct hashtable *h)
  45 {
  46     unsigned int i, tablelength;
  47     struct hashtable_itr *itr = ftdm_malloc(sizeof(struct hashtable_itr));
  48     if (NULL == itr) return NULL;
  49     itr->h = h;
  50     itr->e = NULL;
  51     itr->parent = NULL;
  52     tablelength = h->tablelength;
  53     itr->index = tablelength;
  54     if (0 == h->entrycount) return itr;
  55 
  56     for (i = 0; i < tablelength; i++)
  57                 {
  58                         if (NULL != h->table[i])
  59                                 {
  60                                         itr->e = h->table[i];
  61                                         itr->index = i;
  62                                         break;
  63                                 }
  64                 }
  65     return itr;
  66 }
  67 
  68 /*****************************************************************************/
  69 /* advance - advance the iterator to the next element
  70  *           returns zero if advanced to end of table */
  71 
  72 int
  73 hashtable_iterator_advance(struct hashtable_itr *itr)
  74 {
  75     unsigned int j,tablelength;
  76     struct entry **table;
  77     struct entry *next;
  78     if (NULL == itr->e) return 0; /* stupidity check */
  79 
  80     next = itr->e->next;
  81     if (NULL != next)
  82                 {
  83                         itr->parent = itr->e;
  84                         itr->e = next;
  85                         return -1;
  86                 }
  87     tablelength = itr->h->tablelength;
  88     itr->parent = NULL;
  89     if (tablelength <= (j = ++(itr->index)))
  90                 {
  91                         itr->e = NULL;
  92                         return 0;
  93                 }
  94     table = itr->h->table;
  95     while (NULL == (next = table[j]))
  96                 {
  97                         if (++j >= tablelength)
  98                                 {
  99                                         itr->index = tablelength;
 100                                         itr->e = NULL;
 101                                         return 0;
 102                                 }
 103                 }
 104     itr->index = j;
 105     itr->e = next;
 106     return -1;
 107 }
 108 
 109 /*****************************************************************************/
 110 /* remove - remove the entry at the current iterator position
 111  *          and advance the iterator, if there is a successive
 112  *          element.
 113  *          If you want the value, read it before you remove:
 114  *          beware memory leaks if you don't.
 115  *          Returns zero if end of iteration. */
 116 
 117 int
 118 hashtable_iterator_remove(struct hashtable_itr *itr)
 119 {
 120     struct entry *remember_e, *remember_parent;
 121     int ret;
 122 
 123     /* Do the removal */
 124     if (NULL == (itr->parent))
 125                 {
 126                         /* element is head of a chain */
 127                         itr->h->table[itr->index] = itr->e->next;
 128                 } else {
 129         /* element is mid-chain */
 130         itr->parent->next = itr->e->next;
 131     }
 132     /* itr->e is now outside the hashtable */
 133     remember_e = itr->e;
 134     itr->h->entrycount--;
 135     freekey(remember_e->k);
 136 
 137     /* Advance the iterator, correcting the parent */
 138     remember_parent = itr->parent;
 139     ret = hashtable_iterator_advance(itr);
 140     if (itr->parent == remember_e) { itr->parent = remember_parent; }
 141     ftdm_safe_free(remember_e);
 142     return ret;
 143 }
 144 
 145 /*****************************************************************************/
 146 int /* returns zero if not found */
 147 hashtable_iterator_search(struct hashtable_itr *itr,
 148                           struct hashtable *h, void *k)
 149 {
 150     struct entry *e, *parent;
 151     unsigned int hashvalue, index;
 152 
 153     hashvalue = hash(h,k);
 154     index = indexFor(h->tablelength,hashvalue);
 155 
 156     e = h->table[index];
 157     parent = NULL;
 158     while (NULL != e)
 159                 {
 160                         /* Check hash value to short circuit heavier comparison */
 161                         if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
 162                                 {
 163                                         itr->index = index;
 164                                         itr->e = e;
 165                                         itr->parent = parent;
 166                                         itr->h = h;
 167                                         return -1;
 168                                 }
 169                         parent = e;
 170                         e = e->next;
 171                 }
 172     return 0;
 173 }
 174 
 175 
 176 /* For Emacs:
 177  * Local Variables:
 178  * mode:c
 179  * indent-tabs-mode:t
 180  * tab-width:4
 181  * c-basic-offset:4
 182  * End:
 183  * For VIM:
 184  * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
 185  */
 186 

/* [<][>][^][v][top][bottom][index][help] */