PageRenderTime 28ms CodeModel.GetById 14ms app.highlight 10ms RepoModel.GetById 1ms 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
  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
 28#ifndef LL_STRING_TABLE_H
 29#define LL_STRING_TABLE_H
 30
 31#include "lldefs.h"
 32#include "llformat.h"
 33#include "llstl.h"
 34#include <list>
 35#include <set>
 36
 37#if LL_WINDOWS
 38# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
 39#  define STRING_TABLE_HASH_MAP 1
 40# endif
 41#else
 42//# define STRING_TABLE_HASH_MAP 1
 43#endif
 44
 45#if STRING_TABLE_HASH_MAP
 46# if LL_WINDOWS
 47#  include <hash_map>
 48# else
 49#  include <ext/hash_map>
 50# endif
 51#endif
 52
 53const U32 MAX_STRINGS_LENGTH = 256;
 54
 55class LL_COMMON_API LLStringTableEntry
 56{
 57public:
 58	LLStringTableEntry(const char *str);
 59	~LLStringTableEntry();
 60
 61	void incCount()		{ mCount++; }
 62	BOOL decCount()		{ return --mCount; }
 63
 64	char *mString;
 65	S32  mCount;
 66};
 67
 68class LL_COMMON_API LLStringTable
 69{
 70public:
 71	LLStringTable(int tablesize);
 72	~LLStringTable();
 73
 74	char *checkString(const char *str);
 75	char *checkString(const std::string& str);
 76	LLStringTableEntry *checkStringEntry(const char *str);
 77	LLStringTableEntry *checkStringEntry(const std::string& str);
 78
 79	char *addString(const char *str);
 80	char *addString(const std::string& str);
 81	LLStringTableEntry *addStringEntry(const char *str);
 82	LLStringTableEntry *addStringEntry(const std::string& str);
 83	void  removeString(const char *str);
 84
 85	S32 mMaxEntries;
 86	S32 mUniqueEntries;
 87	
 88#if STRING_TABLE_HASH_MAP
 89#if LL_WINDOWS
 90	typedef std::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
 91#else
 92	typedef __gnu_cxx::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
 93#endif
 94	string_hash_t mStringHash;
 95#else
 96	typedef std::list<LLStringTableEntry *> string_list_t;
 97	typedef string_list_t * string_list_ptr_t;
 98	string_list_ptr_t	*mStringList;
 99#endif	
100};
101
102extern LL_COMMON_API LLStringTable gStringTable;
103
104//============================================================================
105
106// This class is designed to be used locally,
107// e.g. as a member of an LLXmlTree
108// Strings can be inserted only, then quickly looked up
109
110typedef const std::string* LLStdStringHandle;
111
112class LL_COMMON_API LLStdStringTable
113{
114public:
115	LLStdStringTable(S32 tablesize = 0)
116	{
117		if (tablesize == 0)
118		{
119			tablesize = 256; // default
120		}
121		// Make sure tablesize is power of 2
122		for (S32 i = 31; i>0; i--)
123		{
124			if (tablesize & (1<<i))
125			{
126				if (tablesize >= (3<<(i-1)))
127					tablesize = (1<<(i+1));
128				else
129					tablesize = (1<<i);
130				break;
131			}
132		}
133		mTableSize = tablesize;
134		mStringList = new string_set_t[tablesize];
135	}
136	~LLStdStringTable()
137	{
138		cleanup();
139		delete[] mStringList;
140	}
141	void cleanup()
142	{
143		// remove strings
144		for (S32 i = 0; i<mTableSize; i++)
145		{
146			string_set_t& stringset = mStringList[i];
147			for (string_set_t::iterator iter = stringset.begin(); iter != stringset.end(); iter++)
148			{
149				delete *iter;
150			}
151			stringset.clear();
152		}
153	}
154
155	LLStdStringHandle lookup(const std::string& s)
156	{
157		U32 hashval = makehash(s);
158		return lookup(hashval, s);
159	}
160	
161	LLStdStringHandle checkString(const std::string& s)
162	{
163		U32 hashval = makehash(s);
164		return lookup(hashval, s);
165	}
166
167	LLStdStringHandle insert(const std::string& s)
168	{
169		U32 hashval = makehash(s);
170		LLStdStringHandle result = lookup(hashval, s);
171		if (result == NULL)
172		{
173			result = new std::string(s);
174			mStringList[hashval].insert(result);
175		}
176		return result;
177	}
178	LLStdStringHandle addString(const std::string& s)
179	{
180		return insert(s);
181	}
182	
183private:
184	U32 makehash(const std::string& s)
185	{
186		S32 len = (S32)s.size();
187		const char* c = s.c_str();
188		U32 hashval = 0;
189		for (S32 i=0; i<len; i++)
190		{
191			hashval = ((hashval<<5) + hashval) + *c++;
192		}
193		return hashval & (mTableSize-1);
194	}
195	LLStdStringHandle lookup(U32 hashval, const std::string& s)
196	{
197		string_set_t& stringset = mStringList[hashval];
198		LLStdStringHandle handle = &s;
199		string_set_t::iterator iter = stringset.find(handle); // compares actual strings
200		if (iter != stringset.end())
201		{
202			return *iter;
203		}
204		else
205		{
206			return NULL;
207		}
208	}
209	
210private:
211	S32 mTableSize;
212	typedef std::set<LLStdStringHandle, compare_pointer_contents<std::string> > string_set_t;
213	string_set_t* mStringList; // [mTableSize]
214};
215
216
217#endif