PageRenderTime 35ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/llstringtable.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 217 lines | 159 code | 25 blank | 33 comment | 16 complexity | 135d0880e602b579002234632bc23367 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llstringtable.h
  3. * @brief The LLStringTable class provides a _fast_ method for finding
  4. * unique copies of strings.
  5. *
  6. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #ifndef LL_STRING_TABLE_H
  28. #define LL_STRING_TABLE_H
  29. #include "lldefs.h"
  30. #include "llformat.h"
  31. #include "llstl.h"
  32. #include <list>
  33. #include <set>
  34. #if LL_WINDOWS
  35. # if (_MSC_VER >= 1300 && _MSC_VER < 1400)
  36. # define STRING_TABLE_HASH_MAP 1
  37. # endif
  38. #else
  39. //# define STRING_TABLE_HASH_MAP 1
  40. #endif
  41. #if STRING_TABLE_HASH_MAP
  42. # if LL_WINDOWS
  43. # include <hash_map>
  44. # else
  45. # include <ext/hash_map>
  46. # endif
  47. #endif
  48. const U32 MAX_STRINGS_LENGTH = 256;
  49. class LL_COMMON_API LLStringTableEntry
  50. {
  51. public:
  52. LLStringTableEntry(const char *str);
  53. ~LLStringTableEntry();
  54. void incCount() { mCount++; }
  55. BOOL decCount() { return --mCount; }
  56. char *mString;
  57. S32 mCount;
  58. };
  59. class LL_COMMON_API LLStringTable
  60. {
  61. public:
  62. LLStringTable(int tablesize);
  63. ~LLStringTable();
  64. char *checkString(const char *str);
  65. char *checkString(const std::string& str);
  66. LLStringTableEntry *checkStringEntry(const char *str);
  67. LLStringTableEntry *checkStringEntry(const std::string& str);
  68. char *addString(const char *str);
  69. char *addString(const std::string& str);
  70. LLStringTableEntry *addStringEntry(const char *str);
  71. LLStringTableEntry *addStringEntry(const std::string& str);
  72. void removeString(const char *str);
  73. S32 mMaxEntries;
  74. S32 mUniqueEntries;
  75. #if STRING_TABLE_HASH_MAP
  76. #if LL_WINDOWS
  77. typedef std::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
  78. #else
  79. typedef __gnu_cxx::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
  80. #endif
  81. string_hash_t mStringHash;
  82. #else
  83. typedef std::list<LLStringTableEntry *> string_list_t;
  84. typedef string_list_t * string_list_ptr_t;
  85. string_list_ptr_t *mStringList;
  86. #endif
  87. };
  88. extern LL_COMMON_API LLStringTable gStringTable;
  89. //============================================================================
  90. // This class is designed to be used locally,
  91. // e.g. as a member of an LLXmlTree
  92. // Strings can be inserted only, then quickly looked up
  93. typedef const std::string* LLStdStringHandle;
  94. class LL_COMMON_API LLStdStringTable
  95. {
  96. public:
  97. LLStdStringTable(S32 tablesize = 0)
  98. {
  99. if (tablesize == 0)
  100. {
  101. tablesize = 256; // default
  102. }
  103. // Make sure tablesize is power of 2
  104. for (S32 i = 31; i>0; i--)
  105. {
  106. if (tablesize & (1<<i))
  107. {
  108. if (tablesize >= (3<<(i-1)))
  109. tablesize = (1<<(i+1));
  110. else
  111. tablesize = (1<<i);
  112. break;
  113. }
  114. }
  115. mTableSize = tablesize;
  116. mStringList = new string_set_t[tablesize];
  117. }
  118. ~LLStdStringTable()
  119. {
  120. cleanup();
  121. delete[] mStringList;
  122. }
  123. void cleanup()
  124. {
  125. // remove strings
  126. for (S32 i = 0; i<mTableSize; i++)
  127. {
  128. string_set_t& stringset = mStringList[i];
  129. for (string_set_t::iterator iter = stringset.begin(); iter != stringset.end(); iter++)
  130. {
  131. delete *iter;
  132. }
  133. stringset.clear();
  134. }
  135. }
  136. LLStdStringHandle lookup(const std::string& s)
  137. {
  138. U32 hashval = makehash(s);
  139. return lookup(hashval, s);
  140. }
  141. LLStdStringHandle checkString(const std::string& s)
  142. {
  143. U32 hashval = makehash(s);
  144. return lookup(hashval, s);
  145. }
  146. LLStdStringHandle insert(const std::string& s)
  147. {
  148. U32 hashval = makehash(s);
  149. LLStdStringHandle result = lookup(hashval, s);
  150. if (result == NULL)
  151. {
  152. result = new std::string(s);
  153. mStringList[hashval].insert(result);
  154. }
  155. return result;
  156. }
  157. LLStdStringHandle addString(const std::string& s)
  158. {
  159. return insert(s);
  160. }
  161. private:
  162. U32 makehash(const std::string& s)
  163. {
  164. S32 len = (S32)s.size();
  165. const char* c = s.c_str();
  166. U32 hashval = 0;
  167. for (S32 i=0; i<len; i++)
  168. {
  169. hashval = ((hashval<<5) + hashval) + *c++;
  170. }
  171. return hashval & (mTableSize-1);
  172. }
  173. LLStdStringHandle lookup(U32 hashval, const std::string& s)
  174. {
  175. string_set_t& stringset = mStringList[hashval];
  176. LLStdStringHandle handle = &s;
  177. string_set_t::iterator iter = stringset.find(handle); // compares actual strings
  178. if (iter != stringset.end())
  179. {
  180. return *iter;
  181. }
  182. else
  183. {
  184. return NULL;
  185. }
  186. }
  187. private:
  188. S32 mTableSize;
  189. typedef std::set<LLStdStringHandle, compare_pointer_contents<std::string> > string_set_t;
  190. string_set_t* mStringList; // [mTableSize]
  191. };
  192. #endif