PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/llmap.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 245 lines | 178 code | 26 blank | 41 comment | 18 complexity | b03343d28c807a3f6ad58f7b1f15b5c2 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llmap.h
  3. * @brief LLMap class header file
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLMAP_H
  27. #define LL_LLMAP_H
  28. // llmap uses the fast stl library code in a manner consistant with LLSkipMap, et. al.
  29. template<class INDEX_TYPE, class MAPPED_TYPE> class LLMap
  30. {
  31. private:
  32. typedef typename std::map<INDEX_TYPE, MAPPED_TYPE> stl_map_t;
  33. typedef typename stl_map_t::iterator stl_iter_t;
  34. typedef typename stl_map_t::value_type stl_value_t;
  35. stl_map_t mStlMap;
  36. stl_iter_t mCurIter; // *iterator = pair<const INDEX_TYPE, MAPPED_TYPE>
  37. MAPPED_TYPE dummy_data;
  38. INDEX_TYPE dummy_index;
  39. public:
  40. LLMap() : mStlMap()
  41. {
  42. memset((void*)(&dummy_data), 0x0, sizeof(MAPPED_TYPE));
  43. memset((void*)(&dummy_index), 0x0, sizeof(INDEX_TYPE));
  44. mCurIter = mStlMap.begin();
  45. }
  46. ~LLMap()
  47. {
  48. mStlMap.clear();
  49. }
  50. // use these functions to itterate through a list
  51. void resetMap()
  52. {
  53. mCurIter = mStlMap.begin();
  54. }
  55. // get the current data and bump mCurrentp
  56. // This is kind of screwy since it returns a reference;
  57. // We have to have a dummy value for when we reach the end
  58. // or in case we have an empty list. Presumably, this value
  59. // will initialize to some NULL value that will end the iterator.
  60. // We really shouldn't be using getNextData() or getNextKey() anyway...
  61. MAPPED_TYPE &getNextData()
  62. {
  63. if (mCurIter == mStlMap.end())
  64. {
  65. return dummy_data;
  66. }
  67. else
  68. {
  69. return (*mCurIter++).second;
  70. }
  71. }
  72. const INDEX_TYPE &getNextKey()
  73. {
  74. if (mCurIter == mStlMap.end())
  75. {
  76. return dummy_index;
  77. }
  78. else
  79. {
  80. return (*mCurIter++).first;
  81. }
  82. }
  83. MAPPED_TYPE &getFirstData()
  84. {
  85. resetMap();
  86. return getNextData();
  87. }
  88. const INDEX_TYPE &getFirstKey()
  89. {
  90. resetMap();
  91. return getNextKey();
  92. }
  93. S32 getLength()
  94. {
  95. return mStlMap.size();
  96. }
  97. void addData(const INDEX_TYPE &index, MAPPED_TYPE pointed_to)
  98. {
  99. mStlMap.insert(stl_value_t(index, pointed_to));
  100. }
  101. void addData(const INDEX_TYPE &index)
  102. {
  103. mStlMap.insert(stl_value_t(index, dummy_data));
  104. }
  105. // if index doesn't exist, then insert a new node and return it
  106. MAPPED_TYPE &getData(const INDEX_TYPE &index)
  107. {
  108. std::pair<stl_iter_t, bool> res;
  109. res = mStlMap.insert(stl_value_t(index, dummy_data));
  110. return res.first->second;
  111. }
  112. // if index doesn't exist, then insert a new node, return it, and set b_new_entry to true
  113. MAPPED_TYPE &getData(const INDEX_TYPE &index, BOOL &b_new_entry)
  114. {
  115. std::pair<stl_iter_t, bool> res;
  116. res = mStlMap.insert(stl_value_t(index, dummy_data));
  117. b_new_entry = res.second;
  118. return res.first->second;
  119. }
  120. // If there, returns the data.
  121. // If not, returns NULL.
  122. // Never adds entries to the map.
  123. MAPPED_TYPE getIfThere(const INDEX_TYPE &index)
  124. {
  125. stl_iter_t iter;
  126. iter = mStlMap.find(index);
  127. if (iter == mStlMap.end())
  128. {
  129. return (MAPPED_TYPE)0;
  130. }
  131. else
  132. {
  133. return (*iter).second;
  134. }
  135. }
  136. // if index doesn't exist, then make a new node and return it
  137. MAPPED_TYPE &operator[](const INDEX_TYPE &index)
  138. {
  139. return getData(index);
  140. }
  141. // do a reverse look-up, return NULL if failed
  142. INDEX_TYPE reverseLookup(const MAPPED_TYPE data)
  143. {
  144. stl_iter_t iter;
  145. stl_iter_t end_iter;
  146. iter = mStlMap.begin();
  147. end_iter = mStlMap.end();
  148. while (iter != end_iter)
  149. {
  150. if ((*iter).second == data)
  151. return (*iter).first;
  152. iter++;
  153. }
  154. return (INDEX_TYPE)0;
  155. }
  156. BOOL removeData(const INDEX_TYPE &index)
  157. {
  158. mCurIter = mStlMap.find(index);
  159. if (mCurIter == mStlMap.end())
  160. {
  161. return FALSE;
  162. }
  163. else
  164. {
  165. stl_iter_t iter = mCurIter++; // incrament mCurIter to the next element
  166. mStlMap.erase(iter);
  167. return TRUE;
  168. }
  169. }
  170. // does this index exist?
  171. BOOL checkData(const INDEX_TYPE &index)
  172. {
  173. stl_iter_t iter;
  174. iter = mStlMap.find(index);
  175. if (iter == mStlMap.end())
  176. {
  177. return FALSE;
  178. }
  179. else
  180. {
  181. mCurIter = iter;
  182. return TRUE;
  183. }
  184. }
  185. BOOL deleteData(const INDEX_TYPE &index)
  186. {
  187. mCurIter = mStlMap.find(index);
  188. if (mCurIter == mStlMap.end())
  189. {
  190. return FALSE;
  191. }
  192. else
  193. {
  194. stl_iter_t iter = mCurIter++; // incrament mCurIter to the next element
  195. delete (*iter).second;
  196. mStlMap.erase(iter);
  197. return TRUE;
  198. }
  199. }
  200. void deleteAllData()
  201. {
  202. stl_iter_t iter;
  203. stl_iter_t end_iter;
  204. iter = mStlMap.begin();
  205. end_iter = mStlMap.end();
  206. while (iter != end_iter)
  207. {
  208. delete (*iter).second;
  209. iter++;
  210. }
  211. mStlMap.clear();
  212. mCurIter = mStlMap.end();
  213. }
  214. void removeAllData()
  215. {
  216. mStlMap.clear();
  217. }
  218. };
  219. #endif