added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / devs / ram_handler / HashTable.c
blobb2c5094e302ef427b3ac94fb3f8d33392080109d
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 An Hash Table implementation.
6 */
8 #include "HashTable.h"
10 #include <exec/types.h>
11 #include <exec/memory.h>
12 #include <proto/alib.h>
13 #include <proto/exec.h>
15 #define DEBUG 0
16 #include <aros/debug.h>
18 #ifdef UtilityBase
19 #undef UtilityBase
20 #endif
21 #define UtilityBase rambase->utilitybase
23 extern STRPTR Strdup(struct rambase *rambase, STRPTR string);
24 extern void Strfree(struct rambase *rambase, STRPTR string);
26 typedef struct _HashNode
28 struct Node node;
29 void *key;
30 struct List requests;
31 } HashNode;
33 static HashNode *find(struct rambase *rambase, HashTable *ht,
34 const void *key, struct List *list);
36 HashTable *HashTable_new(struct rambase *rambase, ULONG size,
37 ULONG (*hash)(struct rambase *rambase,
38 const void *key),
39 int (*compare)(struct rambase *rambase,
40 const void *key1,
41 const void *key2),
42 void (*delete)(struct rambase *rambase,
43 void *key,
44 struct List *list))
46 ULONG i; /* Loop variable */
47 HashTable *ht = AllocVec(sizeof(HashTable), MEMF_ANY);
49 if (ht == NULL)
51 return NULL;
54 ht->size = size;
55 ht->nElems = 0;
56 ht->array = AllocVec(sizeof(struct List)*size, MEMF_ANY);
58 if (ht->array == NULL)
60 FreeVec(ht);
62 return NULL;
65 ht->hash = hash;
66 ht->compare = compare;
67 ht->delete = delete;
69 for (i = 0; i < size; i++)
71 NewList(&ht->array[i]);
74 return ht;
78 /* TODO: Fix the double list thing, remove the (void *) hack */
79 void HashTable_delete(struct rambase *rambase, HashTable *ht)
81 ULONG i;
83 for (i = 0; i < ht->size; i++)
85 while (!IsListEmpty(&ht->array[i]))
87 HashNode *hn = (HashNode *)RemHead(&ht->array[i]);
89 ht->delete(rambase, hn->key, (void *)&hn->requests);
90 FreeVec(hn);
94 FreeVec(ht);
98 void HashTable_insert(struct rambase *rambase, HashTable *ht, void *key,
99 struct Receiver *rr)
101 ULONG pos;
102 HashNode *hn;
104 pos = ht->hash(rambase, key) % ht->size;
106 hn = find(rambase, ht, key, &ht->array[pos]);
108 if (hn == NULL)
110 /* There was no previous request for this entity */
111 hn = AllocVec(sizeof(HashNode), MEMF_ANY);
113 if (hn == NULL)
115 return;
118 hn->key = Strdup(rambase, key);
120 if (hn->key == NULL)
122 FreeVec(hn);
123 return;
126 NewList(&hn->requests);
127 AddHead(&ht->array[pos], &hn->node);
130 AddHead(&hn->requests, &rr->node);
132 ht->nElems++;
136 void HashTable_remove(struct rambase *rambase, HashTable *ht, void *key)
138 HashNode *hn;
139 ULONG pos;
140 struct Node *tempNode;
141 struct List *list;
143 pos = ht->hash(rambase, key) % ht->size;
144 list = &ht->array[pos];
146 ForeachNodeSafe(list, hn, tempNode)
148 if (ht->compare(rambase, key, hn->key) == 0)
150 Remove(&hn->node);
151 ht->delete(rambase, hn->key, (void *)&hn->requests);
152 FreeVec(hn);
153 break;
159 static HashNode *find(struct rambase *rambase, HashTable *ht,
160 const void *key, struct List *list)
162 HashNode *hn; /* Loop variable */
164 ForeachNode(list, hn)
166 if (ht->compare(rambase, key, hn->key) == 0)
168 return hn;
172 return NULL;
176 struct List *HashTable_find(struct rambase *rambase, HashTable *ht,
177 const void *key)
179 HashNode *hn;
180 ULONG pos;
182 pos = ht->hash(rambase, key) % ht->size;
183 hn = find(rambase, ht, key, &ht->array[pos]);
185 if (hn != NULL)
186 return &hn->requests;
188 return NULL;
192 inline ULONG HashTable_size(HashTable *ht)
194 return ht->nElems;