tDictionary.h 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _TDICTIONARY_H_
  23. #define _TDICTIONARY_H_
  24. #ifndef _STRINGFUNCTIONS_H_
  25. #include "core/strings/stringFunctions.h"
  26. #endif
  27. #ifndef _HASHFUNCTION_H_
  28. #include "core/util/hashFunction.h"
  29. #endif
  30. #ifndef _TORQUE_STRING_H_
  31. #include "core/util/str.h"
  32. #endif
  33. #ifndef _DATACHUNKER_H_
  34. #include "core/dataChunker.h"
  35. #endif
  36. // TODO: Maybe move these into a more general Tuple class?
  37. template<class A, class B>
  38. struct CompoundKey
  39. {
  40. A key1;
  41. B key2;
  42. CompoundKey() {};
  43. CompoundKey(const A & a, const B & b) { key1 = a; key2 = b; };
  44. bool operator==(const CompoundKey & compound) const { return key1==compound.key1 && key2==compound.key2; }
  45. };
  46. template<class A, class B, class C>
  47. struct CompoundKey3
  48. {
  49. A key1;
  50. B key2;
  51. C key3;
  52. CompoundKey3() {};
  53. CompoundKey3(const A & a, const B & b, const C & c) { key1 = a; key2 = b; key3 = c;};
  54. bool operator==(const CompoundKey3 & compound) const { return key1==compound.key1 && key2==compound.key2 && key3==compound.key3; }
  55. };
  56. template<class A, class B, class C, class D>
  57. struct CompoundKey4
  58. {
  59. A key1;
  60. B key2;
  61. C key3;
  62. D key4;
  63. CompoundKey4() {};
  64. CompoundKey4(const A& a, const B& b, const C& c, const D& d) { key1 = a; key2 = b; key3 = c; key4 = d;};
  65. bool operator==(const CompoundKey4& compound) const { return key1 == compound.key1 && key2 == compound.key2 && key3 == compound.key3 && key4 == compound.key4; }
  66. };
  67. namespace DictHash
  68. {
  69. inline U32 hash(U32 data)
  70. {
  71. return data;
  72. }
  73. inline U32 hash(const StringCase &data)
  74. {
  75. return data.getHashCaseSensitive();
  76. }
  77. inline U32 hash(const StringNoCase &data)
  78. {
  79. return data.getHashCaseInsensitive();
  80. }
  81. inline U32 hash(const String &data)
  82. {
  83. return data.getHashCaseInsensitive();
  84. }
  85. inline U32 hash(const char *data)
  86. {
  87. return Torque::hash( (const U8 *)data, dStrlen( data ), 0 );
  88. }
  89. inline U32 hash(const void *data)
  90. {
  91. return (uintptr_t)data;
  92. }
  93. template<class A, class B>
  94. inline U32 hash(const CompoundKey<A,B> & compound)
  95. {
  96. return hash(compound.key1) + hash(compound.key2);
  97. }
  98. template<class A, class B, class C>
  99. inline U32 hash(const CompoundKey3<A,B,C> & compound)
  100. {
  101. return hash(compound.key1) + hash(compound.key2) + hash(compound.key3);
  102. }
  103. template<class A, class B, class C, class D>
  104. inline U32 hash(const CompoundKey4<A, B, C, D>& compound)
  105. {
  106. return hash(compound.key1) + hash(compound.key2) + hash(compound.key3) + hash(compound.key4);
  107. }
  108. U32 nextPrime(U32);
  109. };
  110. namespace KeyCmp
  111. {
  112. template<typename Key>
  113. inline bool equals( const Key &keya, const Key &keyb )
  114. {
  115. return ( keya == keyb );
  116. }
  117. template<>
  118. inline bool equals<>( const StringCase &keya, const StringCase &keyb )
  119. {
  120. return ( keya.equal( keyb, String::Case ) );
  121. }
  122. template<>
  123. inline bool equals<>( const StringNoCase &keya, const StringNoCase &keyb )
  124. {
  125. return ( keya.equal( keyb, String::NoCase ) );
  126. }
  127. template<>
  128. inline bool equals<>( const String &keya, const String &keyb )
  129. {
  130. return ( keya.equal( keyb, String::NoCase ) );
  131. }
  132. template<>
  133. inline bool equals<>( const char * const &keya, const char * const &keyb )
  134. {
  135. return ( String::compare( keya, keyb ) == 0 );
  136. }
  137. };
  138. /// A HashTable template class.
  139. ///
  140. /// The hash table class maps between a key and an associated value. Access
  141. /// using the key is performed using a hash table. The class provides
  142. /// methods for both unique and equal keys. The global ::hash(Type) function
  143. /// is used for hashing, see util/hash.h
  144. /// @ingroup UtilContainers
  145. template<typename Key, typename Value >
  146. class HashTable
  147. {
  148. public:
  149. struct Pair
  150. {
  151. Key key{};
  152. Value value{};
  153. Pair() {}
  154. Pair(Key k,Value v)
  155. : key(k),
  156. value(v)
  157. {}
  158. };
  159. private:
  160. struct Node
  161. {
  162. Node* mNext;
  163. Pair mPair;
  164. Node(): mNext(nullptr) {}
  165. Node(Pair p,Node* n)
  166. : mNext(n),
  167. mPair(p)
  168. {}
  169. };
  170. Node** mTable; ///< Hash table
  171. S32 mTableSize; ///< Hash table size
  172. U32 mSize; ///< Number of keys in the table
  173. ClassChunker<Node> mNodeAllocator;
  174. U32 _hash(const Key& key) const;
  175. U32 _index(const Key& key) const;
  176. Node* _next(U32 index) const;
  177. void _resize(U32 size);
  178. void _destroy();
  179. public:
  180. // Iterator support
  181. template<typename U,typename E, typename M>
  182. class _Iterator {
  183. friend class HashTable;
  184. E* mLink;
  185. M* mHashTable;
  186. operator E*();
  187. public:
  188. typedef U ValueType;
  189. typedef U* Pointer;
  190. typedef U& Reference;
  191. _Iterator()
  192. {
  193. mHashTable = nullptr;
  194. mLink = nullptr;
  195. }
  196. _Iterator(M* table,E* ptr)
  197. {
  198. mHashTable = table;
  199. mLink = ptr;
  200. }
  201. _Iterator& operator++()
  202. {
  203. mLink = mLink->mNext? mLink->mNext :
  204. mHashTable->_next(mHashTable->_index(mLink->mPair.key) + 1);
  205. return *this;
  206. }
  207. _Iterator operator++(int)
  208. {
  209. _Iterator itr(*this);
  210. ++(*this);
  211. return itr;
  212. }
  213. bool operator==(const _Iterator& b) const
  214. {
  215. return mHashTable == b.mHashTable && mLink == b.mLink;
  216. }
  217. bool operator!=(const _Iterator& b) const
  218. {
  219. return !(*this == b);
  220. }
  221. U* operator->() const
  222. {
  223. return &mLink->mPair;
  224. }
  225. U& operator*() const
  226. {
  227. return mLink->mPair;
  228. }
  229. };
  230. // Types
  231. typedef Pair ValueType;
  232. typedef Pair& Reference;
  233. typedef const Pair& ConstReference;
  234. typedef _Iterator<Pair,Node,HashTable> Iterator;
  235. typedef _Iterator<const Pair,const Node,const HashTable> ConstIterator;
  236. typedef S32 DifferenceType;
  237. typedef U32 SizeType;
  238. // Initialization
  239. HashTable();
  240. ~HashTable();
  241. HashTable(const HashTable& p);
  242. // Management
  243. U32 size() const; ///< Return the number of elements
  244. U32 tableSize() const; ///< Return the size of the hash bucket table
  245. void clear(); ///< Empty the HashTable
  246. void resize(U32 size);
  247. bool isEmpty() const; ///< Returns true if the table is empty
  248. F32 collisions() const; ///< Returns the average number of nodes per bucket
  249. // Insert & erase elements
  250. Iterator insertEqual(const Key& key, const Value&);
  251. Iterator insertUnique(const Key& key, const Value&);
  252. void erase(Iterator); ///< Erase the given entry
  253. void erase(const Key& key); ///< Erase all matching keys from the table
  254. void erase(const Key & key, const Value & value); ///< Erase entry for this key-value pair
  255. // HashTable lookup
  256. Iterator findOrInsert(const Key& key);
  257. Iterator find(const Key&); ///< Find the first entry for the given key
  258. ConstIterator find(const Key&) const; ///< Find the first entry for the given key
  259. bool find(const Key & key, Value & value); ///< Find the first entry for the given key
  260. S32 count(const Key&) const; ///< Count the number of matching keys in the table
  261. // Forward Iterator access
  262. Iterator begin(); ///< Iterator to first element
  263. ConstIterator begin() const; ///< Iterator to first element
  264. Iterator end(); ///< Iterator to last element + 1
  265. ConstIterator end() const; ///< Iterator to last element + 1
  266. void operator=(const HashTable& p);
  267. };
  268. template<typename Key, typename Value> HashTable<Key,Value>::HashTable() : mNodeAllocator(512)
  269. {
  270. mTableSize = 0;
  271. mTable = nullptr;
  272. mSize = 0;
  273. }
  274. template<typename Key, typename Value> HashTable<Key,Value>::HashTable(const HashTable& p) : mNodeAllocator(512)
  275. {
  276. mSize = 0;
  277. mTableSize = 0;
  278. mTable = nullptr;
  279. *this = p;
  280. }
  281. template<typename Key, typename Value> HashTable<Key,Value>::~HashTable()
  282. {
  283. _destroy();
  284. }
  285. //-----------------------------------------------------------------------------
  286. template<typename Key, typename Value>
  287. inline U32 HashTable<Key,Value>::_hash(const Key& key) const
  288. {
  289. return DictHash::hash(key);
  290. }
  291. template<typename Key, typename Value>
  292. inline U32 HashTable<Key,Value>::_index(const Key& key) const
  293. {
  294. return _hash(key) % mTableSize;
  295. }
  296. template<typename Key, typename Value>
  297. typename HashTable<Key,Value>::Node* HashTable<Key,Value>::_next(U32 index) const
  298. {
  299. for (; index < mTableSize; index++)
  300. if (Node* node = mTable[index])
  301. return node;
  302. return nullptr;
  303. }
  304. template<typename Key, typename Value>
  305. void HashTable<Key,Value>::_resize(U32 size)
  306. {
  307. S32 currentSize = mTableSize;
  308. mTableSize = DictHash::nextPrime(size);
  309. Node** table = new Node*[mTableSize];
  310. dMemset(table,0,mTableSize * sizeof(Node*));
  311. for (S32 i = 0; i < currentSize; i++)
  312. for (Node* node = mTable[i]; node; )
  313. {
  314. // Get groups of matching keys
  315. Node* last = node;
  316. while (last->mNext && last->mNext->mPair.key == node->mPair.key)
  317. last = last->mNext;
  318. // Move the chain to the new table
  319. Node** link = &table[_index(node->mPair.key)];
  320. Node* tmp = last->mNext;
  321. last->mNext = *link;
  322. *link = node;
  323. node = tmp;
  324. }
  325. delete[] mTable;
  326. mTable = table;
  327. }
  328. template<typename Key, typename Value>
  329. void HashTable<Key,Value>::_destroy()
  330. {
  331. // Call destructors.
  332. for (S32 i = 0; i < mTableSize; i++)
  333. for (Node* ptr = mTable[i]; ptr; )
  334. {
  335. Node *tmp = ptr;
  336. ptr = ptr->mNext;
  337. destructInPlace( tmp );
  338. }
  339. mNodeAllocator.freeBlocks();
  340. delete[] mTable;
  341. mTable = nullptr;
  342. }
  343. //-----------------------------------------------------------------------------
  344. // management
  345. template<typename Key, typename Value>
  346. inline U32 HashTable<Key,Value>::size() const
  347. {
  348. return mSize;
  349. }
  350. template<typename Key, typename Value>
  351. inline U32 HashTable<Key,Value>::tableSize() const
  352. {
  353. return mTableSize;
  354. }
  355. template<typename Key, typename Value>
  356. inline void HashTable<Key,Value>::clear()
  357. {
  358. _destroy();
  359. mTableSize = 0;
  360. mSize = 0;
  361. }
  362. /// Resize the bucket table for an estimated number of elements.
  363. /// This method will optimize the hash bucket table size to hold the given
  364. /// number of elements. The size argument is a hint, and will not be the
  365. /// exact size of the table. If the table is sized down below it's optimal
  366. /// size, the next insert will cause it to be resized again. Normally this
  367. /// function is used to avoid resizes when the number of elements that will
  368. /// be inserted is known in advance.
  369. template<typename Key, typename Value>
  370. inline void HashTable<Key,Value>::resize(U32 size)
  371. {
  372. // Attempt to resize the datachunker as well.
  373. mNodeAllocator.setChunkSize(sizeof(Node) * size);
  374. _resize(size);
  375. }
  376. template<typename Key, typename Value>
  377. inline bool HashTable<Key,Value>::isEmpty() const
  378. {
  379. return mSize == 0;
  380. }
  381. template<typename Key, typename Value>
  382. inline F32 HashTable<Key,Value>::collisions() const
  383. {
  384. S32 chains = 0;
  385. for (S32 i = 0; i < mTableSize; i++)
  386. if (mTable[i])
  387. chains++;
  388. return F32(mSize) / chains;
  389. }
  390. //-----------------------------------------------------------------------------
  391. // add & remove elements
  392. /// Insert the key value pair but don't insert duplicates.
  393. /// This insert method does not insert duplicate keys. If the key already exists in
  394. /// the table the function will fail and end() is returned.
  395. template<typename Key, typename Value>
  396. typename HashTable<Key,Value>::Iterator HashTable<Key,Value>::insertUnique(const Key& key, const Value& x)
  397. {
  398. if (mSize >= mTableSize)
  399. _resize(mSize + 1);
  400. Node** table = &mTable[_index(key)];
  401. for (Node* itr = *table; itr; itr = itr->mNext)
  402. if ( KeyCmp::equals<Key>( itr->mPair.key, key) )
  403. return end();
  404. mSize++;
  405. Node* newNode = mNodeAllocator.alloc();
  406. newNode->mPair = Pair(key, x);
  407. newNode->mNext = *table;
  408. *table = newNode;
  409. return Iterator(this,*table);
  410. }
  411. /// Insert the key value pair and allow duplicates.
  412. /// This insert method allows duplicate keys. Keys are grouped together but
  413. /// are not sorted.
  414. template<typename Key, typename Value>
  415. typename HashTable<Key,Value>::Iterator HashTable<Key,Value>::insertEqual(const Key& key, const Value& x)
  416. {
  417. if (mSize >= mTableSize)
  418. _resize(mSize + 1);
  419. // The new key is inserted at the head of any group of matching keys.
  420. Node** prev = &mTable[_index(key)];
  421. for (Node* itr = *prev; itr; prev = &itr->mNext, itr = itr->mNext)
  422. if ( KeyCmp::equals<Key>( itr->mPair.key, key ) )
  423. break;
  424. mSize++;
  425. Node* newNode = mNodeAllocator.alloc();
  426. newNode->mPair = Pair(key, x);
  427. newNode->mNext = *prev;
  428. *prev = newNode;
  429. return Iterator(this,*prev);
  430. }
  431. template<typename Key, typename Value>
  432. void HashTable<Key,Value>::erase(const Key& key)
  433. {
  434. if (mTable == nullptr)
  435. return;
  436. Node** prev = &mTable[_index(key)];
  437. for (Node* itr = *prev; itr; prev = &itr->mNext, itr = itr->mNext)
  438. if ( KeyCmp::equals<Key>( itr->mPair.key, key ) ) {
  439. // Delete matching keys, which should be grouped together.
  440. do {
  441. Node* tmp = itr;
  442. itr = itr->mNext;
  443. mNodeAllocator.free(tmp);
  444. mSize--;
  445. } while (itr && KeyCmp::equals<Key>( itr->mPair.key, key ) );
  446. *prev = itr;
  447. return;
  448. }
  449. }
  450. template<typename Key, typename Value>
  451. void HashTable<Key,Value>::erase(Iterator node)
  452. {
  453. if (mTable == nullptr)
  454. return;
  455. Node** prev = &mTable[_index(node->key)];
  456. for (Node* itr = *prev; itr; prev = &itr->mNext, itr = itr->mNext)
  457. {
  458. if (itr == node.mLink)
  459. {
  460. *prev = itr->mNext;
  461. mNodeAllocator.free(itr);
  462. mSize--;
  463. return;
  464. }
  465. }
  466. }
  467. template<typename Key, typename Value>
  468. void HashTable<Key,Value>::erase(const Key & key, const Value & value)
  469. {
  470. if (mTable == nullptr)
  471. return;
  472. Node** prev = &mTable[_index(key)];
  473. for (Node* itr = *prev; itr; prev = &itr->mNext, itr = itr->mNext)
  474. {
  475. if ( KeyCmp::equals<Key>( itr->mPair.key, key ) && itr->mPair.value == value)
  476. {
  477. *prev = itr->mNext;
  478. mNodeAllocator.free(itr);
  479. mSize--;
  480. return;
  481. }
  482. }
  483. }
  484. //-----------------------------------------------------------------------------
  485. /// Find the key, or insert a one if it doesn't exist.
  486. /// Returns the first key in the table that matches, or inserts one if there
  487. /// are none.
  488. template<typename Key, typename Value>
  489. typename HashTable<Key,Value>::Iterator HashTable<Key,Value>::findOrInsert(const Key& key)
  490. {
  491. if (mSize >= mTableSize)
  492. _resize(mSize + 1);
  493. Node** table = &mTable[_index(key)];
  494. for (Node* itr = *table; itr; itr = itr->mNext)
  495. if ( KeyCmp::equals<Key>( itr->mPair.key, key ) )
  496. return Iterator(this,itr);
  497. mSize++;
  498. Node* newNode = mNodeAllocator.alloc();
  499. newNode->mPair = Pair(key, Value());
  500. newNode->mNext = *table;
  501. *table = newNode;
  502. return Iterator(this,*table);
  503. }
  504. template<typename Key, typename Value>
  505. typename HashTable<Key,Value>::Iterator HashTable<Key,Value>::find(const Key& key)
  506. {
  507. if (mTableSize)
  508. for (Node* itr = mTable[_index(key)]; itr; itr = itr->mNext)
  509. if ( KeyCmp::equals<Key>( itr->mPair.key, key ) )
  510. return Iterator(this,itr);
  511. return Iterator(this, nullptr);
  512. }
  513. template<typename Key, typename Value>
  514. typename HashTable<Key,Value>::ConstIterator HashTable<Key,Value>::find(const Key& key) const
  515. {
  516. if (mTableSize)
  517. {
  518. for (Node* itr = mTable[_index(key)]; itr; itr = itr->mNext)
  519. {
  520. if ( KeyCmp::equals<Key>( itr->mPair.key, key ) )
  521. return ConstIterator(this,itr);
  522. }
  523. }
  524. return ConstIterator(this, nullptr);
  525. }
  526. template<typename Key, typename Value>
  527. bool HashTable<Key,Value>::find(const Key & key, Value & value)
  528. {
  529. if (mTableSize)
  530. {
  531. for (Node* itr = mTable[_index(key)]; itr; itr = itr->mNext)
  532. if ( KeyCmp::equals<Key>( itr->mPair.key, key ) )
  533. {
  534. value = itr->mPair.value;
  535. return true;
  536. }
  537. }
  538. return false;
  539. }
  540. template<typename Key, typename Value>
  541. S32 HashTable<Key,Value>::count(const Key& key) const
  542. {
  543. S32 count = 0;
  544. if (mTableSize)
  545. for (Node* itr = mTable[_index(key)]; itr; itr = itr->mNext)
  546. if ( KeyCmp::equals<Key>( itr->mPair.key, key ) ) {
  547. // Matching keys should be grouped together.
  548. do {
  549. count++;
  550. itr = itr->mNext;
  551. } while (itr && KeyCmp::equals<Key>( itr->mPair.key, key ) );
  552. break;
  553. }
  554. return count;
  555. }
  556. //-----------------------------------------------------------------------------
  557. // Iterator access
  558. template<typename Key, typename Value>
  559. inline typename HashTable<Key,Value>::Iterator HashTable<Key,Value>::begin()
  560. {
  561. return Iterator(this,_next(0));
  562. }
  563. template<typename Key, typename Value>
  564. inline typename HashTable<Key,Value>::ConstIterator HashTable<Key,Value>::begin() const
  565. {
  566. return ConstIterator(this,_next(0));
  567. }
  568. template<typename Key, typename Value>
  569. inline typename HashTable<Key,Value>::Iterator HashTable<Key,Value>::end()
  570. {
  571. return Iterator(this, nullptr);
  572. }
  573. template<typename Key, typename Value>
  574. inline typename HashTable<Key,Value>::ConstIterator HashTable<Key,Value>::end() const
  575. {
  576. return ConstIterator(this, nullptr);
  577. }
  578. //-----------------------------------------------------------------------------
  579. // operators
  580. template<typename Key, typename Value>
  581. void HashTable<Key,Value>::operator=(const HashTable& p)
  582. {
  583. _destroy();
  584. mTableSize = p.mTableSize;
  585. mTable = new Node*[mTableSize];
  586. mSize = p.mSize;
  587. for (S32 i = 0; i < mTableSize; i++)
  588. if (Node* itr = p.mTable[i])
  589. {
  590. Node** head = &mTable[i];
  591. do
  592. {
  593. *head = new Node(itr->mPair,0);
  594. head = &(*head)->mNext;
  595. itr = itr->mNext;
  596. } while (itr);
  597. }
  598. else
  599. mTable[i] = 0;
  600. }
  601. //-----------------------------------------------------------------------------
  602. // Iterator class
  603. /// A Map template class.
  604. /// The map class maps between a key and an associated value. Keys
  605. /// are unique.
  606. /// The hash table class is used as the default implementation so the
  607. /// the key must be hashable, see util/hash.h for details.
  608. /// @ingroup UtilContainers
  609. template<typename Key, typename Value, class Sequence = HashTable<Key,Value> >
  610. class Map
  611. {
  612. public:
  613. // types
  614. typedef typename Sequence::Pair Pair;
  615. typedef Pair ValueType;
  616. typedef Pair& Reference;
  617. typedef const Pair& ConstReference;
  618. typedef typename Sequence::Iterator Iterator;
  619. typedef typename Sequence::ConstIterator ConstIterator;
  620. typedef S32 DifferenceType;
  621. typedef U32 SizeType;
  622. // initialization
  623. Map() {}
  624. ~Map() {}
  625. Map(const Map& p);
  626. // management
  627. U32 size() const; ///< Return the number of elements
  628. void resize(U32 size);
  629. void clear(); ///< Empty the Map
  630. bool isEmpty() const; ///< Returns true if the map is empty
  631. // insert & erase elements
  632. Iterator insert(const Key& key, const Value&); // Documented below...
  633. void erase(Iterator); ///< Erase the given entry
  634. void erase(const Key& key); ///< Erase the key from the map
  635. // Map lookup
  636. Iterator find(const Key&); ///< Find entry for the given key
  637. ConstIterator find(const Key&) const; ///< Find entry for the given key
  638. bool contains(const Key&a) const
  639. {
  640. return mMap.count(a) > 0;
  641. }
  642. /// Try to get the value of the specified key. Returns true and fills in the value
  643. /// if the key exists. Returns false otherwise.
  644. /// Unlike operator [], this function does not create the key/value if the key
  645. /// is not found.
  646. bool tryGetValue(const Key& key, Value& val) const
  647. {
  648. ConstIterator iter = find(key);
  649. if (iter != end())
  650. {
  651. val = (*iter).value;
  652. return true;
  653. }
  654. return false;
  655. }
  656. // forward Iterator access
  657. Iterator begin(); ///< Iterator to first element
  658. ConstIterator begin() const; ///< Iterator to first element
  659. Iterator end(); ///< IIterator to last element + 1
  660. ConstIterator end() const; ///< Iterator to last element + 1
  661. // operators
  662. /// Index using the given key. If the key is not currently in the map it is added.
  663. /// If you just want to try to get the value without the side effect of creating the
  664. /// key, use tryGetValue() instead.
  665. Value& operator[](const Key&);
  666. private:
  667. Sequence mMap;
  668. };
  669. template<typename Key, typename Value, class Sequence> Map<Key,Value,Sequence>::Map(const Map& p)
  670. {
  671. *this = p;
  672. }
  673. //-----------------------------------------------------------------------------
  674. // management
  675. template<typename Key, typename Value, class Sequence>
  676. inline U32 Map<Key,Value,Sequence>::size() const
  677. {
  678. return mMap.size();
  679. }
  680. template<typename Key, typename Value, class Sequence>
  681. inline void Map<Key,Value,Sequence>::resize(U32 size)
  682. {
  683. return mMap.resize(size);
  684. }
  685. template<typename Key, typename Value, class Sequence>
  686. inline void Map<Key,Value,Sequence>::clear()
  687. {
  688. mMap.clear();
  689. }
  690. template<typename Key, typename Value, class Sequence>
  691. inline bool Map<Key,Value,Sequence>::isEmpty() const
  692. {
  693. return mMap.isEmpty();
  694. }
  695. //-----------------------------------------------------------------------------
  696. // add & remove elements
  697. /// Insert the key value pair but don't allow duplicates.
  698. /// The map class does not allow duplicates keys. If the key already exists in
  699. /// the map the function will fail and return end().
  700. template<typename Key, typename Value, class Sequence>
  701. typename Map<Key,Value,Sequence>::Iterator Map<Key,Value,Sequence>::insert(const Key& key, const Value& x)
  702. {
  703. return mMap.insertUnique(key,x);
  704. }
  705. template<typename Key, typename Value, class Sequence>
  706. void Map<Key,Value,Sequence>::erase(const Key& key)
  707. {
  708. mMap.erase(key);
  709. }
  710. template<typename Key, typename Value, class Sequence>
  711. void Map<Key,Value,Sequence>::erase(Iterator node)
  712. {
  713. mMap.erase(node);
  714. }
  715. //-----------------------------------------------------------------------------
  716. // Searching
  717. template<typename Key, typename Value, class Sequence>
  718. typename Map<Key,Value,Sequence>::Iterator Map<Key,Value,Sequence>::find(const Key& key)
  719. {
  720. return mMap.find(key);
  721. }
  722. template<typename Key, typename Value, class Sequence>
  723. typename Map<Key,Value,Sequence>::ConstIterator Map<Key,Value,Sequence>::find(const Key& key) const
  724. {
  725. return mMap.find(key);
  726. }
  727. //-----------------------------------------------------------------------------
  728. // Iterator access
  729. template<typename Key, typename Value, class Sequence>
  730. inline typename Map<Key,Value,Sequence>::Iterator Map<Key,Value,Sequence>::begin()
  731. {
  732. return mMap.begin();
  733. }
  734. template<typename Key, typename Value, class Sequence>
  735. inline typename Map<Key,Value,Sequence>::ConstIterator Map<Key,Value,Sequence>::begin() const
  736. {
  737. return mMap.begin();
  738. }
  739. template<typename Key, typename Value, class Sequence>
  740. inline typename Map<Key,Value,Sequence>::Iterator Map<Key,Value,Sequence>::end()
  741. {
  742. return mMap.end();
  743. }
  744. template<typename Key, typename Value, class Sequence>
  745. inline typename Map<Key,Value,Sequence>::ConstIterator Map<Key,Value,Sequence>::end() const
  746. {
  747. return mMap.end();
  748. }
  749. //-----------------------------------------------------------------------------
  750. // operators
  751. template<typename Key, typename Value, class Sequence>
  752. inline Value& Map<Key,Value,Sequence>::operator[](const Key& key)
  753. {
  754. return mMap.findOrInsert(key)->value;
  755. }
  756. //-----------------------------------------------------------------------------
  757. // iterator class
  758. /// A HashMap template class.
  759. /// The map class maps between a key and an associated value. Keys
  760. /// are unique.
  761. /// The hash table class is used as the default implementation so the
  762. /// the key must be hashable, see util/hash.h for details.
  763. /// @ingroup UtilContainers
  764. template<typename Key, typename Value, class Sequence = HashTable<Key, Value> >
  765. class HashMap : private Sequence
  766. {
  767. typedef HashTable<Key, Value> Parent;
  768. private:
  769. Sequence mHashMap;
  770. public:
  771. // types
  772. typedef typename Parent::Pair Pair;
  773. typedef Pair ValueType;
  774. typedef Pair& Reference;
  775. typedef const Pair& ConstReference;
  776. typedef typename Parent::Iterator iterator;
  777. typedef typename Parent::ConstIterator const_iterator;
  778. typedef S32 DifferenceType;
  779. typedef U32 SizeType;
  780. // initialization
  781. HashMap() {}
  782. ~HashMap() {}
  783. HashMap(const HashMap& p);
  784. // management
  785. U32 size() const; ///< Return the number of elements
  786. void clear(); ///< Empty the HashMap
  787. bool isEmpty() const; ///< Returns true if the map is empty
  788. // insert & erase elements
  789. iterator insert(const Key& key, const Value&); // Documented below...
  790. void erase(iterator); ///< Erase the given entry
  791. void erase(const Key& key); ///< Erase the key from the map
  792. // HashMap lookup
  793. iterator find(const Key&); ///< Find entry for the given key
  794. const_iterator find(const Key&) const; ///< Find entry for the given key
  795. bool contains(const Key&a)
  796. {
  797. return mHashMap.count(a) > 0;
  798. }
  799. // forward iterator access
  800. iterator begin(); ///< iterator to first element
  801. const_iterator begin() const; ///< iterator to first element
  802. iterator end(); ///< IIterator to last element + 1
  803. const_iterator end() const; ///< iterator to last element + 1
  804. // operators
  805. Value& operator[](const Key&); ///< Index using the given key. If the key is not currently in the map it is added.
  806. };
  807. template<typename Key, typename Value, class Sequence> HashMap<Key, Value, Sequence>::HashMap(const HashMap& p)
  808. {
  809. *this = p;
  810. }
  811. //-----------------------------------------------------------------------------
  812. // management
  813. template<typename Key, typename Value, class Sequence>
  814. inline U32 HashMap<Key, Value, Sequence>::size() const
  815. {
  816. return mHashMap.size();
  817. }
  818. template<typename Key, typename Value, class Sequence>
  819. inline void HashMap<Key, Value, Sequence>::clear()
  820. {
  821. mHashMap.clear();
  822. }
  823. template<typename Key, typename Value, class Sequence>
  824. inline bool HashMap<Key, Value, Sequence>::isEmpty() const
  825. {
  826. return mHashMap.isEmpty();
  827. }
  828. //-----------------------------------------------------------------------------
  829. // add & remove elements
  830. /// Insert the key value pair but don't allow duplicates.
  831. /// The map class does not allow duplicates keys. If the key already exists in
  832. /// the map the function will fail and return end().
  833. template<typename Key, typename Value, class Sequence>
  834. typename HashMap<Key, Value, Sequence>::iterator HashMap<Key, Value, Sequence>::insert(const Key& key, const Value& x)
  835. {
  836. return mHashMap.insertUnique(key, x);
  837. }
  838. template<typename Key, typename Value, class Sequence>
  839. void HashMap<Key, Value, Sequence>::erase(const Key& key)
  840. {
  841. mHashMap.erase(key);
  842. }
  843. template<typename Key, typename Value, class Sequence>
  844. void HashMap<Key, Value, Sequence>::erase(iterator node)
  845. {
  846. mHashMap.erase(node);
  847. }
  848. //-----------------------------------------------------------------------------
  849. // Searching
  850. template<typename Key, typename Value, class Sequence>
  851. typename HashMap<Key, Value, Sequence>::iterator HashMap<Key, Value, Sequence>::find(const Key& key)
  852. {
  853. return mHashMap.find(key);
  854. }
  855. //-----------------------------------------------------------------------------
  856. // iterator access
  857. template<typename Key, typename Value, class Sequence>
  858. inline typename HashMap<Key, Value, Sequence>::iterator HashMap<Key, Value, Sequence>::begin()
  859. {
  860. return mHashMap.begin();
  861. }
  862. template<typename Key, typename Value, class Sequence>
  863. inline typename HashMap<Key, Value, Sequence>::const_iterator HashMap<Key, Value, Sequence>::begin() const
  864. {
  865. return mHashMap.begin();
  866. }
  867. template<typename Key, typename Value, class Sequence>
  868. inline typename HashMap<Key, Value, Sequence>::iterator HashMap<Key, Value, Sequence>::end()
  869. {
  870. return mHashMap.end();
  871. }
  872. template<typename Key, typename Value, class Sequence>
  873. inline typename HashMap<Key, Value, Sequence>::const_iterator HashMap<Key, Value, Sequence>::end() const
  874. {
  875. return mHashMap.end();
  876. }
  877. //-----------------------------------------------------------------------------
  878. // operators
  879. template<typename Key, typename Value, class Sequence>
  880. inline Value& HashMap<Key, Value, Sequence>::operator[](const Key& key)
  881. {
  882. return mHashMap.findOrInsert(key)->value;
  883. }
  884. #endif