Updated MSpec source to 46e80081.
[rbx.git] / shotgun / external_libs / libcchash / hashtable_itr.c
blob366fde71170d42fc63a14c6e71d0c109389e5481
1 /* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
3 #include "hashtable.h"
4 #include "hashtable_private.h"
5 #include "hashtable_itr.h"
6 #include <stdlib.h> /* defines NULL */
8 /*****************************************************************************/
9 /* hashtable_iterator - iterator constructor */
11 void
12 hashtable_iterator_init(struct hashtable_itr *itr, struct hashtable *h)
14 unsigned int i, tablelength;
16 itr->h = h;
17 itr->e = NULL;
18 itr->parent = NULL;
19 tablelength = h->tablelength;
20 itr->index = tablelength;
21 if (0 == h->entrycount) return;
23 for (i = 0; i < tablelength; i++)
25 if (NULL != h->table[i])
27 itr->e = h->table[i];
28 itr->index = i;
29 break;
34 /*****************************************************************************/
35 /* key - return the key of the (key,value) pair at the current position */
36 /* value - return the value of the (key,value) pair at the current position */
38 void *
39 hashtable_iterator_key(struct hashtable_itr *i)
40 { return i->e->k; }
42 void *
43 hashtable_iterator_value(struct hashtable_itr *i)
44 { return i->e->v; }
46 /*****************************************************************************/
47 /* advance - advance the iterator to the next element
48 * returns zero if advanced to end of table */
50 int
51 hashtable_iterator_advance(struct hashtable_itr *itr)
53 unsigned int j,tablelength;
54 struct entry **table;
55 struct entry *next;
56 if (NULL == itr->e) return 0; /* stupidity check */
58 next = itr->e->next;
59 if (NULL != next)
61 itr->parent = itr->e;
62 itr->e = next;
63 return -1;
65 tablelength = itr->h->tablelength;
66 itr->parent = NULL;
67 if (tablelength <= (j = ++(itr->index)))
69 itr->e = NULL;
70 return 0;
72 table = itr->h->table;
73 while (NULL == (next = table[j]))
75 if (++j >= tablelength)
77 itr->index = tablelength;
78 itr->e = NULL;
79 return 0;
82 itr->index = j;
83 itr->e = next;
84 return -1;
87 /*****************************************************************************/
88 /* remove - remove the entry at the current iterator position
89 * and advance the iterator, if there is a successive
90 * element.
91 * If you want the value, read it before you remove:
92 * beware memory leaks if you don't.
93 * Returns zero if end of iteration. */
95 int
96 hashtable_iterator_remove(struct hashtable_itr *itr)
98 struct entry *remember_e, *remember_parent;
99 int ret;
101 /* Do the removal */
102 if (NULL == (itr->parent))
104 /* element is head of a chain */
105 itr->h->table[itr->index] = itr->e->next;
106 } else {
107 /* element is mid-chain */
108 itr->parent->next = itr->e->next;
110 /* itr->e is now outside the hashtable */
111 remember_e = itr->e;
112 itr->h->entrycount--;
113 freekey(remember_e->k);
115 /* Advance the iterator, correcting the parent */
116 remember_parent = itr->parent;
117 ret = hashtable_iterator_advance(itr);
118 if (itr->parent == remember_e) { itr->parent = remember_parent; }
119 free(remember_e);
120 return ret;
123 /*****************************************************************************/
124 int /* returns zero if not found */
125 hashtable_iterator_search(struct hashtable_itr *itr,
126 struct hashtable *h, void *k)
128 struct entry *e, *parent;
129 unsigned int hashvalue, index;
131 hashvalue = hash(h,k);
132 index = indexFor(h->tablelength,hashvalue);
134 e = h->table[index];
135 parent = NULL;
136 while (NULL != e)
138 /* Check hash value to short circuit heavier comparison */
139 if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
141 itr->index = index;
142 itr->e = e;
143 itr->parent = parent;
144 itr->h = h;
145 return -1;
147 parent = e;
148 e = e->next;
150 return 0;
155 * Copyright (c) 2002, 2004, Christopher Clark
156 * All rights reserved.
158 * Redistribution and use in source and binary forms, with or without
159 * modification, are permitted provided that the following conditions
160 * are met:
162 * * Redistributions of source code must retain the above copyright
163 * notice, this list of conditions and the following disclaimer.
165 * * Redistributions in binary form must reproduce the above copyright
166 * notice, this list of conditions and the following disclaimer in the
167 * documentation and/or other materials provided with the distribution.
169 * * Neither the name of the original author; nor the names of any contributors
170 * may be used to endorse or promote products derived from this software
171 * without specific prior written permission.
174 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
176 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
177 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
178 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
179 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
180 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
181 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
182 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
183 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
184 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.