1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2002 Cray Inc.
5 * Copyright (c) 2002 Eric Hoffman
7 * This file is part of Lustre, http://www.lustre.org.
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * a very simple hash table implementation with paramerterizable
30 * comparison and key generation functions. it does resize
31 * in order to accomidate more entries, but never collapses
35 static table_entry *table_lookup (table t,void *comparator,
37 int (*compare_function)(void *, void *),
40 unsigned int key=k%t->size;
43 for (i=&(t->entries[key]);*i;i=&((*i)->next)){
44 if (compare_function && ((*i)->key==k))
45 if ((*t->compare_function)((*i)->value,comparator)){
51 return(&(t->entries[key]));
55 static void resize_table(table t, int size)
58 table_entry *old_entries=t->entries;
61 table_entry *position;
65 t->entries=(table_entry *)malloc(sizeof(table_entry)*t->size);
66 memset(t->entries,0,sizeof(table_entry)*t->size);
68 for (i=0;i<old_size;i++)
69 for (j=old_entries[i];j;j=n){
71 position=table_lookup(t,0,j->key,0,&success);
79 /* Function: key_from_int
80 * Arguments: int i: value to compute the key of
83 unsigned int key_from_int(int i)
89 /* Function: key_from_string
90 * Arguments: char *s: the null terminated string
91 * to compute the key of
94 unsigned int key_from_string(char *s)
96 unsigned int result=0, i;
101 for (n = (unsigned char *)s, i = 0; *n; n++, i++)
102 result ^= (*n * 57) ^ *n * i;
108 /* Function: hash_create_table
109 * Arguments: compare_function: a function to compare
110 * a table instance with a correlator
111 * key_function: a function to generate a 32 bit
112 * hash key from a correlator
113 * Returns: a pointer to the new table
115 table hash_create_table (int (*compare_function)(void *, void *),
116 unsigned int (*key_function)(void *))
118 table new=(table)malloc(sizeof(struct table));
119 memset(new, 0, sizeof(struct table));
121 new->compare_function=compare_function;
122 new->key_function=key_function;
123 new->number_of_entries=0;
125 new->entries=(table_entry *)malloc(sizeof(table_entry)*new->size);
126 memset(new->entries,0,sizeof(table_entry)*new->size);
131 /* Function: hash_table_find
132 * Arguments: t: a table to look in
133 * comparator: a value to access the table entry
134 * Returns: the element references to by comparator, or null
136 void *hash_table_find (table t, void *comparator)
139 table_entry* entry=table_lookup(t,comparator,
140 (*t->key_function)(comparator),
143 if (success) return((*entry)->value);
148 /* Function: hash_table_insert
149 * Arguments: t: a table to insert the object
150 * value: the object to put in the table
151 * comparator: the value by which the object
155 void hash_table_insert (table t, void *value, void *comparator)
158 unsigned int k=(*t->key_function)(comparator);
159 table_entry *position=table_lookup(t,comparator,k,
160 t->compare_function,&success);
166 entry = (table_entry)malloc(sizeof(struct table_entry));
167 memset(entry, 0, sizeof(struct table_entry));
168 entry->next= *position;
170 t->number_of_entries++;
174 if (t->number_of_entries > t->size) resize_table(t,t->size*2);
177 /* Function: hash_table_remove
178 * Arguments: t: the table to remove the object from
179 * comparator: the index value of the object to remove
182 void hash_table_remove (table t, void *comparator)
186 table_entry *position=table_lookup(t,comparator,
187 (*t->key_function)(comparator),
188 t->compare_function,&success);
191 *position=(*position)->next;
192 free(temp); /* the value? */
193 t->number_of_entries--;
197 /* Function: hash_iterate_table_entries
198 * Arguments: t: the table to iterate over
199 * handler: a function to call with each element
200 * of the table, along with arg
201 * arg: the opaque object to pass to handler
204 void hash_iterate_table_entries(table t,
205 void (*handler)(void *,void *),
209 table_entry *j,*next;
211 for (i=0;i<t->size;i++)
212 for (j=t->entries+i;*j;j=next){
214 (*handler)(arg,(*j)->value);
218 /* Function: hash_filter_table_entries
219 * Arguments: t: the table to iterate over
220 * handler: a function to call with each element
221 * of the table, along with arg
222 * arg: the opaque object to pass to handler
224 * Notes: operations on the table inside handler are not safe
226 * filter_table_entires() calls the handler function for each
227 * item in the table, passing it and arg. The handler function
228 * returns 1 if it is to be retained in the table, and 0
229 * if it is to be removed.
231 void hash_filter_table_entries(table t, int (*handler)(void *, void *), void *arg)
234 table_entry *j,*next,v;
236 for (i=0;i<t->size;i++)
237 for (j=t->entries+i;*j;j=next){
239 if (!(*handler)(arg,(*j)->value)){
244 t->number_of_entries--;
249 /* Function: destroy_table
250 * Arguments: t: the table to free
251 * thunk: a function to call with each element,
255 void hash_destroy_table(table t,void (*thunk)(void *))
259 for (i=0;i<t->size;i++)
260 for (j=t->entries[i];j;j=next){
262 if (thunk) (*thunk)(j->value);