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