Make UEFI boot-platform build again
[haiku.git] / src / servers / app / HashTable.cpp
blob74b6ab90ad6eead6d670d7f4ed2f667e36864fea
1 /*
2 * Copyright 2005, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 */
10 #include "HashTable.h"
12 #include <new>
14 #include <stdlib.h>
15 //#include <stdarg.h>
16 #include <string.h>
18 using std::nothrow;
20 struct HashTable::entry {
21 entry* next;
22 Hashable* value;
26 HashTable::HashTable(bool owning, int32 capacity, float loadFactor)
28 fTable(NULL),
29 fCount(0),
30 fThreshold(0),
31 fOwning(owning)
33 if (capacity < 10)
34 capacity = 10;
35 if (loadFactor <= 0.3)
36 loadFactor = 0.3;
38 fLoadFactor = loadFactor;
39 fCapacity = capacity;
43 HashTable::~HashTable()
45 MakeEmpty(fOwning);
49 void
50 HashTable::MakeEmpty(bool deleteValues)
52 if (fTable == NULL)
53 return;
55 for (int32 index = fCapacity; --index >= 0;) {
56 struct entry *entry, *next;
58 for (entry = fTable[index]; entry != NULL; entry = next) {
59 next = entry->next;
61 if (deleteValues)
62 delete entry->value;
63 delete entry;
67 free(fTable);
68 fTable = NULL;
72 Hashable *
73 HashTable::GetValue(Hashable& key) const
75 struct entry* entry = _GetHashEntry(key);
77 return entry != NULL ? entry->value : NULL;
81 bool
82 HashTable::AddItem(Hashable *value)
84 struct entry *entry = _GetHashEntry(*value);
85 int32 hash = value->Hash();
86 int32 index;
88 // already in hash?
89 if (entry != NULL)
90 return true;
92 if (fCount >= fThreshold)
93 _Rehash();
95 index = hash % fCapacity;
97 entry = new (nothrow) HashTable::entry;
98 if (entry == NULL)
99 return false;
101 entry->value = value;
102 entry->next = fTable[index];
103 fTable[index] = entry;
104 fCount++;
105 return true;
109 Hashable *
110 HashTable::RemoveItem(Hashable& key)
112 struct entry* previous = NULL;
113 struct entry* entry;
114 uint32 hash;
115 int32 index;
117 if (fTable == NULL)
118 return NULL;
120 hash = key.Hash();
121 index = hash % fCapacity;
123 for (entry = fTable[index]; entry != NULL; entry = entry->next) {
124 if (entry->value->Hash() == hash && entry->value->CompareTo(key)) {
125 // found value in array
126 Hashable* value;
128 if (previous)
129 previous->next = entry->next;
130 else
131 fTable[index] = entry->next;
133 fCount--;
134 value = entry->value;
135 delete entry;
136 return value;
139 previous = entry;
141 return NULL;
145 bool
146 HashTable::_Rehash()
148 struct entry** newTable;
149 int32 oldCapacity = fCapacity;
150 int32 newCapacity, i;
152 if (fCount != 0)
153 newCapacity = oldCapacity * 2 + 1;
154 else
155 newCapacity = fCapacity;
157 newTable = (struct entry **)malloc(newCapacity * sizeof(struct entry *));
158 if (newTable == NULL)
159 return false;
161 memset(newTable, 0, newCapacity * sizeof(struct entry *));
163 if (fTable != NULL) {
164 // repopulate the entries into the new array
165 for (i = fCapacity; i-- > 0;) {
166 struct entry* entry;
167 struct entry* next;
169 for (entry = fTable[i]; entry != NULL; entry = next) {
170 next = entry->next;
172 int32 index = entry->value->Hash() % newCapacity;
173 entry->next = newTable[index];
174 newTable[index] = entry;
178 free(fTable);
181 fTable = newTable;
182 fCapacity = newCapacity;
183 fThreshold = int32(newCapacity * fLoadFactor);
185 return true;
189 struct HashTable::entry *
190 HashTable::_GetHashEntry(Hashable& key) const
192 struct entry* entry;
193 uint32 hash = key.Hash();
195 if (fTable == NULL)
196 return NULL;
198 for (entry = fTable[hash % fCapacity]; entry != NULL; entry = entry->next) {
199 if (entry->value->Hash() == hash && entry->value->CompareTo(key))
200 return entry;
203 return NULL;