]> andersk Git - moira.git/blame - lib/hash.c
Initial revision
[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>
d9e7aa31 12#include <sms.h>
13
b93ad422 14#define NULL 0
8e24e9aa 15#define hash_func(h, key) (key >= 0 ? (key % h->size) : (-key % h->size))
b93ad422 16
17/* Create a hash table. The size is just a hint, not a maximum. */
18
19struct hash *create_hash(size)
20int size;
21{
22 struct hash *h;
23
24 h = (struct hash *) malloc(sizeof(struct hash));
25 h->size = size;
26 h->data = (struct bucket **) malloc(size * sizeof(char *));
27 bzero(h->data, size * sizeof(char *));
28 return(h);
29}
30
31/* Lookup an object in the hash table. Returns the value associated with
32 * the key, or NULL (thus NULL is not a very good value to store...)
33 */
34
35char *hash_lookup(h, key)
36struct hash *h;
37register int key;
38{
39 register struct bucket *b;
40
8e24e9aa 41 b = h->data[hash_func(h, key)];
b93ad422 42 while (b && b->key != key)
43 b = b->next;
44 if (b && b->key == key)
45 return(b->data);
46 else
47 return(NULL);
48}
49
50
51/* Update an existing object in the hash table. Returns 1 if the object
52 * existed, or 0 if not.
53 */
54
55int hash_update(h, key, value)
56struct hash *h;
57register int key;
58char *value;
59{
60 register struct bucket *b;
61
8e24e9aa 62 b = h->data[hash_func(h, key)];
b93ad422 63 while (b && b->key != key)
64 b = b->next;
65 if (b && b->key == key) {
66 b->data = value;
67 return(1);
68 } else
69 return(0);
70}
71
72
73/* Store an item in the hash table. Returns 0 if the key was not previously
74 * there, or 1 if it was.
75 */
76
77int hash_store(h, key, value)
78struct hash *h;
79register int key;
80char *value;
81{
82 register struct bucket *b, **p;
83
8e24e9aa 84 p = &(h->data[hash_func(h, key)]);
b93ad422 85 if (*p == NULL) {
86 b = *p = (struct bucket *) malloc(sizeof(struct bucket));
87 b->next = NULL;
88 b->key = key;
89 b->data = value;
90 return(0);
91 }
92
93 for (b = *p; b && b->key != key; b = *p)
94 p = (struct bucket **) *p;
95 if (b && b->key == key) {
96 b->data = value;
97 return(1);
98 }
99 b = *p = (struct bucket *) malloc(sizeof(struct bucket));
100 b->next = NULL;
101 b->key = key;
102 b->data = value;
103 return(0);
104}
105
106
107/* Search through the hash table for a given value. For each piece of
108 * data with that value, call the callback proc with the corresponding key.
109 */
110
111hash_search(h, value, callback)
112struct hash *h;
113register char *value;
114void (*callback)();
115{
116 register struct bucket *b, **p;
117
118 for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
119 for (b = *p; b; b = b->next) {
120 if (b->data == value)
121 (*callback)(b->key);
122 }
123 }
124}
125
126
0efcee1f 127/* Step through the hash table, calling the callback proc with each key.
128 */
129
07d9123c 130hash_step(h, callback, hint)
0efcee1f 131struct hash *h;
132void (*callback)();
07d9123c 133char *hint;
0efcee1f 134{
135 register struct bucket *b, **p;
136
137 for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
138 for (b = *p; b; b = b->next) {
07d9123c 139 (*callback)(b->key, b->data, hint);
0efcee1f 140 }
141 }
142}
143
144
b93ad422 145/* Deallocate all of the memory associated with a table */
146
147hash_destroy(h)
148struct hash *h;
149{
150 register struct bucket *b, **p, *b1;
151
152 for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
153 for (b = *p; b; b = b1) {
154 b1 = b->next;
155 free(b);
156 }
157 }
158}
This page took 0.079019 seconds and 5 git commands to generate.