Annotation of embedaddon/trafshow/hashtab.h, revision 1.1.1.1
1.1 misho 1: /*
2: --------------------------------------------------------------------
3: By Bob Jenkins, 1996. hash.h. Public Domain.
4:
5: This implements a hash table.
6: * Keys are unique. Adding an item fails if the key is already there.
7: * Keys and items are pointed at, not copied. If you change the value
8: of the key after it is inserted then hfind will not be able to find it.
9: * The hash table maintains a position that can be set and queried.
10: * The table length doubles dynamically and never shrinks. The insert
11: that causes table doubling may take a long time.
12: * The table length splits when the table length equals the number of items
13: Comparisons usually take 7 instructions.
14: Computing a hash value takes 35+6n instructions for an n-byte key.
15:
16: hcreate - create a hash table
17: hdestroy - destroy a hash table
18: hcount - The number of items in the hash table
19: hkey - key at the current position
20: hkeyl - key length at the current position
21: hstuff - stuff at the current position
22: hfind - find an item in the table
23: hadd - insert an item into the table
24: hdel - delete an item from the table
25: hstat - print statistics about the table
26: hfirst - position at the first item in the table
27: hnext - move the position to the next item in the table
28: --------------------------------------------------------------------
29: */
30:
31: #ifndef STANDARD
32: #include "standard.h"
33: #endif
34:
35: #ifndef HASHTAB
36: #define HASHTAB
37:
38: /* PRIVATE TYPES AND DEFINITIONS */
39:
40: struct hitem
41: {
42: ub1 *key; /* key that is hashed */
43: ub4 keyl; /* length of key */
44: void *stuff; /* stuff stored in this hitem */
45: ub4 hval; /* hash value */
46: struct hitem *next; /* next hitem in list */
47: };
48: typedef struct hitem hitem;
49:
50:
51: struct htab
52: {
53: struct hitem **table; /* hash table, array of size 2^logsize */
54: word logsize; /* log of size of table */
55: size_t mask; /* (hashval & mask) is position in table */
56: ub4 count; /* how many items in this hash table so far? */
57: ub4 apos; /* position in the array */
58: struct hitem *ipos; /* current item in the array */
59: struct reroot *space; /* space for the hitems */
60: ub4 bcount; /* # hitems useable in current block */
61: };
62: typedef struct htab htab;
63:
64:
65:
66:
67:
68: /* PUBLIC FUNCTIONS */
69:
70: /* hcreate - create a hash table
71: ARGUMENTS:
72: logsize - 1<<logsize will be the initial table length
73: RETURNS:
74: the new table
75: */
76: htab *hcreate(word logsize);
77:
78:
79: /* hdestroy - destroy a hash table
80: ARGUMENTS:
81: t - the hash table to be destroyed. Note that the items and keys
82: will not be freed, the user created them and must destroy
83: them himself.
84: RETURNS:
85: nothing
86: */
87: void hdestroy(htab *t);
88:
89:
90: /* hcount, hkey, hkeyl, hstuff
91: ARGUMENTS:
92: t - the hash table
93: RETURNS:
94: hcount - (ub4) The number of items in the hash table
95: hkey - (ub1 *) key for the current item
96: hkeyl - (ub4) key length for the current item
97: hstuff - (void *) stuff for the current item
98: NOTE:
99: The current position always has an item as long as there
100: are items in the table, so hexist can be used to test if the
101: table is empty.
102: hkey, hkeyl, and hstuff will crash if hcount returns 0
103: */
104: #define hcount(t) ((t)->count)
105: #define hkey(t) ((t)->ipos->key)
106: #define hkeyl(t) ((t)->ipos->keyl)
107: #define hstuff(t) ((t)->ipos->stuff)
108:
109:
110:
111: /* hfind - move the current position to a given key
112: ARGUMENTS:
113: t - the hash table
114: key - the key to look for
115: keyl - length of the key
116: RETURNS:
117: TRUE if the item exists, FALSE if it does not.
118: If the item exists, moves the current position to that item.
119: */
120: word hfind(htab *t, ub1 *key, ub4 keyl);
121:
122:
123: /* hadd - add a new item to the hash table
124: change the position to point at the item with the key
125: ARGUMENTS:
126: t - the hash table
127: key - the key to look for
128: keyl - length of the key
129: stuff - other stuff to be stored in this item
130: RETURNS:
131: FALSE if the operation fails (because that key is already there).
132: */
133: word hadd(htab *t, ub1 *key, ub4 keyl, void *stuff);
134:
135:
136: /* hdel - delete the item at the current position
137: change the position to the following item
138: ARGUMENTS:
139: t - the hash table
140: RETURNS:
141: FALSE if there is no current item (meaning the table is empty)
142: NOTE:
143: This frees the item, but not the key or stuff stored in the item.
144: If you want these then deal with them first. For example:
145: if (hfind(tab, key, keyl))
146: {
147: free(hkey(tab));
148: free(hstuff(tab));
149: hdel(tab);
150: }
151: */
152: word hdel(htab *t);
153:
154:
155: /* hfirst - move position to the first item in the table
156: ARGUMENTS:
157: t - the hash table
158: RETURNS:
159: FALSE if there is no current item (meaning the table is empty)
160: NOTE:
161: */
162: word hfirst(htab *t);
163:
164:
165: /* hnext - move position to the next item in the table
166: ARGUMENTS:
167: t - the hash table
168: RETURNS:
169: FALSE if the position wraps around to the beginning of the table
170: NOTE:
171: To see every item in the table, do
172: if (hfirst(t)) do
173: {
174: key = hkey(t);
175: stuff = hstuff(t);
176: }
177: while (hnext(t));
178: */
179: /* word hnext(htab *t); */
180: #define hnext(t) \
181: ((!(t)->ipos) ? FALSE : \
182: ((t)->ipos=(t)->ipos->next) ? TRUE : hnbucket(t))
183:
184: /* hnbucket - PRIVATE - move to first item in the next nonempty bucket
185: ARGUMENTS:
186: t - the hash table
187: RETURNS:
188: FALSE if the position wraps around to the beginning of the table
189: NOTE:
190: This is private to hashtab; do not use it externally.
191: */
192: word hnbucket(htab *t);
193:
194:
195: /* hstat - print statistics about the hash table
196: ARGUMENTS:
197: t - the hash table
198: NOTE:
199: items <0>: <#buckets with zero items> buckets
200: items <1>: <#buckets with 1 item> buckets
201: ...
202: buckets: #buckets items: #items existing: x
203: ( x is the average length of the list when you look for an
204: item that exists. When the item does not exists, the average
205: length is #items/#buckets. )
206:
207: If you put n items into n buckets, expect 1/(n!)e buckets to
208: have n items. That is, .3678 0, .3678 1, .1839 2, ...
209: Also expect "existing" to be about 2.
210: */
211: void hstat(FILE *fp, htab *t);
212:
213: #endif /* HASHTAB */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>