source: trunk/athena/lib/Xj/hash.c @ 12350

Revision 12350, 4.3 KB checked in by ghudson, 26 years ago (diff)
Some RCS ID cleanup: delete $Log$ and replace other RCS keywords with $Id$.
Line 
1/*
2 * Generic hash table routines.  Uses integer keys to store objects.
3 *
4 * $Id: hash.c,v 1.2 1999-01-22 23:17:08 ghudson Exp $
5 *
6 *  (c) Copyright 1988,1991 by the Massachusetts Institute of Technology.
7 *  For copying and distribution information, please see the file
8 *  mit-copyright.h.
9 *
10 *  This file contains the hash table functions create_hash, hash_lookup,
11 *  hash_store, hash_update, hash_search, hash_step, and hash_destroy.
12 *
13 *  Since only the functions create_hash, hash_lookup, and hash_store are
14 *  used, the others have been commented out.  They should be uncommented
15 *  if needed.
16 *
17 *  The general code for these hash table routines were copied from
18 *  another project (smsdev).
19 */
20
21#if  (!defined(lint))  &&  (!defined(SABER))
22static char rcsid[] =
23"$Id: hash.c,v 1.2 1999-01-22 23:17:08 ghudson Exp $";
24#endif
25
26#include "mit-copyright.h"
27#include <stdio.h> /* this is annoying... */
28#include "Jets.h"
29#include "hash.h"
30
31
32#define hash_func(h,key) (key>=0 ? (key % h->size) : (-key % h->size))
33
34
35/* Create a hash table.  The size is just a hint, not a maximum. */
36
37struct hash *create_hash(size)
38     int size;
39{
40    struct hash *h;
41
42    h = (struct hash *) XjMalloc((unsigned) sizeof(struct hash));
43    h->size = size;
44    h->data = (struct bucket **) XjMalloc((unsigned) size
45                                          * sizeof(struct bucket *));
46    memset(h->data, 0, size * sizeof(struct bucket *));
47    return(h);
48}
49
50/* Lookup an object in the hash table.  Returns the value associated with
51 * the key, or NULL (thus NULL is not a very good value to store...)
52 */
53
54caddr_t hash_lookup(h, key)
55     struct hash *h;
56     register int key;
57{
58    register struct bucket *b;
59
60    b = h->data[hash_func(h,key)];
61    while (b && b->key != key)
62      b = b->next;
63    if (b && b->key == key)
64      return(b->data);
65    else
66      return(NULL);
67}
68
69
70/* Store an item in the hash table.  Returns 0 if the key was not previously
71 * there, or 1 if it was.
72 */
73
74int hash_store(h, key, value)
75     struct hash *h;
76     register int key;
77     caddr_t value;
78{
79    register struct bucket *b, **p;
80
81    p = &(h->data[hash_func(h,key)]);
82    if (*p == NULL) {
83        b = *p = (struct bucket *) XjMalloc((unsigned) sizeof(struct bucket));
84        b->next = NULL;
85        b->key = key;
86        b->data = value;
87        return(0);
88    }
89
90    for (b = *p; b && b->key != key; b = *p)
91      p = (struct bucket **) *p;
92    if (b && b->key == key) {
93        b->data = value;
94        return(1);
95    }
96    b = *p = (struct bucket *) XjMalloc((unsigned) sizeof(struct bucket));
97    b->next = NULL;
98    b->key = key;
99    b->data = value;
100    return(0);
101}
102
103
104caddr_t hash_give_any_value(h, key)
105     struct hash *h;
106     int *key;
107{
108  register struct bucket *b, **p;
109
110  for (p = &(h->data[h->size - 1]); p >= h->data; p--)
111    {
112      b = *p;
113      if (b)
114        {
115          *key = b->key;
116          return(b->data);
117        }
118    }
119
120  return(0);
121}
122
123
124#ifdef notdef
125
126/****************************************************************************/
127/* Update an existing object in the hash table.  Returns 1 if the object
128 * existed, or 0 if not.
129 */
130
131int hash_update(h, key, value)
132struct hash *h;
133register int key;
134caddr_t value;
135{
136    register struct bucket *b;
137
138    b = h->data[hash_func(h,key)];
139    while (b && b->key != key)
140      b = b->next;
141    if (b && b->key == key) {
142        b->data = value;
143        return(1);
144    } else
145      return(0);
146}
147
148/* Search through the hash table for a given value.  For each piece of
149 * data with that value, call the callback proc with the corresponding key.
150 */
151
152hash_search(h, value, callback)
153struct hash *h;
154register caddr_t value;
155void (*callback)();
156{
157    register struct bucket *b, **p;
158
159    for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
160        for (b = *p; b; b = b->next) {
161            if (b->data == value)
162              (*callback)(b->key);
163        }
164    }
165}
166
167
168/* Step through the hash table, calling the callback proc with each key.
169 */
170
171hash_step(h, callback, hint)
172struct hash *h;
173void (*callback)();
174caddr_t hint;
175{
176    register struct bucket *b, **p;
177
178    for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
179        for (b = *p; b; b = b->next) {
180            (*callback)(b->key, b->data, hint);
181        }
182    }
183}
184
185
186/* Deallocate all of the memory associated with a table */
187
188hash_destroy(h)
189struct hash *h;
190{
191    register struct bucket *b, **p, *b1;
192
193    for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
194        for (b = *p; b; b = b1) {
195            b1 = b->next;
196            free(b);
197        }
198    }
199}
200
201#endif /* notdef */
Note: See TracBrowser for help on using the repository browser.