DS_Map.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. /// \file DS_Map.h
  11. /// \internal
  12. /// \brief Map
  13. ///
  14. #ifndef __RAKNET_MAP_H
  15. #define __RAKNET_MAP_H
  16. #include "DS_OrderedList.h"
  17. #include "Export.h"
  18. #include "RakMemoryOverride.h"
  19. #include "RakAssert.h"
  20. // If I want to change this to a red-black tree, this is a good site: http://www.cs.auckland.ac.nz/software/AlgAnim/red_black.html
  21. // This makes insertions and deletions faster. But then traversals are slow, while they are currently fast.
  22. /// The namespace DataStructures was only added to avoid compiler errors for commonly named data structures
  23. /// As these data structures are stand-alone, you can use them outside of RakNet for your own projects if you wish.
  24. namespace DataStructures
  25. {
  26. /// The default comparison has to be first so it can be called as a default parameter.
  27. /// It then is followed by MapNode, followed by NodeComparisonFunc
  28. template <class key_type>
  29. int defaultMapKeyComparison(const key_type &a, const key_type &b)
  30. {
  31. if (a<b) return -1; if (a==b) return 0; return 1;
  32. }
  33. /// \note IMPORTANT! If you use defaultMapKeyComparison then call IMPLEMENT_DEFAULT_COMPARISON or you will get an unresolved external linker error.
  34. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&, const key_type&)=defaultMapKeyComparison<key_type> >
  35. class RAK_DLL_EXPORT Map
  36. {
  37. public:
  38. static void IMPLEMENT_DEFAULT_COMPARISON(void) {DataStructures::defaultMapKeyComparison<key_type>(key_type(),key_type());}
  39. struct MapNode
  40. {
  41. MapNode() {}
  42. MapNode(key_type _key, data_type _data) : mapNodeKey(_key), mapNodeData(_data) {}
  43. MapNode& operator = ( const MapNode& input ) {mapNodeKey=input.mapNodeKey; mapNodeData=input.mapNodeData; return *this;}
  44. MapNode( const MapNode & input) {mapNodeKey=input.mapNodeKey; mapNodeData=input.mapNodeData;}
  45. key_type mapNodeKey;
  46. data_type mapNodeData;
  47. };
  48. // Has to be a static because the comparison callback for DataStructures::OrderedList is a C function
  49. static int NodeComparisonFunc(const key_type &a, const MapNode &b)
  50. {
  51. #ifdef _MSC_VER
  52. #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
  53. #endif
  54. return key_comparison_func(a, b.mapNodeKey);
  55. }
  56. Map();
  57. ~Map();
  58. Map( const Map& original_copy );
  59. Map& operator= ( const Map& original_copy );
  60. data_type& Get(const key_type &key) const;
  61. data_type Pop(const key_type &key);
  62. // Add if needed
  63. void Set(const key_type &key, const data_type &data);
  64. // Must already exist
  65. void SetExisting(const key_type &key, const data_type &data);
  66. // Must add
  67. void SetNew(const key_type &key, const data_type &data);
  68. bool Has(const key_type &key) const;
  69. bool Delete(const key_type &key);
  70. data_type& operator[] ( const unsigned int position ) const;
  71. key_type GetKeyAtIndex( const unsigned int position ) const;
  72. unsigned GetIndexAtKey( const key_type &key );
  73. void RemoveAtIndex(const unsigned index);
  74. void Clear(void);
  75. unsigned Size(void) const;
  76. protected:
  77. DataStructures::OrderedList< key_type,MapNode,&Map::NodeComparisonFunc > mapNodeList;
  78. void SaveLastSearch(const key_type &key, unsigned index) const;
  79. bool HasSavedSearchResult(const key_type &key) const;
  80. unsigned lastSearchIndex;
  81. key_type lastSearchKey;
  82. bool lastSearchIndexValid;
  83. };
  84. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  85. Map<key_type, data_type, key_comparison_func>::Map()
  86. {
  87. lastSearchIndexValid=false;
  88. }
  89. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  90. Map<key_type, data_type, key_comparison_func>::~Map()
  91. {
  92. Clear();
  93. }
  94. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  95. Map<key_type, data_type, key_comparison_func>::Map( const Map& original_copy )
  96. {
  97. mapNodeList=original_copy.mapNodeList;
  98. lastSearchIndex=original_copy.lastSearchIndex;
  99. lastSearchKey=original_copy.lastSearchKey;
  100. lastSearchIndexValid=original_copy.lastSearchIndexValid;
  101. }
  102. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  103. Map<key_type, data_type, key_comparison_func>& Map<key_type, data_type, key_comparison_func>::operator= ( const Map& original_copy )
  104. {
  105. mapNodeList=original_copy.mapNodeList;
  106. lastSearchIndex=original_copy.lastSearchIndex;
  107. lastSearchKey=original_copy.lastSearchKey;
  108. lastSearchIndexValid=original_copy.lastSearchIndexValid;
  109. return *this;
  110. }
  111. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  112. data_type& Map<key_type, data_type, key_comparison_func>::Get(const key_type &key) const
  113. {
  114. if (HasSavedSearchResult(key))
  115. return mapNodeList[lastSearchIndex].mapNodeData;
  116. bool objectExists;
  117. unsigned index;
  118. index=mapNodeList.GetIndexFromKey(key, &objectExists);
  119. RakAssert(objectExists);
  120. SaveLastSearch(key,index);
  121. return mapNodeList[index].mapNodeData;
  122. }
  123. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  124. unsigned Map<key_type, data_type, key_comparison_func>::GetIndexAtKey( const key_type &key )
  125. {
  126. if (HasSavedSearchResult(key))
  127. return lastSearchIndex;
  128. bool objectExists;
  129. unsigned index;
  130. index=mapNodeList.GetIndexFromKey(key, &objectExists);
  131. if (objectExists==false)
  132. {
  133. RakAssert(objectExists);
  134. }
  135. SaveLastSearch(key,index);
  136. return index;
  137. }
  138. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  139. void Map<key_type, data_type, key_comparison_func>::RemoveAtIndex(const unsigned index)
  140. {
  141. mapNodeList.RemoveAtIndex(index);
  142. lastSearchIndexValid=false;
  143. }
  144. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  145. data_type Map<key_type, data_type, key_comparison_func>::Pop(const key_type &key)
  146. {
  147. bool objectExists;
  148. unsigned index;
  149. if (HasSavedSearchResult(key))
  150. index=lastSearchIndex;
  151. else
  152. {
  153. index=mapNodeList.GetIndexFromKey(key, &objectExists);
  154. RakAssert(objectExists);
  155. }
  156. data_type tmp = mapNodeList[index].mapNodeData;
  157. mapNodeList.RemoveAtIndex(index);
  158. lastSearchIndexValid=false;
  159. return tmp;
  160. }
  161. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  162. void Map<key_type, data_type, key_comparison_func>::Set(const key_type &key, const data_type &data)
  163. {
  164. bool objectExists;
  165. unsigned index;
  166. if (HasSavedSearchResult(key))
  167. {
  168. mapNodeList[lastSearchIndex].mapNodeData=data;
  169. return;
  170. }
  171. index=mapNodeList.GetIndexFromKey(key, &objectExists);
  172. if (objectExists)
  173. {
  174. SaveLastSearch(key,index);
  175. mapNodeList[index].mapNodeData=data;
  176. }
  177. else
  178. {
  179. SaveLastSearch(key,mapNodeList.Insert(key,MapNode(key,data), true, _FILE_AND_LINE_));
  180. }
  181. }
  182. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  183. void Map<key_type, data_type, key_comparison_func>::SetExisting(const key_type &key, const data_type &data)
  184. {
  185. bool objectExists;
  186. unsigned index;
  187. if (HasSavedSearchResult(key))
  188. {
  189. index=lastSearchIndex;
  190. }
  191. else
  192. {
  193. index=mapNodeList.GetIndexFromKey(key, &objectExists);
  194. RakAssert(objectExists);
  195. SaveLastSearch(key,index);
  196. }
  197. mapNodeList[index].mapNodeData=data;
  198. }
  199. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  200. void Map<key_type, data_type, key_comparison_func>::SetNew(const key_type &key, const data_type &data)
  201. {
  202. #ifdef _DEBUG
  203. bool objectExists;
  204. mapNodeList.GetIndexFromKey(key, &objectExists);
  205. RakAssert(objectExists==false);
  206. #endif
  207. SaveLastSearch(key,mapNodeList.Insert(key,MapNode(key,data), true, _FILE_AND_LINE_));
  208. }
  209. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  210. bool Map<key_type, data_type, key_comparison_func>::Has(const key_type &key) const
  211. {
  212. if (HasSavedSearchResult(key))
  213. return true;
  214. bool objectExists;
  215. unsigned index;
  216. index=mapNodeList.GetIndexFromKey(key, &objectExists);
  217. if (objectExists)
  218. SaveLastSearch(key,index);
  219. return objectExists;
  220. }
  221. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  222. bool Map<key_type, data_type, key_comparison_func>::Delete(const key_type &key)
  223. {
  224. if (HasSavedSearchResult(key))
  225. {
  226. lastSearchIndexValid=false;
  227. mapNodeList.RemoveAtIndex(lastSearchIndex);
  228. return true;
  229. }
  230. bool objectExists;
  231. unsigned index;
  232. index=mapNodeList.GetIndexFromKey(key, &objectExists);
  233. if (objectExists)
  234. {
  235. lastSearchIndexValid=false;
  236. mapNodeList.RemoveAtIndex(index);
  237. return true;
  238. }
  239. else
  240. return false;
  241. }
  242. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  243. void Map<key_type, data_type, key_comparison_func>::Clear(void)
  244. {
  245. lastSearchIndexValid=false;
  246. mapNodeList.Clear(false, _FILE_AND_LINE_);
  247. }
  248. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  249. data_type& Map<key_type, data_type, key_comparison_func>::operator[]( const unsigned int position ) const
  250. {
  251. return mapNodeList[position].mapNodeData;
  252. }
  253. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  254. key_type Map<key_type, data_type, key_comparison_func>::GetKeyAtIndex( const unsigned int position ) const
  255. {
  256. return mapNodeList[position].mapNodeKey;
  257. }
  258. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  259. unsigned Map<key_type, data_type, key_comparison_func>::Size(void) const
  260. {
  261. return mapNodeList.Size();
  262. }
  263. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  264. void Map<key_type, data_type, key_comparison_func>::SaveLastSearch(const key_type &key, const unsigned index) const
  265. {
  266. (void) key;
  267. (void) index;
  268. /*
  269. lastSearchIndex=index;
  270. lastSearchKey=key;
  271. lastSearchIndexValid=true;
  272. */
  273. }
  274. template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
  275. bool Map<key_type, data_type, key_comparison_func>::HasSavedSearchResult(const key_type &key) const
  276. {
  277. (void) key;
  278. // Not threadsafe!
  279. return false;
  280. // return lastSearchIndexValid && key_comparison_func(key,lastSearchKey)==0;
  281. }
  282. }
  283. #endif
粤ICP备19079148号