Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Map.h 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. /*!
  2. * \file include/Map.h
  3. * \brief Template Map
  4. *
  5. * Using RBTree and list overlay for faster access
  6. *
  7. * Access: O(1)/O(n)/O(logn) ?
  8. * Insert: O(nlogn) ?
  9. * Remove: O(nlogn) ?
  10. *
  11. * \author Mongoose
  12. * \author xythobuz
  13. */
  14. #ifndef _MAP_H_
  15. #define _MAP_H_
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <Tree.h>
  19. #ifdef DEBUG_MEMORY
  20. #include <memory_test.h>
  21. #endif
  22. /*!
  23. * \brief Template class encapsulating a single map node
  24. * \tparam K key type
  25. * \tparam D data type
  26. */
  27. template <class K, class D> class MapNode {
  28. public:
  29. /*!
  30. * \brief Construct a MapNode
  31. * \param key key of this Node
  32. * \param data data of this Node
  33. */
  34. MapNode(K key, D data) {
  35. _data = data;
  36. _key = key;
  37. _next = NULL;
  38. }
  39. /*!
  40. * \brief Deconstruct a MapNode
  41. */
  42. ~MapNode() {
  43. }
  44. /*!
  45. * \brief Set the key of this MapNode
  46. * \param key new key
  47. */
  48. void Key(K key) {
  49. _key = key;
  50. }
  51. /*!
  52. * \brief Get the key of this MapNode
  53. * \returns key
  54. */
  55. K Key() {
  56. return _key;
  57. }
  58. /*!
  59. * \brief Set the data of this MapNode
  60. * \param data new data
  61. */
  62. void Data(D data) {
  63. _data = data;
  64. }
  65. /*!
  66. * \brief Get the data of this MapNode
  67. * \returns data
  68. */
  69. D Data() {
  70. return _data;
  71. }
  72. /*!
  73. * \brief Get the next MapNode in the Map
  74. * \returns next pointer
  75. */
  76. MapNode<K, D> *Next() {
  77. return _next;
  78. }
  79. /*!
  80. * \brief Set the next MapNode in the Map
  81. * \param next new next pointer
  82. */
  83. void Next(MapNode<K, D> *next) {
  84. _next = next;
  85. }
  86. private:
  87. MapNode<K, D> *_next; //!< Next pointer
  88. K _key; //!< Key of the MapNode
  89. D _data; //!< Data of the MapNode
  90. };
  91. /*!
  92. * \brief Template class representing a Map, mapping data to a key.
  93. * \tparam K key type
  94. * \tparam D data type
  95. */
  96. template <class K, class D> class Map {
  97. public:
  98. /*!
  99. * \brief Construct a Map
  100. */
  101. Map() {
  102. UnSetError();
  103. _num_items = 0;
  104. _head = NULL;
  105. _current = NULL;
  106. _cache = NULL;
  107. }
  108. /*!
  109. * \brief Deconstruct a Map
  110. * \sa Map::Clear()
  111. */
  112. ~Map() {
  113. Clear();
  114. }
  115. /*!
  116. * \brief Deletes every item in the Map. Clears error flag.
  117. */
  118. void Clear() {
  119. UnSetError();
  120. _num_items = 0;
  121. _cache = NULL;
  122. while (_head) {
  123. _current = _head;
  124. _head = _head->Next();
  125. delete _current;
  126. }
  127. _tree.Clear();
  128. }
  129. /*!
  130. * \brief Set the error flag
  131. */
  132. void SetError() {
  133. _error = true;
  134. }
  135. /*!
  136. * \brief Unset the error flag
  137. */
  138. void UnSetError() {
  139. _error = false;
  140. }
  141. /*!
  142. * \brief Get the error flag
  143. * \returns error flag
  144. */
  145. bool GetError() {
  146. return _error;
  147. }
  148. /*!
  149. * \brief Search for data with a key. Sets error flag if nothing is found.
  150. * \param key key to search for
  151. * \returns data matching key or 0
  152. */
  153. D FindDataByKey(K key) {
  154. MapNode<K, D> *current = NULL;
  155. MapNode<K, D> *next = NULL;
  156. if (_head) {
  157. UnSetError();
  158. if (_cache) {
  159. next = _cache->Next();
  160. }
  161. // Mongoose 2002.02.19, Optimize for sequential searches
  162. if (next && key == next->Key()) {
  163. current = next;
  164. } else { // Mongoose 2002.02.19, Use search algorithm otherwise
  165. current = _tree.SearchByKey(key, &_error);
  166. if (_error)
  167. return false;
  168. }
  169. if (current) {
  170. _cache = _current = current;
  171. return current->Data();
  172. }
  173. }
  174. SetError();
  175. return 0;
  176. }
  177. /*!
  178. * \brief Search for data with a key
  179. * \param key key to search for
  180. * \returns data matching key or 0
  181. * \sa Map::FindDataByKey()
  182. */
  183. D operator [] (K key) {
  184. return FindDataByKey(key);
  185. }
  186. /*!
  187. * \brief Search for a key with specific data. Sets error flag if nothing is found.
  188. * \param data data to search for
  189. * \returns key matching data or 0
  190. */
  191. K FindKeyByData(D data) {
  192. MapNode<K, D> *current = _head;
  193. MapNode<K, D> *last = NULL;
  194. UnSetError();
  195. while (current) {
  196. // Found
  197. if (current->Data() == data) {
  198. _cache = current;
  199. return current->Key();
  200. }
  201. last = current;
  202. current = current->Next();
  203. }
  204. SetError();
  205. return 0;
  206. }
  207. /*!
  208. * \brief Returns data of the cached MapNode
  209. * \returns cached data
  210. */
  211. D getCache() {
  212. if (_cache == 0x0) {
  213. printf("Map::getCache> Bad request - should segfault\n");
  214. }
  215. return _cache->Data();
  216. }
  217. /*!
  218. * \brief Check if a key is in this map. Sets error flag if nothing is found.
  219. * \returns true if the key is in the map, false otherwise
  220. * \sa Tree:SearchByKey()
  221. */
  222. bool findKey(K key) {
  223. MapNode<K, D> *current = NULL;
  224. MapNode<K, D> *next = NULL;
  225. if (_head) {
  226. UnSetError();
  227. if (_cache) {
  228. if (_cache->Key() == key) {
  229. return true;
  230. }
  231. next = _cache->Next();
  232. }
  233. // Mongoose 2002.02.19, Optimize for sequential searches
  234. if (next && key == next->Key()) {
  235. current = next;
  236. } else { // Mongoose 2002.02.19, Use search algorithm otherwise
  237. current = _tree.SearchByKey(key, &_error);
  238. }
  239. if (current) {
  240. _cache = _current = current;
  241. //curData = current->Data();
  242. return true;
  243. }
  244. }
  245. SetError();
  246. return false;
  247. }
  248. /*!
  249. * \brief Add a Key-Data pair to the Map, creating a new MapNode. Clears error flag.
  250. * \param key key to add
  251. * \param data to add
  252. * \returns true on success, false if there is not enough memory
  253. */
  254. bool Add(K key, D data) {
  255. MapNode<K, D> *node;
  256. UnSetError();
  257. node = new MapNode<K, D>(key, data);
  258. _num_items++;
  259. return Add(node);
  260. }
  261. /*!
  262. * \brief Add a MapNode to the Map. Clears error flag on success.
  263. * \param node node to add
  264. * \returns true on success, false if node is NULL
  265. * \sa Tree:Insert()
  266. */
  267. bool Add(MapNode<K, D> *node) {
  268. MapNode<K, D> *current = _head;
  269. MapNode<K, D> *last = NULL;
  270. if (!node)
  271. return false;
  272. UnSetError();
  273. if (_head) {
  274. current = _head;
  275. last = NULL;
  276. while (current) {
  277. // Prepend
  278. if (current->Key() > node->Key()) {
  279. node->Next(current);
  280. if (current == _head) {
  281. _head = node;
  282. } else if (last) {
  283. last->Next(node);
  284. }
  285. _tree.Insert(node->Key(), node);
  286. return true;
  287. }
  288. last = current;
  289. current = current->Next();
  290. }
  291. // Append
  292. last->Next(node);
  293. } else {
  294. _head = node;
  295. }
  296. _tree.Insert(node->Key(), node);
  297. return true;
  298. }
  299. /*!
  300. * \brief Remove item with the specified key. Sets error flag if nothing is removed.
  301. * \param key key to remove
  302. */
  303. void RemoveByKey(K key) {
  304. MapNode<K, D> *current = _head;
  305. MapNode<K, D> *last = NULL;
  306. UnSetError();
  307. _cache = NULL;
  308. while (current) {
  309. // Remove
  310. if (current->Key() == key) {
  311. if (current == _head) {
  312. _head = current->Next();
  313. } else {
  314. last->Next(current->Next());
  315. }
  316. if (_current == current) {
  317. _current = NULL;
  318. }
  319. _tree.RemoveByKey(current->Key());
  320. delete current;
  321. _num_items--;
  322. return;
  323. }
  324. last = current;
  325. current = current->Next();
  326. }
  327. SetError();
  328. }
  329. /*!
  330. * \brief Remove item with the specified data. Sets error flag if nothing is removed.
  331. * \param data data to remove
  332. */
  333. void RemoveByData(D data) {
  334. MapNode<K, D> *current = _head;
  335. MapNode<K, D> *last = NULL;
  336. UnSetError();
  337. _cache = NULL;
  338. while (current)
  339. {
  340. // Remove
  341. if (current->Data() == data) {
  342. if (current == _head) {
  343. _head = current->Next();
  344. } else {
  345. last->Next(current->Next());
  346. }
  347. if (_current == current) {
  348. _current = NULL;
  349. }
  350. _tree.RemoveByKey(current->Key());
  351. delete current;
  352. _num_items--;
  353. return;
  354. }
  355. last = current;
  356. current = current->Next();
  357. }
  358. SetError();
  359. }
  360. /*!
  361. * \brief Check if the Map is empty
  362. * \returns true if Map is empty, false otherwise
  363. */
  364. bool Empty() {
  365. return (_head == NULL);
  366. }
  367. /*!
  368. * \brief Returns number of items in the Map
  369. * \returns number of items
  370. */
  371. unsigned int NumItems() {
  372. return _num_items;
  373. }
  374. /*!
  375. * \brief Print the Map. Sets error flag if one or both functions aren't provided.
  376. * \param print_key_func function that prints a key
  377. * \param print_data_func function that prints the data
  378. */
  379. void Print(void (*print_key_func)(K), void (*print_data_func)(D)) {
  380. MapNode<K, D> *current = _head;
  381. UnSetError();
  382. if (!print_key_func || !print_data_func) {
  383. SetError();
  384. return;
  385. }
  386. printf(" [%i] {\n", _num_items);
  387. while (current) {
  388. printf("(");
  389. (*print_key_func)(current->Key());
  390. printf(", ");
  391. (*print_data_func)(current->Data());
  392. printf("), ");
  393. current = current->Next();
  394. fflush(stdout);
  395. }
  396. printf(" }\n");
  397. }
  398. /*!
  399. * \brief Reset the Map iterator
  400. */
  401. void Reset() {
  402. _current = _head;
  403. _cache = _head;
  404. }
  405. /*!
  406. * \brief Iterate over the Map
  407. * \returns true if there is a new current element
  408. * \sa Map::Next()
  409. */
  410. bool operator ++ (int) {
  411. return Next();
  412. }
  413. /*!
  414. * \brief Iterate over the Map
  415. * \returns true if there is a new current element
  416. * \sa Map::Next()
  417. */
  418. bool operator ++ () {
  419. return Next();
  420. }
  421. /*!
  422. * \brief Iterate over the Map
  423. * \returns true if there is a new current element
  424. * \sa Map::Next()
  425. */
  426. bool Next() {
  427. if (_current) {
  428. _current = _current->Next();
  429. }
  430. return (_current != NULL);
  431. }
  432. /*!
  433. * \brief Check if there is a current item in the iterator
  434. * \returns true if the current item exists
  435. */
  436. bool CurrentExists() {
  437. return (_current != 0);
  438. }
  439. /*!
  440. * \brief Returns the key of the current item. Sets error flag if there is no current item.
  441. * \returns key or 0 if there is no current item
  442. */
  443. K CurrentKey() {
  444. UnSetError();
  445. if (!_current) {
  446. SetError();
  447. return 0;
  448. }
  449. return _current->Key();
  450. }
  451. /*!
  452. * \brief Returns the data of the current item. Sets error flag if there is no current item.
  453. * \returns data or 0 if there is no current item
  454. */
  455. D Current() {
  456. UnSetError();
  457. if (!_current) {
  458. SetError();
  459. return 0;
  460. }
  461. return _current->Data();
  462. }
  463. private:
  464. unsigned int _num_items; //!< Number of items in the Map
  465. bool _error; //!< Error flag
  466. Tree<K, MapNode<K, D> *> _tree; //!< Tree containing the MapNodes
  467. MapNode<K, D> *_head; //!< First item of the Map
  468. MapNode<K, D> *_current; //!< Current item for the iterator
  469. MapNode<K, D> *_cache; //!< Cached item used by search & remove methods
  470. };
  471. #endif