2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 An Hash Table implementation.
10 #include <exec/types.h>
11 #include <exec/memory.h>
12 #include <proto/alib.h>
13 #include <proto/exec.h>
16 #include <aros/debug.h>
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
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
,
39 int (*compare
)(struct rambase
*rambase
,
42 void (*delete)(struct rambase
*rambase
,
46 ULONG i
; /* Loop variable */
47 HashTable
*ht
= AllocVec(sizeof(HashTable
), MEMF_ANY
);
56 ht
->array
= AllocVec(sizeof(struct List
)*size
, MEMF_ANY
);
58 if (ht
->array
== NULL
)
66 ht
->compare
= compare
;
69 for (i
= 0; i
< size
; i
++)
71 NewList(&ht
->array
[i
]);
78 /* TODO: Fix the double list thing, remove the (void *) hack */
79 void HashTable_delete(struct rambase
*rambase
, HashTable
*ht
)
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
);
98 void HashTable_insert(struct rambase
*rambase
, HashTable
*ht
, void *key
,
104 pos
= ht
->hash(rambase
, key
) % ht
->size
;
106 hn
= find(rambase
, ht
, key
, &ht
->array
[pos
]);
110 /* There was no previous request for this entity */
111 hn
= AllocVec(sizeof(HashNode
), MEMF_ANY
);
118 hn
->key
= Strdup(rambase
, key
);
126 NewList(&hn
->requests
);
127 AddHead(&ht
->array
[pos
], &hn
->node
);
130 AddHead(&hn
->requests
, &rr
->node
);
136 void HashTable_remove(struct rambase
*rambase
, HashTable
*ht
, void *key
)
140 struct Node
*tempNode
;
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)
151 ht
->delete(rambase
, hn
->key
, (void *)&hn
->requests
);
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)
176 struct List
*HashTable_find(struct rambase
*rambase
, HashTable
*ht
,
182 pos
= ht
->hash(rambase
, key
) % ht
->size
;
183 hn
= find(rambase
, ht
, key
, &ht
->array
[pos
]);
186 return &hn
->requests
;
192 inline ULONG
HashTable_size(HashTable
*ht
)