tDictionary.h 29 KB

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