summaryrefslogtreecommitdiff
path: root/indra/llcommon/llstringtable.h
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
committerJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
commit420b91db29485df39fd6e724e782c449158811cb (patch)
treeb471a94563af914d3ed3edd3e856d21cb1b69945 /indra/llcommon/llstringtable.h
Print done when done.
Diffstat (limited to 'indra/llcommon/llstringtable.h')
-rw-r--r--indra/llcommon/llstringtable.h208
1 files changed, 208 insertions, 0 deletions
diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h
new file mode 100644
index 0000000000..ad428ce565
--- /dev/null
+++ b/indra/llcommon/llstringtable.h
@@ -0,0 +1,208 @@
+/**
+ * @file llstringtable.h
+ * @brief The LLStringTable class provides a _fast_ method for finding
+ * unique copies of strings.
+ *
+ * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_STRING_TABLE_H
+#define LL_STRING_TABLE_H
+
+#include "llstl.h"
+#include <list>
+#include <set>
+
+#if LL_WINDOWS
+# if (_MSC_VER >= 1300)
+# define STRING_TABLE_HASH_MAP 1
+# pragma warning(disable : 4996)
+# endif
+#else
+//# define STRING_TABLE_HASH_MAP 1
+#endif
+
+#if STRING_TABLE_HASH_MAP
+#include <hash_map>
+#endif
+
+// string_table.h
+// LLStringTable class header file
+// Provides a _fast_ method for finding unique copies of strings
+//
+// Copyright 2001-2002, Linden Research, Inc.
+
+const U32 MAX_STRINGS_LENGTH = 256;
+
+class LLStringTableEntry
+{
+public:
+ LLStringTableEntry(const char *str)
+ : mString(NULL), mCount(1)
+ {
+ // Copy string
+ U32 length = (U32)strlen(str) + 1; /*Flawfinder: ignore*/
+ length = llmin(length, MAX_STRINGS_LENGTH);
+ mString = new char[length];
+ strncpy(mString, str, length); /*Flawfinder: ignore*/
+ mString[length - 1] = 0;
+ }
+ ~LLStringTableEntry()
+ {
+ delete [] mString;
+ mCount = 0;
+ }
+ void incCount() { mCount++; }
+ BOOL decCount() { return --mCount; }
+
+ char *mString;
+ S32 mCount;
+};
+
+class LLStringTable
+{
+public:
+ LLStringTable(int tablesize);
+ ~LLStringTable();
+
+ char *checkString(const char *str);
+ char *checkString(const std::string& str);
+ LLStringTableEntry *checkStringEntry(const char *str);
+ LLStringTableEntry *checkStringEntry(const std::string& str);
+
+ char *addString(const char *str);
+ char *addString(const std::string& str);
+ LLStringTableEntry *addStringEntry(const char *str);
+ LLStringTableEntry *addStringEntry(const std::string& str);
+ void removeString(const char *str);
+
+ S32 mMaxEntries;
+ S32 mUniqueEntries;
+
+#if STRING_TABLE_HASH_MAP
+ typedef std::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
+ string_hash_t mStringHash;
+#else
+ typedef std::list<LLStringTableEntry *> string_list_t;
+ typedef string_list_t * string_list_ptr_t;
+ string_list_ptr_t *mStringList;
+#endif
+};
+
+extern LLStringTable gStringTable;
+
+//============================================================================
+
+// This class is designed to be used locally,
+// e.g. as a member of an LLXmlTree
+// Strings can be inserted only, then quickly looked up
+
+typedef const std::string* LLStdStringHandle;
+
+class LLStdStringTable
+{
+public:
+ LLStdStringTable(S32 tablesize = 0)
+ {
+ if (tablesize == 0)
+ {
+ tablesize = 256; // default
+ }
+ // Make sure tablesize is power of 2
+ for (S32 i = 31; i>0; i--)
+ {
+ if (tablesize & (1<<i))
+ {
+ if (tablesize >= (3<<(i-1)))
+ tablesize = (1<<(i+1));
+ else
+ tablesize = (1<<i);
+ break;
+ }
+ }
+ mTableSize = tablesize;
+ mStringList = new string_set_t[tablesize];
+ }
+ ~LLStdStringTable()
+ {
+ cleanup();
+ delete[] mStringList;
+ }
+ void cleanup()
+ {
+ // remove strings
+ for (S32 i = 0; i<mTableSize; i++)
+ {
+ string_set_t& stringset = mStringList[i];
+ for (string_set_t::iterator iter = stringset.begin(); iter != stringset.end(); iter++)
+ {
+ delete *iter;
+ }
+ stringset.clear();
+ }
+ }
+
+ LLStdStringHandle lookup(const std::string& s)
+ {
+ U32 hashval = makehash(s);
+ return lookup(hashval, s);
+ }
+
+ LLStdStringHandle checkString(const std::string& s)
+ {
+ U32 hashval = makehash(s);
+ return lookup(hashval, s);
+ }
+
+ LLStdStringHandle insert(const std::string& s)
+ {
+ U32 hashval = makehash(s);
+ LLStdStringHandle result = lookup(hashval, s);
+ if (result == NULL)
+ {
+ result = new std::string(s);
+ mStringList[hashval].insert(result);
+ }
+ return result;
+ }
+ LLStdStringHandle addString(const std::string& s)
+ {
+ return insert(s);
+ }
+
+private:
+ U32 makehash(const std::string& s)
+ {
+ S32 len = (S32)s.size();
+ const char* c = s.c_str();
+ U32 hashval = 0;
+ for (S32 i=0; i<len; i++)
+ {
+ hashval = ((hashval<<5) + hashval) + *c++;
+ }
+ return hashval & (mTableSize-1);
+ }
+ LLStdStringHandle lookup(U32 hashval, const std::string& s)
+ {
+ string_set_t& stringset = mStringList[hashval];
+ LLStdStringHandle handle = &s;
+ string_set_t::iterator iter = stringset.find(handle); // compares actual strings
+ if (iter != stringset.end())
+ {
+ return *iter;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+private:
+ S32 mTableSize;
+ typedef std::set<LLStdStringHandle, compare_pointer_contents<std::string> > string_set_t;
+ string_set_t* mStringList; // [mTableSize]
+};
+
+
+#endif