more rendering corrections
[AROS.git] / workbench / devs / ram_handler / HashTable.c
blob2f343f873ea56dcafe69d7edff880f7fcbdbcdd6
1 /*
2 Copyright © 1995-2008, 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 extern STRPTR Strdup(struct rambase *rambase, STRPTR string);
19 extern void Strfree(struct rambase *rambase, STRPTR string);
21 typedef struct _HashNode
23 struct Node node;
24 void *key;
25 struct List requests;
26 } HashNode;
28 static HashNode *find(struct rambase *rambase, HashTable *ht,
29 const void *key, struct List *list);
31 HashTable *HashTable_new(struct rambase *rambase, ULONG size,
32 ULONG (*hash)(struct rambase *rambase,
33 const void *key),
34 int (*compare)(struct rambase *rambase,
35 const void *key1,
36 const void *key2),
37 void (*delete)(struct rambase *rambase,
38 void *key,
39 struct List *list))
41 ULONG i; /* Loop variable */
42 HashTable *ht = AllocVec(sizeof(HashTable), MEMF_ANY);
44 if (ht == NULL)
46 return NULL;
49 ht->size = size;
50 ht->nElems = 0;
51 ht->array = AllocVec(sizeof(struct List)*size, MEMF_ANY);
53 if (ht->array == NULL)
55 FreeVec(ht);
57 return NULL;
60 ht->hash = hash;
61 ht->compare = compare;
62 ht->delete = delete;
64 for (i = 0; i < size; i++)
66 NewList(&ht->array[i]);
69 return ht;
73 /* TODO: Fix the double list thing, remove the (void *) hack */
74 void HashTable_delete(struct rambase *rambase, HashTable *ht)
76 ULONG i;
78 for (i = 0; i < ht->size; i++)
80 while (!IsListEmpty(&ht->array[i]))
82 HashNode *hn = (HashNode *)RemHead(&ht->array[i]);
84 ht->delete(rambase, hn->key, (void *)&hn->requests);
85 FreeVec(hn);
89 FreeVec(ht);
93 void HashTable_insert(struct rambase *rambase, HashTable *ht, void *key,
94 struct Receiver *rr)
96 ULONG pos;
97 HashNode *hn;
99 pos = ht->hash(rambase, key) % ht->size;
101 hn = find(rambase, ht, key, &ht->array[pos]);
103 if (hn == NULL)
105 /* There was no previous request for this entity */
106 hn = AllocVec(sizeof(HashNode), MEMF_ANY);
108 if (hn == NULL)
110 return;
113 hn->key = Strdup(rambase, key);
115 if (hn->key == NULL)
117 FreeVec(hn);
118 return;
121 NewList(&hn->requests);
122 AddHead(&ht->array[pos], &hn->node);
125 AddHead(&hn->requests, &rr->node);
127 ht->nElems++;
131 void HashTable_remove(struct rambase *rambase, HashTable *ht, void *key)
133 HashNode *hn;
134 ULONG pos;
135 struct Node *tempNode;
136 struct List *list;
138 pos = ht->hash(rambase, key) % ht->size;
139 list = &ht->array[pos];
141 ForeachNodeSafe(list, hn, tempNode)
143 if (ht->compare(rambase, key, hn->key) == 0)
145 Remove(&hn->node);
146 ht->delete(rambase, hn->key, (void *)&hn->requests);
147 FreeVec(hn);
148 break;
154 static HashNode *find(struct rambase *rambase, HashTable *ht,
155 const void *key, struct List *list)
157 HashNode *hn; /* Loop variable */
159 ForeachNode(list, hn)
161 if (ht->compare(rambase, key, hn->key) == 0)
163 return hn;
167 return NULL;
171 struct List *HashTable_find(struct rambase *rambase, HashTable *ht,
172 const void *key)
174 HashNode *hn;
175 ULONG pos;
177 pos = ht->hash(rambase, key) % ht->size;
178 hn = find(rambase, ht, key, &ht->array[pos]);
180 if (hn != NULL)
181 return &hn->requests;
183 return NULL;
187 inline ULONG HashTable_size(HashTable *ht)
189 return ht->nElems;