Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Map.h 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. /*================================================================
  3. *
  4. * Project : Freyja
  5. * Author : Mongoose
  6. * Website : http://www.westga.edu/~stu7440/
  7. * Email : stu7440@westga.edu
  8. * Object : Map
  9. * License : No use w/o permission (C) 2000-2002 Mongoose
  10. * Comments: mtk Template list
  11. *
  12. * This file was generated using Mongoose's C++
  13. * template generator script. <stu7440@westga.edu>
  14. *
  15. *-- History ------------------------------------------------
  16. *
  17. * 2002.02.19:
  18. * Mongoose - Using RBTree and list overlay for faster access
  19. *
  20. * Access: O(1)/O(n)/O(logn) ?
  21. * Insert: O(nlogn) ?
  22. * Remove: O(nlogn) ?
  23. *
  24. * 2002.02.16:
  25. * Mongoose - Binary tree overlay started... at 0300 /_\ Zzzz
  26. *
  27. * 2002.02.01:
  28. * Mongoose - Dug out of cobwebs and fixed up
  29. * Yes, I believe in code reuse! =)
  30. *
  31. * 2000.10.26:
  32. * Mongoose - Created
  33. ================================================================*/
  34. #ifndef __FREYJA_MONGOOSE_MAP_H_
  35. #define __FREYJA_MONGOOSE_MAP_H_
  36. #include <stdlib.h>
  37. #include <stdio.h>
  38. #include <Tree.h>
  39. #ifdef DEBUG_MEMORY
  40. #include <memory_test.h>
  41. #endif
  42. template <class K, class D> class MapNode
  43. {
  44. public:
  45. MapNode(K key, D data)
  46. {
  47. _data = data;
  48. _key = key;
  49. _next = NULL;
  50. }
  51. ~MapNode()
  52. {
  53. }
  54. void Key(K key)
  55. {
  56. _key = key;
  57. }
  58. K Key()
  59. {
  60. return _key;
  61. }
  62. void Data(D data)
  63. {
  64. _data = data;
  65. }
  66. D Data()
  67. {
  68. return _data;
  69. }
  70. MapNode<K, D> *Next()
  71. {
  72. return _next;
  73. }
  74. void Next(MapNode<K, D> *next)
  75. {
  76. _next = next;
  77. }
  78. private:
  79. MapNode<K, D> *_next;
  80. K _key;
  81. D _data;
  82. };
  83. template <class K, class D> class Map
  84. {
  85. public:
  86. Map()
  87. {
  88. UnSetError();
  89. _num_items = 0;
  90. _head = NULL;
  91. _current = NULL;
  92. _cache = NULL;
  93. }
  94. ~Map()
  95. {
  96. Clear();
  97. }
  98. void Clear()
  99. {
  100. UnSetError();
  101. _num_items = 0;
  102. _cache = NULL;
  103. while (_head)
  104. {
  105. _current = _head;
  106. _head = _head->Next();
  107. delete _current;
  108. }
  109. _tree.Clear();
  110. }
  111. void SetError()
  112. {
  113. _error = true;
  114. }
  115. void UnSetError()
  116. {
  117. _error = false;
  118. }
  119. bool GetError()
  120. {
  121. return _error;
  122. }
  123. D FindDataByKey(K key)
  124. {
  125. MapNode<K, D> *current = NULL;
  126. MapNode<K, D> *next = NULL;
  127. if (_head)
  128. {
  129. UnSetError();
  130. if (_cache)
  131. {
  132. next = _cache->Next();
  133. }
  134. // Mongoose 2002.02.19, Optimize for sequential searches
  135. if (next && key == next->Key())
  136. {
  137. current = next;
  138. }
  139. else // Mongoose 2002.02.19, Use search algorithm otherwise
  140. {
  141. current = _tree.SearchByKey(key, &_error);
  142. if (_error)
  143. return false;
  144. }
  145. if (current)
  146. {
  147. _cache = _current = current;
  148. return current->Data();
  149. }
  150. }
  151. SetError();
  152. return 0;
  153. }
  154. D operator [] (K key)
  155. {
  156. return FindDataByKey(key);
  157. }
  158. K FindKeyByData(D data)
  159. {
  160. MapNode<K, D> *current = _head;
  161. MapNode<K, D> *last = NULL;
  162. UnSetError();
  163. while (current)
  164. {
  165. // Found
  166. if (current->Data() == data)
  167. {
  168. _cache = current;
  169. return current->Key();
  170. }
  171. last = current;
  172. current = current->Next();
  173. }
  174. SetError();
  175. return 0;
  176. }
  177. D getCache()
  178. {
  179. if (_cache == 0x0)
  180. {
  181. printf("Map::getCache> Bad request - should segfault\n");
  182. }
  183. return _cache->Data();
  184. }
  185. bool findKey(K key)
  186. {
  187. MapNode<K, D> *current = NULL;
  188. MapNode<K, D> *next = NULL;
  189. if (_head)
  190. {
  191. UnSetError();
  192. if (_cache)
  193. {
  194. if (_cache->Key() == key)
  195. {
  196. return true;
  197. }
  198. next = _cache->Next();
  199. }
  200. // Mongoose 2002.02.19, Optimize for sequential searches
  201. if (next && key == next->Key())
  202. {
  203. current = next;
  204. }
  205. else // Mongoose 2002.02.19, Use search algorithm otherwise
  206. {
  207. current = _tree.SearchByKey(key, &_error);
  208. }
  209. if (current)
  210. {
  211. _cache = _current = current;
  212. //curData = current->Data();
  213. return true;
  214. }
  215. }
  216. SetError();
  217. return false;
  218. }
  219. bool Add(K key, D data)
  220. {
  221. MapNode<K, D> *node;
  222. UnSetError();
  223. node = new MapNode<K, D>(key, data);
  224. _num_items++;
  225. return Add(node);
  226. }
  227. bool Add(MapNode<K, D> *node)
  228. {
  229. MapNode<K, D> *current = _head;
  230. MapNode<K, D> *last = NULL;
  231. if (!node)
  232. return false;
  233. UnSetError();
  234. if (_head)
  235. {
  236. current = _head;
  237. last = NULL;
  238. while (current)
  239. {
  240. // Prepend
  241. if (current->Key() > node->Key())
  242. {
  243. node->Next(current);
  244. if (current == _head)
  245. {
  246. _head = node;
  247. }
  248. else if (last)
  249. {
  250. last->Next(node);
  251. }
  252. _tree.Insert(node->Key(), node);
  253. return true;
  254. }
  255. last = current;
  256. current = current->Next();
  257. }
  258. // Append
  259. last->Next(node);
  260. }
  261. else
  262. {
  263. _head = node;
  264. }
  265. _tree.Insert(node->Key(), node);
  266. return true;
  267. }
  268. void RemoveByKey(K key)
  269. {
  270. MapNode<K, D> *current = _head;
  271. MapNode<K, D> *last = NULL;
  272. UnSetError();
  273. _cache = NULL;
  274. while (current)
  275. {
  276. // Remove
  277. if (current->Key() == key)
  278. {
  279. if (current == _head)
  280. {
  281. _head = current->Next();
  282. }
  283. else
  284. {
  285. last->Next(current->Next());
  286. }
  287. if (_current == current)
  288. {
  289. _current = NULL;
  290. }
  291. _tree.RemoveByKey(current->Key());
  292. delete current;
  293. _num_items--;
  294. return;
  295. }
  296. last = current;
  297. current = current->Next();
  298. }
  299. SetError();
  300. }
  301. void RemoveByData(D data)
  302. {
  303. MapNode<K, D> *current = _head;
  304. MapNode<K, D> *last = NULL;
  305. UnSetError();
  306. _cache = NULL;
  307. while (current)
  308. {
  309. // Remove
  310. if (current->Data() == data)
  311. {
  312. if (current == _head)
  313. {
  314. _head = current->Next();
  315. }
  316. else
  317. {
  318. last->Next(current->Next());
  319. }
  320. if (_current == current)
  321. {
  322. _current = NULL;
  323. }
  324. _tree.RemoveByKey(current->Key());
  325. delete current;
  326. _num_items--;
  327. return;
  328. }
  329. last = current;
  330. current = current->Next();
  331. }
  332. SetError();
  333. }
  334. bool Empty()
  335. {
  336. return (_head == NULL);
  337. }
  338. unsigned int count()
  339. {
  340. return _num_items;
  341. }
  342. unsigned int NumItems()
  343. {
  344. return _num_items;
  345. }
  346. void Print(void (*print_key_func)(K), void (*print_data_func)(D))
  347. {
  348. MapNode<K, D> *current = _head;
  349. UnSetError();
  350. if (!print_key_func || !print_data_func)
  351. {
  352. SetError();
  353. return;
  354. }
  355. printf(" [%i] {\n", _num_items);
  356. while (current)
  357. {
  358. printf("(");
  359. (*print_key_func)(current->Key());
  360. printf(", ");
  361. (*print_data_func)(current->Data());
  362. printf("), ");
  363. current = current->Next();
  364. fflush(stdout);
  365. }
  366. printf(" }\n");
  367. }
  368. void Reset()
  369. {
  370. _current = _head;
  371. _cache = _head;
  372. }
  373. bool operator ++ (int dummy)
  374. {
  375. return Next();
  376. }
  377. bool Next()
  378. {
  379. if (_current)
  380. {
  381. _current = _current->Next();
  382. }
  383. return (_current != NULL);
  384. }
  385. bool CurrentExists()
  386. {
  387. return (_current != 0);
  388. }
  389. K CurrentKey()
  390. {
  391. UnSetError();
  392. if (!_current)
  393. {
  394. SetError();
  395. return 0;
  396. }
  397. return _current->Key();
  398. }
  399. D Current()
  400. {
  401. UnSetError();
  402. if (!_current)
  403. {
  404. SetError();
  405. return 0;
  406. }
  407. return _current->Data();
  408. }
  409. private:
  410. unsigned int _num_items;
  411. bool _error;
  412. Tree<K, MapNode<K, D> *> _tree;
  413. MapNode<K, D> *_head;
  414. MapNode<K, D> *_current;
  415. MapNode<K, D> *_cache;
  416. };
  417. #endif