]> andersk Git - moira.git/blame - lib/hash.c
missing coma in last change, causes compile_et to coredump
[moira.git] / lib / hash.c
CommitLineData
b93ad422 1/* $Header$
2 *
3 * Generic hash table routines. Uses integer keys to store char * values.
babbc197 4 *
5 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
b93ad422 8 */
9
babbc197 10#include <mit-copyright.h>
b93ad422 11#include <ctype.h>
8defc06b 12#include <moira.h>
8fd777cf 13#include <string.h>
d9e7aa31 14
24582af9 15extern char *malloc();
16
b93ad422 17#define NULL 0
8e24e9aa 18#define hash_func(h, key) (key >= 0 ? (key % h->size) : (-key % h->size))
b93ad422 19
20/* Create a hash table. The size is just a hint, not a maximum. */
21
22struct hash *create_hash(size)
23int size;
24{
25 struct hash *h;
26
27 h = (struct hash *) malloc(sizeof(struct hash));
7b0a0eca 28 if (h == (struct hash *) NULL)
29 return((struct hash *) NULL);
b93ad422 30 h->size = size;
31 h->data = (struct bucket **) malloc(size * sizeof(char *));
7b0a0eca 32 if (h->data == (struct bucket **) NULL) {
33 free(h);
34 return((struct hash *) NULL);
35 }
8fd777cf 36 memset(h->data, 0, size * sizeof(char *));
b93ad422 37 return(h);
38}
39
40/* Lookup an object in the hash table. Returns the value associated with
41 * the key, or NULL (thus NULL is not a very good value to store...)
42 */
43
44char *hash_lookup(h, key)
45struct hash *h;
46register int key;
47{
48 register struct bucket *b;
49
8e24e9aa 50 b = h->data[hash_func(h, key)];
b93ad422 51 while (b && b->key != key)
52 b = b->next;
53 if (b && b->key == key)
54 return(b->data);
55 else
56 return(NULL);
57}
58
59
60/* Update an existing object in the hash table. Returns 1 if the object
61 * existed, or 0 if not.
62 */
63
64int hash_update(h, key, value)
65struct hash *h;
66register int key;
67char *value;
68{
69 register struct bucket *b;
70
8e24e9aa 71 b = h->data[hash_func(h, key)];
b93ad422 72 while (b && b->key != key)
73 b = b->next;
74 if (b && b->key == key) {
75 b->data = value;
76 return(1);
77 } else
78 return(0);
79}
80
81
82/* Store an item in the hash table. Returns 0 if the key was not previously
7b0a0eca 83 * there, 1 if it was, or -1 if we ran out of memory.
b93ad422 84 */
85
86int hash_store(h, key, value)
87struct hash *h;
88register int key;
89char *value;
90{
91 register struct bucket *b, **p;
92
8e24e9aa 93 p = &(h->data[hash_func(h, key)]);
b93ad422 94 if (*p == NULL) {
95 b = *p = (struct bucket *) malloc(sizeof(struct bucket));
7b0a0eca 96 if (b == (struct bucket *) NULL)
97 return(-1);
b93ad422 98 b->next = NULL;
99 b->key = key;
100 b->data = value;
101 return(0);
102 }
103
104 for (b = *p; b && b->key != key; b = *p)
105 p = (struct bucket **) *p;
106 if (b && b->key == key) {
107 b->data = value;
108 return(1);
109 }
110 b = *p = (struct bucket *) malloc(sizeof(struct bucket));
7b0a0eca 111 if (b == (struct bucket *) NULL)
112 return(-1);
b93ad422 113 b->next = NULL;
114 b->key = key;
115 b->data = value;
116 return(0);
117}
118
119
120/* Search through the hash table for a given value. For each piece of
121 * data with that value, call the callback proc with the corresponding key.
122 */
123
124hash_search(h, value, callback)
125struct hash *h;
126register char *value;
127void (*callback)();
128{
129 register struct bucket *b, **p;
130
131 for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
132 for (b = *p; b; b = b->next) {
133 if (b->data == value)
134 (*callback)(b->key);
135 }
136 }
137}
138
139
0efcee1f 140/* Step through the hash table, calling the callback proc with each key.
141 */
142
07d9123c 143hash_step(h, callback, hint)
0efcee1f 144struct hash *h;
145void (*callback)();
07d9123c 146char *hint;
0efcee1f 147{
148 register struct bucket *b, **p;
149
150 for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
151 for (b = *p; b; b = b->next) {
07d9123c 152 (*callback)(b->key, b->data, hint);
0efcee1f 153 }
154 }
155}
156
157
b93ad422 158/* Deallocate all of the memory associated with a table */
159
160hash_destroy(h)
161struct hash *h;
162{
163 register struct bucket *b, **p, *b1;
164
165 for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
166 for (b = *p; b; b = b1) {
167 b1 = b->next;
168 free(b);
169 }
170 }
171}
This page took 0.163453 seconds and 5 git commands to generate.