Make UEFI boot-platform build again
[haiku.git] / headers / private / shared / HashSet.h
blob9a102d1f02503d2653d4cd32848d6dac22d49a22
1 // HashSet.h
2 //
3 // Copyright (c) 2004, Ingo Weinhold (bonefish@cs.tu-berlin.de)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 // DEALINGS IN THE SOFTWARE.
23 // Except as contained in this notice, the name of a copyright holder shall
24 // not be used in advertising or otherwise to promote the sale, use or other
25 // dealings in this Software without prior written authorization of the
26 // copyright holder.
28 #ifndef HASH_SET_H
29 #define HASH_SET_H
31 #include <Locker.h>
33 #include "AutoLocker.h"
34 #include "OpenHashTable.h"
37 namespace BPrivate {
39 // HashSetElement
40 template<typename Key>
41 class HashSetElement : public OpenHashElement {
42 private:
43 typedef HashSetElement<Key> Element;
44 public:
46 HashSetElement() : OpenHashElement(), fKey()
48 fNext = -1;
51 inline uint32 Hash() const
53 return fKey.GetHashCode();
56 inline bool operator==(const OpenHashElement &_element) const
58 const Element &element = static_cast<const Element&>(_element);
59 return (fKey == element.fKey);
62 inline void Adopt(Element &element)
64 fKey = element.fKey;
67 Key fKey;
70 // HashSet
71 template<typename Key>
72 class HashSet {
73 public:
74 class Iterator {
75 private:
76 typedef HashSetElement<Key> Element;
77 public:
78 Iterator(const Iterator& other)
79 : fSet(other.fSet),
80 fIndex(other.fIndex),
81 fElement(other.fElement),
82 fLastElement(other.fElement)
86 bool HasNext() const
88 return fElement;
91 Key Next()
93 if (!fElement)
94 return Key();
95 Key result(fElement->fKey);
96 _FindNext();
97 return result;
100 bool Remove()
102 if (!fLastElement)
103 return false;
104 fSet->fTable.Remove(fLastElement);
105 fLastElement = NULL;
106 return true;
109 Iterator& operator=(const Iterator& other)
111 fSet = other.fSet;
112 fIndex = other.fIndex;
113 fElement = other.fElement;
114 fLastElement = other.fLastElement;
115 return *this;
118 private:
119 Iterator(HashSet<Key>* map)
120 : fSet(map),
121 fIndex(0),
122 fElement(NULL),
123 fLastElement(NULL)
125 // find first
126 _FindNext();
129 void _FindNext()
131 fLastElement = fElement;
132 if (fElement && fElement->fNext >= 0) {
133 fElement = fSet->fTable.ElementAt(fElement->fNext);
134 return;
136 fElement = NULL;
137 int32 arraySize = fSet->fTable.ArraySize();
138 for (; !fElement && fIndex < arraySize; fIndex++)
139 fElement = fSet->fTable.FindFirst(fIndex);
142 private:
143 friend class HashSet<Key>;
145 HashSet<Key>* fSet;
146 int32 fIndex;
147 Element* fElement;
148 Element* fLastElement;
151 HashSet();
152 ~HashSet();
154 status_t InitCheck() const;
156 status_t Add(const Key& key);
157 bool Remove(const Key& key);
158 void Clear();
159 bool Contains(const Key& key) const;
161 int32 Size() const;
162 bool IsEmpty() const { return Size() == 0; }
164 Iterator GetIterator();
166 protected:
167 typedef HashSetElement<Key> Element;
168 friend class Iterator;
170 private:
171 Element *_FindElement(const Key& key) const;
173 protected:
174 OpenHashElementArray<Element> fElementArray;
175 OpenHashTable<Element, OpenHashElementArray<Element> > fTable;
178 // SynchronizedHashSet
179 template<typename Key>
180 class SynchronizedHashSet : public BLocker {
181 public:
182 typedef typename HashSet<Key>::Iterator Iterator;
184 SynchronizedHashSet() : BLocker("synchronized hash set") {}
185 ~SynchronizedHashSet() { Lock(); }
187 status_t InitCheck() const
189 return fSet.InitCheck();
192 status_t Add(const Key& key)
194 MapLocker locker(this);
195 if (!locker.IsLocked())
196 return B_ERROR;
197 return fSet.Add(key);
200 bool Remove(const Key& key)
202 MapLocker locker(this);
203 if (!locker.IsLocked())
204 return false;
205 return fSet.Remove(key);
208 bool Contains(const Key& key) const
210 const BLocker* lock = this;
211 MapLocker locker(const_cast<BLocker*>(lock));
212 if (!locker.IsLocked())
213 return false;
214 return fSet.Contains(key);
217 int32 Size() const
219 const BLocker* lock = this;
220 MapLocker locker(const_cast<BLocker*>(lock));
221 return fSet.Size();
224 Iterator GetIterator()
226 return fSet.GetIterator();
229 // for debugging only
230 const HashSet<Key>& GetUnsynchronizedSet() const { return fSet; }
231 HashSet<Key>& GetUnsynchronizedSet() { return fSet; }
233 protected:
234 typedef AutoLocker<BLocker> MapLocker;
236 HashSet<Key> fSet;
239 // HashSet
241 // constructor
242 template<typename Key>
243 HashSet<Key>::HashSet()
244 : fElementArray(1000),
245 fTable(1000, &fElementArray)
249 // destructor
250 template<typename Key>
251 HashSet<Key>::~HashSet()
255 // InitCheck
256 template<typename Key>
257 status_t
258 HashSet<Key>::InitCheck() const
260 return (fTable.InitCheck() && fElementArray.InitCheck()
261 ? B_OK : B_NO_MEMORY);
264 // Add
265 template<typename Key>
266 status_t
267 HashSet<Key>::Add(const Key& key)
269 if (Contains(key))
270 return B_OK;
271 Element* element = fTable.Add(key.GetHashCode());
272 if (!element)
273 return B_NO_MEMORY;
274 element->fKey = key;
275 return B_OK;
278 // Remove
279 template<typename Key>
280 bool
281 HashSet<Key>::Remove(const Key& key)
283 if (Element* element = _FindElement(key)) {
284 fTable.Remove(element);
285 return true;
287 return false;
290 // Clear
291 template<typename Key>
292 void
293 HashSet<Key>::Clear()
295 fTable.RemoveAll();
298 // Contains
299 template<typename Key>
300 bool
301 HashSet<Key>::Contains(const Key& key) const
303 return _FindElement(key);
306 // Size
307 template<typename Key>
308 int32
309 HashSet<Key>::Size() const
311 return fTable.CountElements();
314 // GetIterator
315 template<typename Key>
316 typename HashSet<Key>::Iterator
317 HashSet<Key>::GetIterator()
319 return Iterator(this);
322 // _FindElement
323 template<typename Key>
324 HashSetElement<Key> *
325 HashSet<Key>::_FindElement(const Key& key) const
327 Element* element = fTable.FindFirst(key.GetHashCode());
328 while (element && element->fKey != key) {
329 if (element->fNext >= 0)
330 element = fTable.ElementAt(element->fNext);
331 else
332 element = NULL;
334 return element;
337 } // namespace BPrivate
339 using BPrivate::HashSet;
340 using BPrivate::SynchronizedHashSet;
342 #endif // HASH_SET_H