annotate mcabber/libjabber/genhash.c @ 1346:e36b21e11760

Remove useless casts
author Mikael Berthe <mikael@lilotux.net>
date Fri, 09 Nov 2007 20:09:47 +0100
parents c3ae9251c197
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
25
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
1 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
2 * This program is free software; you can redistribute it and/or modify
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
3 * it under the terms of the GNU General Public License as published by
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
4 * the Free Software Foundation; either version 2 of the License, or
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
5 * (at your option) any later version.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
6 *
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
7 * This program is distributed in the hope that it will be useful,
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
10 * GNU General Public License for more details.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
11 *
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
12 * You should have received a copy of the GNU General Public License
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
13 * along with this program; if not, write to the Free Software
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
15 *
417
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
16 * Copyrights
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
17 *
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
18 * Portions created by or assigned to Jabber.com, Inc. are
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
19 * Copyright (c) 1999-2002 Jabber.com, Inc. All Rights Reserved. Contact
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
20 * information for Jabber.com, Inc. is available at http://www.jabber.com/.
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
21 *
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
22 * Portions Copyright (c) 1998-1999 Jeremie Miller.
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
23 *
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
24 * Acknowledgements
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
25 *
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
26 * Special thanks to the Jabber Open Source Contributors for their
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
27 * suggestions and support of Jabber.
c3ae9251c197 Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents: 414
diff changeset
28 *
25
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
29 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
30 #include <libxode.h>
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
31
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
32 /*****************************************************************************
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
33 * Internal type definitions
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
34 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
35
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
36 typedef struct tagHNODE
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
37 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
38 struct tagHNODE *next; /* next node in list */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
39 const void *key; /* key pointer */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
40 void *value; /* value pointer */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
41 } HNODE;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
42
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
43 #define SLAB_NUM_NODES 64 /* allocate this many nodes per slab */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
44
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
45 typedef struct tagHSLAB
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
46 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
47 struct tagHSLAB *next; /* next slab pointer */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
48 HNODE nodes[SLAB_NUM_NODES]; /* the actual nodes */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
49 } HSLAB;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
50
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
51 #define HASH_NUM_BUCKETS 509 /* should be a prime number; see Knuth */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
52
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
53 typedef struct tagHASHTABLE_INTERNAL
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
54 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
55 unsigned long sig1; /* first signature word */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
56 KEYHASHFUNC hash; /* hash function */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
57 KEYCOMPAREFUNC cmp; /* comparison function */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
58 int count; /* table entry count */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
59 int bcount; /* bucket count */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
60 HNODE **buckets; /* the hash buckets */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
61 unsigned long sig2; /* second signature word */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
62
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
63 } HASHTABLE_INTERNAL;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
64
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
65 #define HASH_SIG1 0x68736148UL /* "Hash" */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
66 #define HASH_SIG2 0x6F627245UL /* "Erbo" */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
67
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
68 #define do_hash(tb,key) ((*((tb)->hash))(key) % ((tb)->bcount))
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
69
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
70 static HNODE *s_free_nodes = NULL; /* free nodes list */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
71 static HSLAB *s_slabs = NULL; /* node slabs list */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
72
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
73 /*****************************************************************************
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
74 * Internal functions
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
75 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
76
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
77 static HNODE *allocate_node(
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
78 const void *key, /* key pointer for this node */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
79 void *value) /* value pointer for this node */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
80 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
81 allocate_node allocates a new hash node and fills it. Returns NULL if the
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
82 node could not be allocated.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
83 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
84 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
85 HNODE *rc; /* return from this function */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
86
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
87 if (!s_free_nodes)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
88 { /* allocate a new slabful of nodes and chain them to make a new free list */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
89 register int i; /* loop counter */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
90 HSLAB *slab = (HSLAB *)malloc(sizeof(HSLAB));
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
91 if (!slab)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
92 return NULL;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
93 memset(slab,0,sizeof(HSLAB));
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
94 slab->next = s_slabs;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
95 for (i=0; i<(SLAB_NUM_NODES-1); i++)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
96 slab->nodes[i].next = &(slab->nodes[i+1]);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
97 s_free_nodes = &(slab->nodes[0]);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
98 s_slabs = slab;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
99
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
100 } /* end if */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
101
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
102 /* grab a node off the fron of the free list and fill it */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
103 rc = s_free_nodes;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
104 s_free_nodes = rc->next;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
105 rc->next = NULL;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
106 rc->key = key;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
107 rc->value = value;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
108 return rc;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
109
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
110 } /* end allocate_node */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
111
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
112 static void free_node(
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
113 HNODE *node) /* node to be freed */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
114 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
115 free_node returns a hash node to the list.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
116 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
117 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
118 /* zap the node contents to avoid problems later */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
119 memset(node,0,sizeof(HNODE));
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
120
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
121 /* chain it onto the free list */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
122 node->next = s_free_nodes;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
123 s_free_nodes = node;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
124
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
125 } /* end free_node */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
126
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
127 static HNODE *find_node(
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
128 HASHTABLE_INTERNAL *tab, /* pointer to hash table */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
129 const void *key, /* key value to look up */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
130 int bucket) /* bucket number (-1 to have function compute it) */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
131 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
132 find_node walks a hash bucket to find a node whose key matches the named key value.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
133 Returns the node pointer, or NULL if it's not found.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
134 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
135 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
136 register HNODE *p; /* search pointer/return from this function */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
137
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
138 if (bucket<0) /* compute hash value if we don't know it already */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
139 bucket = do_hash(tab,key);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
140
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
141 /* search through the bucket contents */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
142 for (p=tab->buckets[bucket]; p; p=p->next)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
143 if ((*(tab->cmp))(key,p->key)==0)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
144 return p; /* found! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
145
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
146 return NULL; /* not found */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
147
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
148 } /* end find_node */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
149
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
150 static HASHTABLE_INTERNAL *handle2ptr(
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
151 HASHTABLE tbl) /* hash table handle */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
152 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
153 handle2ptr converts a hash table handle into a pointer and checks its signatures
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
154 to make sure someone's not trying to pull a whizzer on this module.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
155 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
156 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
157 register HASHTABLE_INTERNAL *rc = (HASHTABLE_INTERNAL *)tbl;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
158 if ((rc->sig1==HASH_SIG1) && (rc->sig2==HASH_SIG2))
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
159 return rc; /* signatures match */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
160 else
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
161 return NULL; /* yIkes! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
162 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
163
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
164 /*****************************************************************************
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
165 * External functions
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
166 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
167
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
168 HASHTABLE ghash_create(int buckets, KEYHASHFUNC hash, KEYCOMPAREFUNC cmp)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
169 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
170 Description:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
171 Creates a new hash table.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
172
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
173 Input:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
174 Parameters:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
175 buckets - Number of buckets to allocate for the hash table; this value
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
176 should be a prime number for maximum efficiency.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
177 hash - Key hash code function to use.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
178 cmp - Key comparison function to use.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
179
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
180 Output:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
181 Returns:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
182 NULL - Table could not be allocated.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
183 Other - Handle to the new hashtable.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
184 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
185 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
186 HASHTABLE_INTERNAL *tab; /* new table structure */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
187 char *allocated;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
188
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
189 if (!hash || !cmp)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
190 return NULL; /* bogus! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
191
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
192 if (buckets<=0)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
193 buckets = HASH_NUM_BUCKETS;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
194
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
195 /* allocate a hash table structure */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
196 allocated = malloc(sizeof(HASHTABLE_INTERNAL) + (buckets * sizeof(HNODE *)));
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
197 if (!allocated)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
198 return NULL; /* memory error */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
199
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
200 /* fill the fields of the hash table */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
201 tab = (HASHTABLE_INTERNAL *)allocated;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
202 allocated += sizeof(HASHTABLE_INTERNAL);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
203 memset(tab,0,sizeof(HASHTABLE_INTERNAL));
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
204 memset(allocated,0,buckets * sizeof(HNODE *));
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
205 tab->sig1 = HASH_SIG1;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
206 tab->hash = hash;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
207 tab->cmp = cmp;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
208 tab->bcount = buckets;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
209 tab->buckets = (HNODE **)allocated;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
210 tab->sig2 = HASH_SIG2;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
211
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
212 return (HASHTABLE)tab; /* Qa'pla! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
213
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
214 } /* end ghash_create */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
215
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
216 void ghash_destroy(HASHTABLE tbl)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
217 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
218 Description:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
219 Destroys a hash table.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
220
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
221 Input:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
222 Parameters:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
223 tbl - Table to be destroyed.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
224
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
225 Output:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
226 Returns:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
227 Nothing.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
228 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
229 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
230 HASHTABLE_INTERNAL *tab; /* new table structure */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
231 int i; /* loop counter */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
232 HNODE *p, *p2; /* temporary pointers */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
233
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
234 if (!tbl)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
235 return; /* bogus! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
236
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
237 /* Convert the handle to a table pointer. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
238 tab = handle2ptr(tbl);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
239 if (!tab)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
240 return;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
241
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
242 /* Nuke the nodes it contains. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
243 for (i=0; i<tab->bcount; i++)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
244 { /* free the contents of each bucket */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
245 p = tab->buckets[i];
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
246 while (p)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
247 { /* free each node in turn */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
248 p2 = p->next;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
249 free_node(p);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
250 p = p2;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
251
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
252 } /* end while */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
253
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
254 } /* end for */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
255
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
256 free(tab); /* bye bye now! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
257
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
258 } /* end ghash_destroy */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
259
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
260 void *ghash_get(HASHTABLE tbl, const void *key)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
261 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
262 Description:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
263 Retrieves a value stored in the hash table.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
264
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
265 Input:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
266 Parameters:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
267 tbl - The hash table to look in.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
268 key - The key value to search on.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
269
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
270 Output:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
271 Returns:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
272 NULL - Value not found.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
273 Other - Value corresponding to the specified key.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
274 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
275 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
276 HASHTABLE_INTERNAL *tab; /* internal table pointer */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
277 HNODE *node; /* hash node */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
278 void *rc = NULL; /* return from this function */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
279
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
280 if (!tbl || !key)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
281 return NULL; /* bogus! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
282
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
283 /* Convert the handle to a table pointer. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
284 tab = handle2ptr(tbl);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
285 if (!tab)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
286 return NULL; /* error */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
287
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
288 /* Attempt to find the node. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
289 node = find_node(tab,key,-1);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
290 if (node)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
291 rc = node->value; /* found it! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
292
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
293 return rc;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
294
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
295 } /* end ghash_get */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
296
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
297 int ghash_put(HASHTABLE tbl, const void *key, void *value)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
298 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
299 Description:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
300 Associates a key with a value in this hash table.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
301
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
302 Input:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
303 Parameters:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
304 tbl - Hash table to add.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
305 key - Key to use for the value in the table.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
306 value - Value to add for this key.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
307
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
308 Output:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
309 Returns:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
310 1 - Success.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
311 0 - Failure.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
312
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
313 Notes:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
314 If the specified key is already in the hashtable, its value will be replaced.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
315 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
316 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
317 HASHTABLE_INTERNAL *tab; /* internal table pointer */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
318 int bucket; /* bucket value goes into */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
319 HNODE *node; /* hash node */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
320 int rc = 1; /* return from this function */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
321
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
322 if (!tbl || !key || !value)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
323 return 0; /* bogus! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
324
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
325 /* Convert the handle to a table pointer. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
326 tab = handle2ptr(tbl);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
327 if (!tab)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
328 return 0; /* error */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
329
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
330
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
331 /* Compute the hash bucket and try to find an existing node. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
332 bucket = do_hash(tab,key);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
333 node = find_node(tab,key,bucket);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
334 if (!node)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
335 { /* OK, try to allocate a new node. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
336 node = allocate_node(key,value);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
337 if (node)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
338 { /* Chain the new node into the hash table. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
339 node->next = tab->buckets[bucket];
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
340 tab->buckets[bucket] = node;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
341 tab->count++;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
342
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
343 } /* end if */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
344 else /* allocation error */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
345 rc = 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
346
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
347 } /* end if */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
348 else /* already in table - just reassign value */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
349 node->value = value;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
350
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
351 return rc;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
352
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
353 } /* end ghash_put */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
354
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
355 int ghash_remove(HASHTABLE tbl, const void *key)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
356 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
357 Description:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
358 Removes an entry from a hash table, given its key.
414
ec86d759ed54 Trailing whitespace cleanup
Mikael Berthe <mikael@lilotux.net>
parents: 25
diff changeset
359
25
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
360 Input:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
361 Parameters:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
362 tbl - Hash table to remove from.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
363 key - Key of value to remove.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
364
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
365 Output:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
366 Returns:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
367 1 - Success.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
368 0 - Failure; key not present in hash table.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
369 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
370 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
371 HASHTABLE_INTERNAL *tab; /* internal table pointer */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
372 int bucket; /* bucket value goes into */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
373 HNODE *node; /* hash node */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
374 register HNODE *p; /* removal pointer */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
375 int rc = 1; /* return from this function */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
376
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
377 if (!tbl || !key)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
378 return 0; /* bogus! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
379
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
380 /* Convert the handle to a table pointer. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
381 tab = handle2ptr(tbl);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
382 if (!tab)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
383 return 0; /* error */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
384
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
385
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
386 /* Compute the hash bucket and try to find an existing node. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
387 bucket = do_hash(tab,key);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
388 node = find_node(tab,key,bucket);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
389 if (node)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
390 { /* look to unchain it from the bucket it's in */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
391 if (node==tab->buckets[bucket])
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
392 tab->buckets[bucket] = node->next; /* unchain at head */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
393 else
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
394 { /* unchain in middle of list */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
395 for (p=tab->buckets[bucket]; p->next!=node; p=p->next) ;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
396 p->next = node->next;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
397
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
398 } /* end else */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
399
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
400 free_node(node); /* bye bye now! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
401 tab->count--;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
402
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
403 } /* end if */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
404 else /* node not found */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
405 rc = 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
406
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
407 return rc;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
408
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
409 } /* end ghash_remove */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
410
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
411 int ghash_walk(HASHTABLE tbl, TABLEWALKFUNC func, void *user_data)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
412 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
413 Description:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
414 "Walks" through a hash table, calling a callback function for each element
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
415 stored in it.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
416
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
417 Input:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
418 Parameters:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
419 tbl - Hash table to walk.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
420 func - Function to be called for each node. It takes three parameters,
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
421 a user data pointer, a key value pointer, and a data value pointer.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
422 It returns 0 to stop the enumeration or 1 to keep it going.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
423 user_data - Value to use as the first parameter for the callback
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
424 function.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
425
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
426 Output:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
427 Returns:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
428 0 - Error occurred.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
429 Other - Number of nodes visited up to and including the one for which
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
430 the callback function returned 0, if it did; ranges from 1
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
431 to the number of nodes in the hashtable.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
432 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
433 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
434 HASHTABLE_INTERNAL *tab; /* internal table pointer */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
435 int i; /* loop counter */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
436 int running = 1; /* we're still running */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
437 int count = 0; /* number of nodes visited before stop node */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
438 register HNODE *p, *p2; /* loop pointer */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
439
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
440 if (!tbl || !func)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
441 return -1; /* bogus values! */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
442
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
443 /* Convert the handle to a table pointer. */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
444 tab = handle2ptr(tbl);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
445 if (!tab)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
446 return -1; /* error */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
447
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
448
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
449 for (i=0; running && (i<tab->bcount); i++)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
450 { /* visit the contents of each bucket */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
451 p = tab->buckets[i];
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
452 while (running && p)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
453 { /* visit each node in turn */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
454 p2 = p->next;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
455 count++;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
456 running = (*func)(user_data,p->key,p->value);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
457 p = p2;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
458
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
459 } /* end while */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
460
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
461 } /* end for */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
462
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
463 return count;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
464
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
465 } /* end ghash_walk */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
466
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
467 int str_hash_code(const char *s)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
468 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
469 Description:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
470 Generates a hash code for a string. This function uses the ELF hashing
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
471 algorithm as reprinted in Andrew Binstock, "Hashing Rehashed," _Dr.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
472 Dobb's Journal_, April 1996.
414
ec86d759ed54 Trailing whitespace cleanup
Mikael Berthe <mikael@lilotux.net>
parents: 25
diff changeset
473
25
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
474 Input:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
475 Parameters:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
476 s - The string to be hashed.
414
ec86d759ed54 Trailing whitespace cleanup
Mikael Berthe <mikael@lilotux.net>
parents: 25
diff changeset
477
25
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
478 Output:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
479 Returns:
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
480 A hash code for the string.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
481 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
482 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
483 /* ELF hash uses unsigned chars and unsigned arithmetic for portability */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
484 const unsigned char *name = (const unsigned char *)s;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
485 unsigned long h = 0, g;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
486
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
487 if (!name)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
488 return 0; /* anti-NULL guard not in the original */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
489
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
490 while (*name)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
491 { /* do some fancy bitwanking on the string */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
492 h = (h << 4) + (unsigned long)(*name++);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
493 if ((g = (h & 0xF0000000UL))!=0)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
494 h ^= (g >> 24);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
495 h &= ~g;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
496
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
497 } /* end while */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
498
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
499 return (int)h;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
500
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
501 }