]> andersk Git - moira.git/blame - lib/hash.c
Command line printer manipulation client, and build goo.
[moira.git] / lib / hash.c
CommitLineData
fa59b86f 1/* $Id$
b93ad422 2 *
3 * Generic hash table routines. Uses integer keys to store char * values.
babbc197 4 *
7ac48069 5 * Copyright (C) 1988-1998 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>
8defc06b 11#include <moira.h>
7ac48069 12
a43ce477 13#include <stdlib.h>
7ac48069 14#include <string.h>
15
16RCSID("$Header$");
d9e7aa31 17
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
5eaef520 22struct hash *create_hash(int size)
b93ad422 23{
5eaef520 24 struct hash *h;
25
26 h = malloc(sizeof(struct hash));
27 if (!h)
28 return NULL;
29 h->size = size;
7ac48069 30 h->data = malloc(size * sizeof(void *));
5eaef520 31 if (!h->data)
32 {
33 free(h);
34 return NULL;
7b0a0eca 35 }
7ac48069 36 memset(h->data, 0, size * sizeof(void *));
5eaef520 37 return h;
b93ad422 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
7ac48069 44void *hash_lookup(struct hash *h, int key)
b93ad422 45{
44d12d58 46 struct bucket *b;
5eaef520 47
48 b = h->data[hash_func(h, key)];
49 while (b && b->key != key)
50 b = b->next;
51 if (b && b->key == key)
52 return b->data;
53 else
54 return NULL;
b93ad422 55}
56
57
58/* Update an existing object in the hash table. Returns 1 if the object
59 * existed, or 0 if not.
60 */
61
7ac48069 62int hash_update(struct hash *h, int key, void *value)
b93ad422 63{
44d12d58 64 struct bucket *b;
5eaef520 65
66 b = h->data[hash_func(h, key)];
67 while (b && b->key != key)
68 b = b->next;
69 if (b && b->key == key)
70 {
71 b->data = value;
72 return 1;
73 }
74 else
75 return 0;
b93ad422 76}
77
78
79/* Store an item in the hash table. Returns 0 if the key was not previously
7b0a0eca 80 * there, 1 if it was, or -1 if we ran out of memory.
b93ad422 81 */
82
7ac48069 83int hash_store(struct hash *h, int key, void *value)
b93ad422 84{
44d12d58 85 struct bucket *b, **p;
5eaef520 86
87 p = &(h->data[hash_func(h, key)]);
88 if (!*p)
89 {
90 b = *p = malloc(sizeof(struct bucket));
91 if (!b)
92 return -1;
93 b->next = NULL;
94 b->key = key;
95 b->data = value;
96 return 0;
b93ad422 97 }
98
5eaef520 99 for (b = *p; b && b->key != key; b = *p)
100 p = (struct bucket **) *p;
101 if (b && b->key == key)
102 {
103 b->data = value;
104 return 1;
b93ad422 105 }
5eaef520 106 b = *p = malloc(sizeof(struct bucket));
107 if (!b)
108 return -1;
109 b->next = NULL;
110 b->key = key;
111 b->data = value;
112 return 0;
b93ad422 113}
114
115
116/* Search through the hash table for a given value. For each piece of
117 * data with that value, call the callback proc with the corresponding key.
118 */
119
7ac48069 120void hash_search(struct hash *h, void *value, void (*callback)(int))
b93ad422 121{
44d12d58 122 struct bucket *b, **p;
5eaef520 123
124 for (p = &(h->data[h->size - 1]); p >= h->data; p--)
125 {
126 for (b = *p; b; b = b->next)
127 {
128 if (b->data == value)
129 (*callback)(b->key);
b93ad422 130 }
131 }
132}
133
134
0efcee1f 135/* Step through the hash table, calling the callback proc with each key.
136 */
137
7ac48069 138void hash_step(struct hash *h, void (*callback)(int, void *, void *),
139 void *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
7ac48069 153void hash_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.311988 seconds and 5 git commands to generate.