OVR_Hash.h 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306
  1. /************************************************************************************
  2. PublicHeader: None
  3. Filename : OVR_Hash.h
  4. Content : Template hash-table/set implementation
  5. Created : September 19, 2012
  6. Notes :
  7. Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
  8. Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
  9. you may not use the Oculus VR Rift SDK except in compliance with the License,
  10. which is provided at the time of installation or download, or which
  11. otherwise accompanies this software in either electronic or hard copy form.
  12. You may obtain a copy of the License at
  13. http://www.oculusvr.com/licenses/LICENSE-3.2
  14. Unless required by applicable law or agreed to in writing, the Oculus VR SDK
  15. distributed under the License is distributed on an "AS IS" BASIS,
  16. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. See the License for the specific language governing permissions and
  18. limitations under the License.
  19. ************************************************************************************/
  20. #ifndef OVR_Hash_h
  21. #define OVR_Hash_h
  22. #include "OVR_ContainerAllocator.h"
  23. #include "OVR_Alg.h"
  24. // 'new' operator is redefined/used in this file.
  25. #undef new
  26. namespace OVR {
  27. //-----------------------------------------------------------------------------------
  28. // ***** Hash Table Implementation
  29. // HastSet and Hash.
  30. //
  31. // Hash table, linear probing, internal chaining. One interesting/nice thing
  32. // about this implementation is that the table itself is a flat chunk of memory
  33. // containing no pointers, only relative indices. If the key and value types
  34. // of the Hash contain no pointers, then the Hash can be serialized using raw IO.
  35. //
  36. // Never shrinks, unless you explicitly Clear() it. Expands on
  37. // demand, though. For best results, if you know roughly how big your
  38. // table will be, default it to that size when you create it.
  39. //
  40. // Key usability feature:
  41. //
  42. // 1. Allows node hash values to either be cached or not.
  43. //
  44. // 2. Allows for alternative keys with methods such as GetAlt(). Handy
  45. // if you need to search nodes by their components; no need to create
  46. // temporary nodes.
  47. //
  48. // *** Hash functors:
  49. //
  50. // IdentityHash - use when the key is already a good hash
  51. // HFixedSizeHash - general hash based on object's in-memory representation.
  52. // Hash is just the input value; can use this for integer-indexed hash tables.
  53. template<class C>
  54. class IdentityHash
  55. {
  56. public:
  57. size_t operator()(const C& data) const
  58. { return (size_t) data; }
  59. };
  60. // Computes a hash of an object's representation.
  61. template<class C>
  62. class FixedSizeHash
  63. {
  64. public:
  65. // Alternative: "sdbm" hash function, suggested at same web page
  66. // above, http::/www.cs.yorku.ca/~oz/hash.html
  67. // This is somewhat slower then Bernstein, but it works way better than the above
  68. // hash function for hashing large numbers of 32-bit ints.
  69. static OVR_FORCE_INLINE size_t SDBM_Hash(const void* data_in, size_t size, size_t seed = 5381)
  70. {
  71. const uint8_t* data = (const uint8_t*) data_in;
  72. size_t h = seed;
  73. while (size > 0)
  74. {
  75. --size;
  76. #ifndef __clang_analyzer__ // It mistakenly thinks data is garbage.
  77. h = (h << 16) + (h << 6) - h + (size_t)data[size];
  78. #endif
  79. }
  80. return h;
  81. }
  82. size_t operator()(const C& data) const
  83. {
  84. const unsigned char* p = (const unsigned char*) &data;
  85. const size_t size = sizeof(C);
  86. return SDBM_Hash(p, size);
  87. }
  88. };
  89. // *** HashsetEntry Entry types.
  90. // Compact hash table Entry type that re-computes hash keys during hash traversal.
  91. // Good to use if the hash function is cheap or the hash value is already cached in C.
  92. template<class C, class HashF>
  93. class HashsetEntry
  94. {
  95. public:
  96. // Internal chaining for collisions.
  97. intptr_t NextInChain;
  98. C Value;
  99. HashsetEntry()
  100. : NextInChain(-2) { }
  101. HashsetEntry(const HashsetEntry& e)
  102. : NextInChain(e.NextInChain), Value(e.Value) { }
  103. HashsetEntry(const C& key, intptr_t next)
  104. : NextInChain(next), Value(key) { }
  105. bool IsEmpty() const { return NextInChain == -2; }
  106. bool IsEndOfChain() const { return NextInChain == -1; }
  107. // Cached hash value access - can be optimized bu storing hash locally.
  108. // Mask value only needs to be used if SetCachedHash is not implemented.
  109. size_t GetCachedHash(size_t maskValue) const { return HashF()(Value) & maskValue; }
  110. void SetCachedHash(size_t) {}
  111. void Clear()
  112. {
  113. Value.~C(); // placement delete
  114. NextInChain = -2;
  115. }
  116. // Free is only used from dtor of hash; Clear is used during regular operations:
  117. // assignment, hash reallocations, value reassignments, so on.
  118. void Free() { Clear(); }
  119. };
  120. // Hash table Entry type that caches the Entry hash value for nodes, so that it
  121. // does not need to be re-computed during access.
  122. template<class C, class HashF>
  123. class HashsetCachedEntry
  124. {
  125. public:
  126. // Internal chaining for collisions.
  127. intptr_t NextInChain;
  128. size_t HashValue;
  129. C Value;
  130. HashsetCachedEntry()
  131. : NextInChain(-2) { }
  132. HashsetCachedEntry(const HashsetCachedEntry& e)
  133. : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { }
  134. HashsetCachedEntry(const C& key, intptr_t next)
  135. : NextInChain(next), Value(key) { }
  136. bool IsEmpty() const { return NextInChain == -2; }
  137. bool IsEndOfChain() const { return NextInChain == -1; }
  138. // Cached hash value access - can be optimized bu storing hash locally.
  139. // Mask value only needs to be used if SetCachedHash is not implemented.
  140. size_t GetCachedHash(size_t maskValue) const { OVR_UNUSED(maskValue); return HashValue; }
  141. void SetCachedHash(size_t hashValue) { HashValue = hashValue; }
  142. void Clear()
  143. {
  144. Value.~C();
  145. NextInChain = -2;
  146. }
  147. // Free is only used from dtor of hash; Clear is used during regular operations:
  148. // assignment, hash reallocations, value reassignments, so on.
  149. void Free() { Clear(); }
  150. };
  151. //-----------------------------------------------------------------------------------
  152. // *** HashSet implementation - relies on either cached or regular entries.
  153. //
  154. // Use: Entry = HashsetCachedEntry<C, HashF> if hashes are expensive to
  155. // compute and thus need caching in entries.
  156. // Entry = HashsetEntry<C, HashF> if hashes are already externally cached.
  157. //
  158. template<class C, class HashF = FixedSizeHash<C>,
  159. class AltHashF = HashF,
  160. class Allocator = ContainerAllocator<C>,
  161. class Entry = HashsetCachedEntry<C, HashF> >
  162. class HashSetBase
  163. {
  164. enum { HashMinSize = 8 };
  165. public:
  166. OVR_MEMORY_REDEFINE_NEW(HashSetBase)
  167. typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry> SelfType;
  168. HashSetBase() : pTable(NULL) { }
  169. HashSetBase(int sizeHint) : pTable(NULL) { SetCapacity(sizeHint); }
  170. HashSetBase(const SelfType& src) : pTable(NULL) { Assign(src); }
  171. ~HashSetBase()
  172. {
  173. if (pTable)
  174. {
  175. // Delete the entries.
  176. for (size_t i = 0, n = pTable->SizeMask; i <= n; i++)
  177. {
  178. Entry* e = &E(i);
  179. if (!e->IsEmpty())
  180. e->Free();
  181. }
  182. Allocator::Free(pTable);
  183. pTable = NULL;
  184. }
  185. }
  186. void Assign(const SelfType& src)
  187. {
  188. Clear();
  189. if (src.IsEmpty() == false)
  190. {
  191. SetCapacity(src.GetSize());
  192. for (ConstIterator it = src.Begin(); it != src.End(); ++it)
  193. {
  194. Add(*it);
  195. }
  196. }
  197. }
  198. // Remove all entries from the HashSet table.
  199. void Clear()
  200. {
  201. if (pTable)
  202. {
  203. // Delete the entries.
  204. for (size_t i = 0, n = pTable->SizeMask; i <= n; i++)
  205. {
  206. Entry* e = &E(i);
  207. if (!e->IsEmpty())
  208. e->Clear();
  209. }
  210. Allocator::Free(pTable);
  211. pTable = NULL;
  212. }
  213. }
  214. // Returns true if the HashSet is empty.
  215. bool IsEmpty() const
  216. {
  217. return pTable == NULL || pTable->EntryCount == 0;
  218. }
  219. // Set a new or existing value under the key, to the value.
  220. // Pass a different class of 'key' so that assignment reference object
  221. // can be passed instead of the actual object.
  222. template<class CRef>
  223. void Set(const CRef& key)
  224. {
  225. size_t hashValue = HashF()(key);
  226. intptr_t index = (intptr_t)-1;
  227. if (pTable != NULL)
  228. index = findIndexCore(key, hashValue & pTable->SizeMask);
  229. if (index >= 0)
  230. {
  231. E(index).Value = key;
  232. }
  233. else
  234. {
  235. // Entry under key doesn't exist.
  236. add(key, hashValue);
  237. }
  238. }
  239. template<class CRef>
  240. inline void Add(const CRef& key)
  241. {
  242. size_t hashValue = HashF()(key);
  243. add(key, hashValue);
  244. }
  245. // Remove by alternative key.
  246. template<class K>
  247. void RemoveAlt(const K& key)
  248. {
  249. if (pTable == NULL)
  250. return;
  251. size_t hashValue = AltHashF()(key);
  252. intptr_t index = hashValue & pTable->SizeMask;
  253. Entry* e = &E(index);
  254. // If empty node or occupied by collider, we have nothing to remove.
  255. if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != (size_t)index))
  256. return;
  257. // Save index
  258. intptr_t naturalIndex = index;
  259. intptr_t prevIndex = -1;
  260. while ((e->GetCachedHash(pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key))
  261. {
  262. // Keep looking through the chain.
  263. prevIndex = index;
  264. index = e->NextInChain;
  265. if (index == -1)
  266. return; // End of chain, item not found
  267. e = &E(index);
  268. }
  269. // Found it - our item is at index
  270. if (naturalIndex == index)
  271. {
  272. // If we have a follower, move it to us
  273. if (!e->IsEndOfChain())
  274. {
  275. Entry* enext = &E(e->NextInChain);
  276. e->Clear();
  277. new (e) Entry(*enext);
  278. // Point us to the follower's cell that will be cleared
  279. e = enext;
  280. }
  281. }
  282. else
  283. {
  284. // We are not at natural index, so deal with the prev items next index
  285. E(prevIndex).NextInChain = e->NextInChain;
  286. }
  287. // Clear us, of the follower cell that was moved.
  288. e->Clear();
  289. pTable->EntryCount --;
  290. // Should we check the size to condense hash? ...
  291. }
  292. // Remove by main key.
  293. template<class CRef>
  294. void Remove(const CRef& key)
  295. {
  296. RemoveAlt(key);
  297. }
  298. // Retrieve the pointer to a value under the given key.
  299. // - If there's no value under the key, then return NULL.
  300. // - If there is a value, return the pointer.
  301. template<class K>
  302. C* Get(const K& key)
  303. {
  304. intptr_t index = findIndex(key);
  305. if (index >= 0)
  306. return &E(index).Value;
  307. return 0;
  308. }
  309. template<class K>
  310. const C* Get(const K& key) const
  311. {
  312. intptr_t index = findIndex(key);
  313. if (index >= 0)
  314. return &E(index).Value;
  315. return 0;
  316. }
  317. // Alternative key versions of Get. Used by Hash.
  318. template<class K>
  319. const C* GetAlt(const K& key) const
  320. {
  321. intptr_t index = findIndexAlt(key);
  322. if (index >= 0)
  323. return &E(index).Value;
  324. return 0;
  325. }
  326. template<class K>
  327. C* GetAlt(const K& key)
  328. {
  329. intptr_t index = findIndexAlt(key);
  330. if (index >= 0)
  331. return &E(index).Value;
  332. return 0;
  333. }
  334. template<class K>
  335. bool GetAlt(const K& key, C* pval) const
  336. {
  337. intptr_t index = findIndexAlt(key);
  338. if (index >= 0)
  339. {
  340. if (pval)
  341. *pval = E(index).Value;
  342. return true;
  343. }
  344. return false;
  345. }
  346. size_t GetSize() const
  347. {
  348. return pTable == NULL ? 0 : (size_t)pTable->EntryCount;
  349. }
  350. int GetSizeI() const { return (int)GetSize(); }
  351. // Resize the HashSet table to fit one more Entry. Often this
  352. // doesn't involve any action.
  353. void CheckExpand()
  354. {
  355. if (pTable == NULL)
  356. {
  357. // Initial creation of table. Make a minimum-sized table.
  358. setRawCapacity(HashMinSize);
  359. }
  360. else if (pTable->EntryCount * 5 > (pTable->SizeMask + 1) * 4)
  361. {
  362. // pTable is more than 5/4 ths full. Expand.
  363. setRawCapacity((pTable->SizeMask + 1) * 2);
  364. }
  365. }
  366. // Hint the bucket count to >= n.
  367. void Resize(size_t n)
  368. {
  369. // Not really sure what this means in relation to
  370. // STLport's hash_map... they say they "increase the
  371. // bucket count to at least n" -- but does that mean
  372. // their real capacity after Resize(n) is more like
  373. // n*2 (since they do linked-list chaining within
  374. // buckets?).
  375. SetCapacity(n);
  376. }
  377. // Size the HashSet so that it can comfortably contain the given
  378. // number of elements. If the HashSet already contains more
  379. // elements than newSize, then this may be a no-op.
  380. void SetCapacity(size_t newSize)
  381. {
  382. size_t newRawSize = (newSize * 5) / 4;
  383. if (newRawSize <= GetSize())
  384. return;
  385. setRawCapacity(newRawSize);
  386. }
  387. // Disable inappropriate 'operator ->' warning on MSVC6.
  388. #ifdef OVR_CC_MSVC
  389. #if (OVR_CC_MSVC < 1300)
  390. # pragma warning(disable : 4284)
  391. #endif
  392. #endif
  393. // Iterator API, like STL.
  394. struct ConstIterator
  395. {
  396. const C& operator * () const
  397. {
  398. OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask);
  399. return pHash->E(Index).Value;
  400. }
  401. const C* operator -> () const
  402. {
  403. OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask);
  404. return &pHash->E(Index).Value;
  405. }
  406. void operator ++ ()
  407. {
  408. // Find next non-empty Entry.
  409. if (Index <= (intptr_t)pHash->pTable->SizeMask)
  410. {
  411. Index++;
  412. while ((size_t)Index <= pHash->pTable->SizeMask &&
  413. pHash->E(Index).IsEmpty())
  414. {
  415. Index++;
  416. }
  417. }
  418. }
  419. bool operator == (const ConstIterator& it) const
  420. {
  421. if (IsEnd() && it.IsEnd())
  422. {
  423. return true;
  424. }
  425. else
  426. {
  427. return (pHash == it.pHash) && (Index == it.Index);
  428. }
  429. }
  430. bool operator != (const ConstIterator& it) const
  431. {
  432. return ! (*this == it);
  433. }
  434. bool IsEnd() const
  435. {
  436. return (pHash == NULL) ||
  437. (pHash->pTable == NULL) ||
  438. (Index > (intptr_t)pHash->pTable->SizeMask);
  439. }
  440. ConstIterator()
  441. : pHash(NULL), Index(0)
  442. { }
  443. public:
  444. // Constructor was intentionally made public to allow create
  445. // iterator with arbitrary index.
  446. ConstIterator(const SelfType* h, intptr_t index)
  447. : pHash(h), Index(index)
  448. { }
  449. const SelfType* GetContainer() const
  450. {
  451. return pHash;
  452. }
  453. intptr_t GetIndex() const
  454. {
  455. return Index;
  456. }
  457. protected:
  458. friend class HashSetBase<C, HashF, AltHashF, Allocator, Entry>;
  459. const SelfType* pHash;
  460. intptr_t Index;
  461. };
  462. friend struct ConstIterator;
  463. // Non-const Iterator; Get most of it from ConstIterator.
  464. struct Iterator : public ConstIterator
  465. {
  466. // Allow non-const access to entries.
  467. C& operator*() const
  468. {
  469. OVR_ASSERT((ConstIterator::pHash) && ConstIterator::pHash->pTable && (ConstIterator::Index >= 0) && (ConstIterator::Index <= (intptr_t)ConstIterator::pHash->pTable->SizeMask));
  470. return const_cast<SelfType*>(ConstIterator::pHash)->E(ConstIterator::Index).Value;
  471. }
  472. C* operator->() const
  473. {
  474. return &(operator*());
  475. }
  476. Iterator()
  477. : ConstIterator(NULL, 0)
  478. { }
  479. // Removes current element from Hash
  480. void Remove()
  481. {
  482. RemoveAlt(operator*());
  483. }
  484. template <class K>
  485. void RemoveAlt(const K& key)
  486. {
  487. SelfType* phash = const_cast<SelfType*>(ConstIterator::pHash);
  488. //Entry* ee = &phash->E(ConstIterator::Index);
  489. //const C& key = ee->Value;
  490. size_t hashValue = AltHashF()(key);
  491. intptr_t index = hashValue & phash->pTable->SizeMask;
  492. Entry* e = &phash->E(index);
  493. // If empty node or occupied by collider, we have nothing to remove.
  494. if (e->IsEmpty() || (e->GetCachedHash(phash->pTable->SizeMask) != (size_t)index))
  495. return;
  496. // Save index
  497. intptr_t naturalIndex = index;
  498. intptr_t prevIndex = -1;
  499. while ((e->GetCachedHash(phash->pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key))
  500. {
  501. // Keep looking through the chain.
  502. prevIndex = index;
  503. index = e->NextInChain;
  504. if (index == -1)
  505. return; // End of chain, item not found
  506. e = &phash->E(index);
  507. }
  508. if (index == (intptr_t)ConstIterator::Index)
  509. {
  510. // Found it - our item is at index
  511. if (naturalIndex == index)
  512. {
  513. // If we have a follower, move it to us
  514. if (!e->IsEndOfChain())
  515. {
  516. Entry* enext = &phash->E(e->NextInChain);
  517. e->Clear();
  518. new (e) Entry(*enext);
  519. // Point us to the follower's cell that will be cleared
  520. e = enext;
  521. --ConstIterator::Index;
  522. }
  523. }
  524. else
  525. {
  526. // We are not at natural index, so deal with the prev items next index
  527. phash->E(prevIndex).NextInChain = e->NextInChain;
  528. }
  529. // Clear us, of the follower cell that was moved.
  530. e->Clear();
  531. phash->pTable->EntryCount --;
  532. }
  533. else
  534. OVR_ASSERT(0); //?
  535. }
  536. private:
  537. friend class HashSetBase<C, HashF, AltHashF, Allocator, Entry>;
  538. Iterator(SelfType* h, intptr_t i0)
  539. : ConstIterator(h, i0)
  540. { }
  541. };
  542. friend struct Iterator;
  543. Iterator Begin()
  544. {
  545. if (pTable == 0)
  546. return Iterator(NULL, 0);
  547. // Scan till we hit the First valid Entry.
  548. size_t i0 = 0;
  549. while (i0 <= pTable->SizeMask && E(i0).IsEmpty())
  550. {
  551. i0++;
  552. }
  553. return Iterator(this, i0);
  554. }
  555. Iterator End() { return Iterator(NULL, 0); }
  556. ConstIterator Begin() const { return const_cast<SelfType*>(this)->Begin(); }
  557. ConstIterator End() const { return const_cast<SelfType*>(this)->End(); }
  558. template<class K>
  559. Iterator Find(const K& key)
  560. {
  561. intptr_t index = findIndex(key);
  562. if (index >= 0)
  563. return Iterator(this, index);
  564. return Iterator(NULL, 0);
  565. }
  566. template<class K>
  567. Iterator FindAlt(const K& key)
  568. {
  569. intptr_t index = findIndexAlt(key);
  570. if (index >= 0)
  571. return Iterator(this, index);
  572. return Iterator(NULL, 0);
  573. }
  574. template<class K>
  575. ConstIterator Find(const K& key) const { return const_cast<SelfType*>(this)->Find(key); }
  576. template<class K>
  577. ConstIterator FindAlt(const K& key) const { return const_cast<SelfType*>(this)->FindAlt(key); }
  578. private:
  579. // Find the index of the matching Entry. If no match, then return -1.
  580. template<class K>
  581. intptr_t findIndex(const K& key) const
  582. {
  583. if (pTable == NULL)
  584. return -1;
  585. size_t hashValue = HashF()(key) & pTable->SizeMask;
  586. return findIndexCore(key, hashValue);
  587. }
  588. template<class K>
  589. intptr_t findIndexAlt(const K& key) const
  590. {
  591. if (pTable == NULL)
  592. return -1;
  593. size_t hashValue = AltHashF()(key) & pTable->SizeMask;
  594. return findIndexCore(key, hashValue);
  595. }
  596. // Find the index of the matching Entry. If no match, then return -1.
  597. template<class K>
  598. intptr_t findIndexCore(const K& key, size_t hashValue) const
  599. {
  600. // Table must exist.
  601. OVR_ASSERT(pTable != 0);
  602. // Hash key must be 'and-ed' by the caller.
  603. OVR_ASSERT((hashValue & ~pTable->SizeMask) == 0);
  604. size_t index = hashValue;
  605. const Entry* e = &E(index);
  606. // If empty or occupied by a collider, not found.
  607. if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != index))
  608. return -1;
  609. while(1)
  610. {
  611. OVR_ASSERT(e->GetCachedHash(pTable->SizeMask) == hashValue);
  612. if (e->GetCachedHash(pTable->SizeMask) == hashValue && e->Value == key)
  613. {
  614. // Found it.
  615. return index;
  616. }
  617. // Values can not be equal at this point.
  618. // That would mean that the hash key for the same value differs.
  619. OVR_ASSERT(!(e->Value == key));
  620. // Keep looking through the chain.
  621. index = e->NextInChain;
  622. if (index == (size_t)-1)
  623. break; // end of chain
  624. e = &E(index);
  625. OVR_ASSERT(!e->IsEmpty());
  626. }
  627. return -1;
  628. }
  629. // Add a new value to the HashSet table, under the specified key.
  630. template<class CRef>
  631. void add(const CRef& key, size_t hashValue)
  632. {
  633. CheckExpand();
  634. hashValue &= pTable->SizeMask;
  635. pTable->EntryCount++;
  636. intptr_t index = hashValue;
  637. Entry* naturalEntry = &(E(index));
  638. if (naturalEntry->IsEmpty())
  639. {
  640. // Put the new Entry in.
  641. new (naturalEntry) Entry(key, -1);
  642. }
  643. else
  644. {
  645. // Find a blank spot.
  646. intptr_t blankIndex = index;
  647. do {
  648. blankIndex = (blankIndex + 1) & pTable->SizeMask;
  649. } while(!E(blankIndex).IsEmpty());
  650. Entry* blankEntry = &E(blankIndex);
  651. if (naturalEntry->GetCachedHash(pTable->SizeMask) == (size_t)index)
  652. {
  653. // Collision. Link into this chain.
  654. // Move existing list head.
  655. new (blankEntry) Entry(*naturalEntry); // placement new, copy ctor
  656. // Put the new info in the natural Entry.
  657. naturalEntry->Value = key;
  658. naturalEntry->NextInChain = blankIndex;
  659. }
  660. else
  661. {
  662. // Existing Entry does not naturally
  663. // belong in this slot. Existing
  664. // Entry must be moved.
  665. // Find natural location of collided element (i.e. root of chain)
  666. intptr_t collidedIndex = naturalEntry->GetCachedHash(pTable->SizeMask);
  667. OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask);
  668. for (;;)
  669. {
  670. Entry* e = &E(collidedIndex);
  671. if (e->NextInChain == index)
  672. {
  673. // Here's where we need to splice.
  674. new (blankEntry) Entry(*naturalEntry);
  675. e->NextInChain = blankIndex;
  676. break;
  677. }
  678. collidedIndex = e->NextInChain;
  679. OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask);
  680. }
  681. // Put the new data in the natural Entry.
  682. naturalEntry->Value = key;
  683. naturalEntry->NextInChain = -1;
  684. }
  685. }
  686. // Record hash value: has effect only if cached node is used.
  687. naturalEntry->SetCachedHash(hashValue);
  688. }
  689. // Index access helpers.
  690. Entry& E(size_t index)
  691. {
  692. // Must have pTable and access needs to be within bounds.
  693. OVR_ASSERT(index <= pTable->SizeMask);
  694. return *(((Entry*) (pTable + 1)) + index);
  695. }
  696. const Entry& E(size_t index) const
  697. {
  698. OVR_ASSERT(index <= pTable->SizeMask);
  699. return *(((Entry*) (pTable + 1)) + index);
  700. }
  701. // Resize the HashSet table to the given size (Rehash the
  702. // contents of the current table). The arg is the number of
  703. // HashSet table entries, not the number of elements we should
  704. // actually contain (which will be less than this).
  705. void setRawCapacity(size_t newSize)
  706. {
  707. if (newSize == 0)
  708. {
  709. // Special case.
  710. Clear();
  711. return;
  712. }
  713. // Minimum size; don't incur rehashing cost when expanding
  714. // very small tables. Not that we perform this check before
  715. // 'log2f' call to avoid fp exception with newSize == 1.
  716. if (newSize < HashMinSize)
  717. newSize = HashMinSize;
  718. else
  719. {
  720. // Force newSize to be a power of two.
  721. int bits = Alg::UpperBit(newSize-1) + 1; // Chop( Log2f((float)(newSize-1)) + 1);
  722. OVR_ASSERT((size_t(1) << bits) >= newSize);
  723. newSize = size_t(1) << bits;
  724. }
  725. SelfType newHash;
  726. newHash.pTable = (TableType*)
  727. Allocator::Alloc(
  728. sizeof(TableType) + sizeof(Entry) * newSize);
  729. // Need to do something on alloc failure!
  730. OVR_ASSERT(newHash.pTable);
  731. newHash.pTable->EntryCount = 0;
  732. newHash.pTable->SizeMask = newSize - 1;
  733. size_t i, n;
  734. // Mark all entries as empty.
  735. for (i = 0; i < newSize; i++)
  736. newHash.E(i).NextInChain = -2;
  737. // Copy stuff to newHash
  738. if (pTable)
  739. {
  740. for (i = 0, n = pTable->SizeMask; i <= n; i++)
  741. {
  742. Entry* e = &E(i);
  743. if (e->IsEmpty() == false)
  744. {
  745. // Insert old Entry into new HashSet.
  746. newHash.Add(e->Value);
  747. // placement delete of old element
  748. e->Clear();
  749. }
  750. }
  751. // Delete our old data buffer.
  752. Allocator::Free(pTable);
  753. }
  754. // Steal newHash's data.
  755. pTable = newHash.pTable;
  756. newHash.pTable = NULL;
  757. }
  758. struct TableType
  759. {
  760. size_t EntryCount;
  761. size_t SizeMask;
  762. // Entry array follows this structure
  763. // in memory.
  764. };
  765. TableType* pTable;
  766. };
  767. //-----------------------------------------------------------------------------------
  768. template<class C, class HashF = FixedSizeHash<C>,
  769. class AltHashF = HashF,
  770. class Allocator = ContainerAllocator<C>,
  771. class Entry = HashsetCachedEntry<C, HashF> >
  772. class HashSet : public HashSetBase<C, HashF, AltHashF, Allocator, Entry>
  773. {
  774. public:
  775. typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry> BaseType;
  776. typedef HashSet<C, HashF, AltHashF, Allocator, Entry> SelfType;
  777. HashSet() { }
  778. HashSet(int sizeHint) : BaseType(sizeHint) { }
  779. HashSet(const SelfType& src) : BaseType(src) { }
  780. ~HashSet() { }
  781. void operator = (const SelfType& src) { BaseType::Assign(src); }
  782. // Set a new or existing value under the key, to the value.
  783. // Pass a different class of 'key' so that assignment reference object
  784. // can be passed instead of the actual object.
  785. template<class CRef>
  786. void Set(const CRef& key)
  787. {
  788. BaseType::Set(key);
  789. }
  790. template<class CRef>
  791. inline void Add(const CRef& key)
  792. {
  793. BaseType::Add(key);
  794. }
  795. // Hint the bucket count to >= n.
  796. void Resize(size_t n)
  797. {
  798. BaseType::SetCapacity(n);
  799. }
  800. // Size the HashSet so that it can comfortably contain the given
  801. // number of elements. If the HashSet already contains more
  802. // elements than newSize, then this may be a no-op.
  803. void SetCapacity(size_t newSize)
  804. {
  805. BaseType::SetCapacity(newSize);
  806. }
  807. };
  808. // HashSet with uncached hash code; declared for convenience.
  809. template<class C, class HashF = FixedSizeHash<C>,
  810. class AltHashF = HashF,
  811. class Allocator = ContainerAllocator<C> >
  812. class HashSetUncached : public HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF> >
  813. {
  814. public:
  815. typedef HashSetUncached<C, HashF, AltHashF, Allocator> SelfType;
  816. typedef HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF> > BaseType;
  817. // Delegated constructors.
  818. HashSetUncached() { }
  819. HashSetUncached(int sizeHint) : BaseType(sizeHint) { }
  820. HashSetUncached(const SelfType& src) : BaseType(src) { }
  821. ~HashSetUncached() { }
  822. void operator = (const SelfType& src)
  823. {
  824. BaseType::operator = (src);
  825. }
  826. };
  827. //-----------------------------------------------------------------------------------
  828. // ***** Hash hash table implementation
  829. // Node for Hash - necessary so that Hash can delegate its implementation
  830. // to HashSet.
  831. template<class C, class U, class HashF>
  832. struct HashNode
  833. {
  834. typedef HashNode<C, U, HashF> SelfType;
  835. typedef C FirstType;
  836. typedef U SecondType;
  837. C First;
  838. U Second;
  839. // NodeRef is used to allow passing of elements into HashSet
  840. // without using a temporary object.
  841. struct NodeRef
  842. {
  843. const C* pFirst;
  844. const U* pSecond;
  845. NodeRef(const C& f, const U& s) : pFirst(&f), pSecond(&s) { }
  846. NodeRef(const NodeRef& src) : pFirst(src.pFirst), pSecond(src.pSecond) { }
  847. // Enable computation of ghash_node_hashf.
  848. inline size_t GetHash() const { return HashF()(*pFirst); }
  849. // Necessary conversion to allow HashNode::operator == to work.
  850. operator const C& () const { return *pFirst; }
  851. };
  852. // Note: No default constructor is necessary.
  853. HashNode(const HashNode& src) : First(src.First), Second(src.Second) { }
  854. HashNode(const NodeRef& src) : First(*src.pFirst), Second(*src.pSecond) { }
  855. void operator = (const NodeRef& src) { First = *src.pFirst; Second = *src.pSecond; }
  856. template<class K>
  857. bool operator == (const K& src) const { return (First == src); }
  858. template<class K>
  859. static size_t CalcHash(const K& data) { return HashF()(data); }
  860. inline size_t GetHash() const { return HashF()(First); }
  861. // Hash functors used with this node. A separate functor is used for alternative
  862. // key lookup so that it does not need to access the '.First' element.
  863. struct NodeHashF
  864. {
  865. template<class K>
  866. size_t operator()(const K& data) const { return data.GetHash(); }
  867. };
  868. struct NodeAltHashF
  869. {
  870. template<class K>
  871. size_t operator()(const K& data) const { return HashNode<C,U,HashF>::CalcHash(data); }
  872. };
  873. };
  874. // **** Extra hashset_entry types to allow NodeRef construction.
  875. // The big difference between the below types and the ones used in hash_set is that
  876. // these allow initializing the node with 'typename C::NodeRef& keyRef', which
  877. // is critical to avoid temporary node allocation on stack when using placement new.
  878. // Compact hash table Entry type that re-computes hash keys during hash traversal.
  879. // Good to use if the hash function is cheap or the hash value is already cached in C.
  880. template<class C, class HashF>
  881. class HashsetNodeEntry
  882. {
  883. public:
  884. // Internal chaining for collisions.
  885. intptr_t NextInChain;
  886. C Value;
  887. HashsetNodeEntry()
  888. : NextInChain(-2) { }
  889. HashsetNodeEntry(const HashsetNodeEntry& e)
  890. : NextInChain(e.NextInChain), Value(e.Value) { }
  891. HashsetNodeEntry(const C& key, intptr_t next)
  892. : NextInChain(next), Value(key) { }
  893. HashsetNodeEntry(const typename C::NodeRef& keyRef, intptr_t next)
  894. : NextInChain(next), Value(keyRef) { }
  895. bool IsEmpty() const { return NextInChain == -2; }
  896. bool IsEndOfChain() const { return NextInChain == -1; }
  897. size_t GetCachedHash(size_t maskValue) const { return HashF()(Value) & maskValue; }
  898. void SetCachedHash(size_t hashValue) { OVR_UNUSED(hashValue); }
  899. void Clear()
  900. {
  901. Value.~C(); // placement delete
  902. NextInChain = -2;
  903. }
  904. // Free is only used from dtor of hash; Clear is used during regular operations:
  905. // assignment, hash reallocations, value reassignments, so on.
  906. void Free() { Clear(); }
  907. };
  908. // Hash table Entry type that caches the Entry hash value for nodes, so that it
  909. // does not need to be re-computed during access.
  910. template<class C, class HashF>
  911. class HashsetCachedNodeEntry
  912. {
  913. public:
  914. // Internal chaining for collisions.
  915. intptr_t NextInChain;
  916. size_t HashValue;
  917. C Value;
  918. HashsetCachedNodeEntry()
  919. : NextInChain(-2) { }
  920. HashsetCachedNodeEntry(const HashsetCachedNodeEntry& e)
  921. : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { }
  922. HashsetCachedNodeEntry(const C& key, intptr_t next)
  923. : NextInChain(next), Value(key) { }
  924. HashsetCachedNodeEntry(const typename C::NodeRef& keyRef, intptr_t next)
  925. : NextInChain(next), Value(keyRef) { }
  926. bool IsEmpty() const { return NextInChain == -2; }
  927. bool IsEndOfChain() const { return NextInChain == -1; }
  928. size_t GetCachedHash(size_t maskValue) const { OVR_UNUSED(maskValue); return HashValue; }
  929. void SetCachedHash(size_t hashValue) { HashValue = hashValue; }
  930. void Clear()
  931. {
  932. Value.~C();
  933. NextInChain = -2;
  934. }
  935. // Free is only used from dtor of hash; Clear is used during regular operations:
  936. // assignment, hash reallocations, value reassignments, so on.
  937. void Free() { Clear(); }
  938. };
  939. //-----------------------------------------------------------------------------------
  940. template<class C, class U,
  941. class HashF = FixedSizeHash<C>,
  942. class Allocator = ContainerAllocator<C>,
  943. class HashNode = OVR::HashNode<C,U,HashF>,
  944. class Entry = HashsetCachedNodeEntry<HashNode, typename HashNode::NodeHashF>,
  945. class Container = HashSet<HashNode, typename HashNode::NodeHashF,
  946. typename HashNode::NodeAltHashF, Allocator,
  947. Entry> >
  948. class Hash
  949. {
  950. public:
  951. OVR_MEMORY_REDEFINE_NEW(Hash)
  952. // Types used for hash_set.
  953. typedef U ValueType;
  954. typedef Hash<C, U, HashF, Allocator, HashNode, Entry, Container> SelfType;
  955. // Actual hash table itself, implemented as hash_set.
  956. Container mHash;
  957. public:
  958. Hash() { }
  959. Hash(int sizeHint) : mHash(sizeHint) { }
  960. Hash(const SelfType& src) : mHash(src.mHash) { }
  961. ~Hash() { }
  962. void operator = (const SelfType& src) { mHash = src.mHash; }
  963. // Remove all entries from the Hash table.
  964. inline void Clear() { mHash.Clear(); }
  965. // Returns true if the Hash is empty.
  966. inline bool IsEmpty() const { return mHash.IsEmpty(); }
  967. // Access (set).
  968. inline void Set(const C& key, const U& value)
  969. {
  970. typename HashNode::NodeRef e(key, value);
  971. mHash.Set(e);
  972. }
  973. inline void Add(const C& key, const U& value)
  974. {
  975. typename HashNode::NodeRef e(key, value);
  976. mHash.Add(e);
  977. }
  978. // Removes an element by clearing its Entry.
  979. inline void Remove(const C& key)
  980. {
  981. mHash.RemoveAlt(key);
  982. }
  983. template<class K>
  984. inline void RemoveAlt(const K& key)
  985. {
  986. mHash.RemoveAlt(key);
  987. }
  988. // Retrieve the value under the given key.
  989. // - If there's no value under the key, then return false and leave *pvalue alone.
  990. // - If there is a value, return true, and Set *Pvalue to the Entry's value.
  991. // - If value == NULL, return true or false according to the presence of the key.
  992. bool Get(const C& key, U* pvalue) const
  993. {
  994. const HashNode* p = mHash.GetAlt(key);
  995. if (p)
  996. {
  997. if (pvalue)
  998. *pvalue = p->Second;
  999. return true;
  1000. }
  1001. return false;
  1002. }
  1003. template<class K>
  1004. bool GetAlt(const K& key, U* pvalue) const
  1005. {
  1006. const HashNode* p = mHash.GetAlt(key);
  1007. if (p)
  1008. {
  1009. if (pvalue)
  1010. *pvalue = p->Second;
  1011. return true;
  1012. }
  1013. return false;
  1014. }
  1015. // Retrieve the pointer to a value under the given key.
  1016. // - If there's no value under the key, then return NULL.
  1017. // - If there is a value, return the pointer.
  1018. inline U* Get(const C& key)
  1019. {
  1020. HashNode* p = mHash.GetAlt(key);
  1021. return p ? &p->Second : 0;
  1022. }
  1023. inline const U* Get(const C& key) const
  1024. {
  1025. const HashNode* p = mHash.GetAlt(key);
  1026. return p ? &p->Second : 0;
  1027. }
  1028. template<class K>
  1029. inline U* GetAlt(const K& key)
  1030. {
  1031. HashNode* p = mHash.GetAlt(key);
  1032. return p ? &p->Second : 0;
  1033. }
  1034. template<class K>
  1035. inline const U* GetAlt(const K& key) const
  1036. {
  1037. const HashNode* p = mHash.GetAlt(key);
  1038. return p ? &p->Second : 0;
  1039. }
  1040. // Sizing methods - delegate to Hash.
  1041. inline size_t GetSize() const { return mHash.GetSize(); }
  1042. inline int GetSizeI() const { return (int)GetSize(); }
  1043. inline void Resize(size_t n) { mHash.Resize(n); }
  1044. inline void SetCapacity(size_t newSize) { mHash.SetCapacity(newSize); }
  1045. // Iterator API, like STL.
  1046. typedef typename Container::ConstIterator ConstIterator;
  1047. typedef typename Container::Iterator Iterator;
  1048. inline Iterator Begin() { return mHash.Begin(); }
  1049. inline Iterator End() { return mHash.End(); }
  1050. inline ConstIterator Begin() const { return mHash.Begin(); }
  1051. inline ConstIterator End() const { return mHash.End(); }
  1052. Iterator Find(const C& key) { return mHash.FindAlt(key); }
  1053. ConstIterator Find(const C& key) const { return mHash.FindAlt(key); }
  1054. template<class K>
  1055. Iterator FindAlt(const K& key) { return mHash.FindAlt(key); }
  1056. template<class K>
  1057. ConstIterator FindAlt(const K& key) const { return mHash.FindAlt(key); }
  1058. };
  1059. // Hash with uncached hash code; declared for convenience.
  1060. template<class C, class U, class HashF = FixedSizeHash<C>, class Allocator = ContainerAllocator<C> >
  1061. class HashUncached
  1062. : public Hash<C, U, HashF, Allocator, HashNode<C,U,HashF>,
  1063. HashsetNodeEntry<HashNode<C,U,HashF>, typename HashNode<C,U,HashF>::NodeHashF> >
  1064. {
  1065. public:
  1066. typedef HashUncached<C, U, HashF, Allocator> SelfType;
  1067. typedef Hash<C, U, HashF, Allocator, HashNode<C,U,HashF>,
  1068. HashsetNodeEntry<HashNode<C,U,HashF>,
  1069. typename HashNode<C,U,HashF>::NodeHashF> > BaseType;
  1070. // Delegated constructors.
  1071. HashUncached() { }
  1072. HashUncached(int sizeHint) : BaseType(sizeHint) { }
  1073. HashUncached(const SelfType& src) : BaseType(src) { }
  1074. ~HashUncached() { }
  1075. void operator = (const SelfType& src) { BaseType::operator = (src); }
  1076. };
  1077. // And identity hash in which keys serve as hash value. Can be uncached,
  1078. // since hash computation is assumed cheap.
  1079. template<class C, class U, class Allocator = ContainerAllocator<C>, class HashF = IdentityHash<C> >
  1080. class HashIdentity
  1081. : public HashUncached<C, U, HashF, Allocator>
  1082. {
  1083. public:
  1084. typedef HashIdentity<C, U, Allocator, HashF> SelfType;
  1085. typedef HashUncached<C, U, HashF, Allocator> BaseType;
  1086. // Delegated constructors.
  1087. HashIdentity() { }
  1088. HashIdentity(int sizeHint) : BaseType(sizeHint) { }
  1089. HashIdentity(const SelfType& src) : BaseType(src) { }
  1090. ~HashIdentity() { }
  1091. void operator = (const SelfType& src) { BaseType::operator = (src); }
  1092. };
  1093. } // OVR
  1094. #ifdef OVR_DEFINE_NEW
  1095. #define new OVR_DEFINE_NEW
  1096. #endif
  1097. #endif