llstringtable.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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=viewergpl$
  7. *
  8. * Copyright (c) 2001-2009, Linden Research, Inc.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #ifndef LL_STRING_TABLE_H
  34. #define LL_STRING_TABLE_H
  35. #include <list>
  36. #include <set>
  37. #include "hbfastmap.h"
  38. #include "hbxxh.h"
  39. constexpr U32 MAX_STRINGS_LENGTH = 256;
  40. ///////////////////////////////////////////////////////////////////////////////
  41. // LLStringTableEntry class
  42. ///////////////////////////////////////////////////////////////////////////////
  43. class LLStringTableEntry
  44. {
  45. public:
  46. LLStringTableEntry(const char* str);
  47. ~LLStringTableEntry();
  48. LL_INLINE void incCount() { ++mCount; }
  49. LL_INLINE bool decCount() { return --mCount != 0; }
  50. public:
  51. char* mString;
  52. S32 mCount;
  53. };
  54. ///////////////////////////////////////////////////////////////////////////////
  55. // LLStringTable class
  56. ///////////////////////////////////////////////////////////////////////////////
  57. class LLStringTable
  58. {
  59. protected:
  60. LOG_CLASS(LLStringTable);
  61. public:
  62. LLStringTable(S32 tablesize);
  63. ~LLStringTable();
  64. LL_INLINE char* checkString(const char* str)
  65. {
  66. LLStringTableEntry* entry = checkStringEntry(str);
  67. return entry ? entry->mString : NULL;
  68. }
  69. LL_INLINE char* checkString(const std::string& str)
  70. {
  71. return checkString(str.c_str());
  72. }
  73. LLStringTableEntry* checkStringEntry(const char* str);
  74. LL_INLINE LLStringTableEntry* checkStringEntry(const std::string& str)
  75. {
  76. return checkStringEntry(str.c_str());
  77. }
  78. LLStringTableEntry* addStringEntry(const char* str);
  79. LL_INLINE LLStringTableEntry* addStringEntry(const std::string& str)
  80. {
  81. return addStringEntry(str.c_str());
  82. }
  83. LL_INLINE char* addString(const char* str)
  84. {
  85. LLStringTableEntry* entry = addStringEntry(str);
  86. return entry ? entry->mString : NULL;
  87. }
  88. LL_INLINE char* addString(const std::string& str)
  89. {
  90. // RN: safe to use temporary c_str since string is copied
  91. return addString(str.c_str());
  92. }
  93. void removeString(const char* str);
  94. public:
  95. U32 mMaxEntries;
  96. U32 mUniqueEntries;
  97. typedef std::list<LLStringTableEntry*> string_list_t;
  98. typedef string_list_t* string_list_ptr_t;
  99. string_list_ptr_t* mStringList;
  100. };
  101. extern LLStringTable gStringTable;
  102. ///////////////////////////////////////////////////////////////////////////////
  103. // LLStdStringTable class designed to be used locally, e.g. as a member of an
  104. // LLXmlTree. Strings can be inserted only, then quickly looked up
  105. ///////////////////////////////////////////////////////////////////////////////
  106. typedef const std::string* LLStdStringHandle;
  107. class LLStdStringTable
  108. {
  109. protected:
  110. LOG_CLASS(LLStdStringTable);
  111. public:
  112. LLStdStringTable(S32 tablesize = 0);
  113. LL_INLINE ~LLStdStringTable()
  114. {
  115. cleanup();
  116. delete[] mStringList;
  117. }
  118. void cleanup();
  119. LL_INLINE LLStdStringHandle lookup(const std::string& s)
  120. {
  121. U32 hashval = makehash(s);
  122. return lookup(hashval, s);
  123. }
  124. LL_INLINE LLStdStringHandle checkString(const std::string& s)
  125. {
  126. U32 hashval = makehash(s);
  127. return lookup(hashval, s);
  128. }
  129. LL_INLINE LLStdStringHandle insert(const std::string& s)
  130. {
  131. U32 hashval = makehash(s);
  132. LLStdStringHandle result = lookup(hashval, s);
  133. if (!result)
  134. {
  135. result = new std::string(s);
  136. mStringList[hashval].insert(result);
  137. }
  138. return result;
  139. }
  140. LL_INLINE LLStdStringHandle addString(const std::string& s)
  141. {
  142. return insert(s);
  143. }
  144. private:
  145. LL_INLINE U32 makehash(const std::string& s)
  146. {
  147. if (s.empty())
  148. {
  149. return 0;
  150. }
  151. return digest64to32(HBXXH64::digest(s)) & (mTableSize - 1);
  152. }
  153. LL_INLINE LLStdStringHandle lookup(U32 hashval, const std::string& s)
  154. {
  155. string_set_t& stringset = mStringList[hashval];
  156. LLStdStringHandle handle = &s;
  157. // Compares actual strings:
  158. string_set_t::iterator iter = stringset.find(handle);
  159. return iter != stringset.end() ? *iter : NULL;
  160. }
  161. // Used to compare the contents of two pointers (e.g. std::string*)
  162. template <typename T>
  163. struct compare_pointer_contents
  164. {
  165. typedef const T* Tptr;
  166. LL_INLINE bool operator()(const Tptr& a, const Tptr& b) const
  167. {
  168. return *a < *b;
  169. }
  170. };
  171. private:
  172. typedef std::set<LLStdStringHandle,
  173. compare_pointer_contents<std::string> > string_set_t;
  174. string_set_t* mStringList; // [mTableSize]
  175. U32 mTableSize;
  176. };
  177. ///////////////////////////////////////////////////////////////////////////////
  178. // LLStaticHashedString class, mainly used by shaders for uniforms hashing
  179. ///////////////////////////////////////////////////////////////////////////////
  180. class LLStaticHashedString
  181. {
  182. public:
  183. LLStaticHashedString(const std::string& s)
  184. : mString(s)
  185. {
  186. mStringHash = makehash(s);
  187. }
  188. LL_INLINE const std::string& String() const { return mString; }
  189. LL_INLINE size_t Hash() const { return mStringHash; }
  190. LL_INLINE bool operator==(const LLStaticHashedString& b) const
  191. {
  192. return Hash() == b.Hash();
  193. }
  194. protected:
  195. LL_INLINE size_t makehash(const std::string& s)
  196. {
  197. return s.empty() ? std::string::npos : (size_t)HBXXH64::digest(s);
  198. }
  199. protected:
  200. std::string mString;
  201. size_t mStringHash;
  202. };
  203. struct LLStaticStringHasher
  204. {
  205. enum { bucket_size = 8 };
  206. LL_INLINE size_t operator()(const LLStaticHashedString& key_value) const noexcept
  207. {
  208. return key_value.Hash();
  209. }
  210. LL_INLINE bool operator()(const LLStaticHashedString& left,
  211. const LLStaticHashedString& right) const noexcept
  212. {
  213. return left.Hash() < right.Hash();
  214. }
  215. };
  216. template<typename MappedObject>
  217. class LLStaticStringTable
  218. : public safe_hmap<LLStaticHashedString, MappedObject, LLStaticStringHasher>
  219. {
  220. };
  221. #endif