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