2 Copyright © 1995-2008, 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>
18 extern STRPTR
Strdup(struct rambase
*rambase
, STRPTR string
);
19 extern void Strfree(struct rambase
*rambase
, STRPTR string
);
21 typedef struct _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
,
34 int (*compare
)(struct rambase
*rambase
,
37 void (*delete)(struct rambase
*rambase
,
41 ULONG i
; /* Loop variable */
42 HashTable
*ht
= AllocVec(sizeof(HashTable
), MEMF_ANY
);
51 ht
->array
= AllocVec(sizeof(struct List
)*size
, MEMF_ANY
);
53 if (ht
->array
== NULL
)
61 ht
->compare
= compare
;
64 for (i
= 0; i
< size
; i
++)
66 NewList(&ht
->array
[i
]);
73 /* TODO: Fix the double list thing, remove the (void *) hack */
74 void HashTable_delete(struct rambase
*rambase
, HashTable
*ht
)
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
);
93 void HashTable_insert(struct rambase
*rambase
, HashTable
*ht
, void *key
,
99 pos
= ht
->hash(rambase
, key
) % ht
->size
;
101 hn
= find(rambase
, ht
, key
, &ht
->array
[pos
]);
105 /* There was no previous request for this entity */
106 hn
= AllocVec(sizeof(HashNode
), MEMF_ANY
);
113 hn
->key
= Strdup(rambase
, key
);
121 NewList(&hn
->requests
);
122 AddHead(&ht
->array
[pos
], &hn
->node
);
125 AddHead(&hn
->requests
, &rr
->node
);
131 void HashTable_remove(struct rambase
*rambase
, HashTable
*ht
, void *key
)
135 struct Node
*tempNode
;
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)
146 ht
->delete(rambase
, hn
->key
, (void *)&hn
->requests
);
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)
171 struct List
*HashTable_find(struct rambase
*rambase
, HashTable
*ht
,
177 pos
= ht
->hash(rambase
, key
) % ht
->size
;
178 hn
= find(rambase
, ht
, key
, &ht
->array
[pos
]);
181 return &hn
->requests
;
187 inline ULONG
HashTable_size(HashTable
*ht
)