llstringtable.h

Go to the documentation of this file.
00001 
00033 #ifndef LL_STRING_TABLE_H
00034 #define LL_STRING_TABLE_H
00035 
00036 #include "lldefs.h"
00037 #include "llformat.h"
00038 #include "llstl.h"
00039 #include <list>
00040 #include <set>
00041 
00042 #if LL_WINDOWS
00043 # if (_MSC_VER >= 1300 && _MSC_VER < 1400)
00044 #  define STRING_TABLE_HASH_MAP 1
00045 # endif
00046 #else
00047 //# define STRING_TABLE_HASH_MAP 1
00048 #endif
00049 
00050 #if LL_WINDOWS
00051 #include <hash_map>
00052 #else
00053 #include <ext/hash_map>
00054 #endif
00055 
00056 const U32 MAX_STRINGS_LENGTH = 256;
00057 
00058 class LLStringTableEntry
00059 {
00060 public:
00061         LLStringTableEntry(const char *str)
00062                 : mString(NULL), mCount(1)
00063         {
00064                 // Copy string
00065                 U32 length = (U32)strlen(str) + 1;       /*Flawfinder: ignore*/
00066                 length = llmin(length, MAX_STRINGS_LENGTH);
00067                 mString = new char[length];
00068                 strncpy(mString, str, length);   /*Flawfinder: ignore*/
00069                 mString[length - 1] = 0;
00070         }
00071         ~LLStringTableEntry()
00072         {
00073                 delete [] mString;
00074                 mCount = 0;
00075         }
00076         void incCount()         { mCount++; }
00077         BOOL decCount()         { return --mCount; }
00078 
00079         char *mString;
00080         S32  mCount;
00081 };
00082 
00083 class LLStringTable
00084 {
00085 public:
00086         LLStringTable(int tablesize);
00087         ~LLStringTable();
00088 
00089         char *checkString(const char *str);
00090         char *checkString(const std::string& str);
00091         LLStringTableEntry *checkStringEntry(const char *str);
00092         LLStringTableEntry *checkStringEntry(const std::string& str);
00093 
00094         char *addString(const char *str);
00095         char *addString(const std::string& str);
00096         LLStringTableEntry *addStringEntry(const char *str);
00097         LLStringTableEntry *addStringEntry(const std::string& str);
00098         void  removeString(const char *str);
00099 
00100         S32 mMaxEntries;
00101         S32 mUniqueEntries;
00102         
00103 #if STRING_TABLE_HASH_MAP
00104 #if LL_WINDOWS
00105         typedef std::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
00106 #else
00107         typedef __gnu_cxx::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
00108 #endif
00109         string_hash_t mStringHash;
00110 #else
00111         typedef std::list<LLStringTableEntry *> string_list_t;
00112         typedef string_list_t * string_list_ptr_t;
00113         string_list_ptr_t       *mStringList;
00114 #endif  
00115 };
00116 
00117 extern LLStringTable gStringTable;
00118 
00119 //============================================================================
00120 
00121 // This class is designed to be used locally,
00122 // e.g. as a member of an LLXmlTree
00123 // Strings can be inserted only, then quickly looked up
00124 
00125 typedef const std::string* LLStdStringHandle;
00126 
00127 class LLStdStringTable
00128 {
00129 public:
00130         LLStdStringTable(S32 tablesize = 0)
00131         {
00132                 if (tablesize == 0)
00133                 {
00134                         tablesize = 256; // default
00135                 }
00136                 // Make sure tablesize is power of 2
00137                 for (S32 i = 31; i>0; i--)
00138                 {
00139                         if (tablesize & (1<<i))
00140                         {
00141                                 if (tablesize >= (3<<(i-1)))
00142                                         tablesize = (1<<(i+1));
00143                                 else
00144                                         tablesize = (1<<i);
00145                                 break;
00146                         }
00147                 }
00148                 mTableSize = tablesize;
00149                 mStringList = new string_set_t[tablesize];
00150         }
00151         ~LLStdStringTable()
00152         {
00153                 cleanup();
00154                 delete[] mStringList;
00155         }
00156         void cleanup()
00157         {
00158                 // remove strings
00159                 for (S32 i = 0; i<mTableSize; i++)
00160                 {
00161                         string_set_t& stringset = mStringList[i];
00162                         for (string_set_t::iterator iter = stringset.begin(); iter != stringset.end(); iter++)
00163                         {
00164                                 delete *iter;
00165                         }
00166                         stringset.clear();
00167                 }
00168         }
00169 
00170         LLStdStringHandle lookup(const std::string& s)
00171         {
00172                 U32 hashval = makehash(s);
00173                 return lookup(hashval, s);
00174         }
00175         
00176         LLStdStringHandle checkString(const std::string& s)
00177         {
00178                 U32 hashval = makehash(s);
00179                 return lookup(hashval, s);
00180         }
00181 
00182         LLStdStringHandle insert(const std::string& s)
00183         {
00184                 U32 hashval = makehash(s);
00185                 LLStdStringHandle result = lookup(hashval, s);
00186                 if (result == NULL)
00187                 {
00188                         result = new std::string(s);
00189                         mStringList[hashval].insert(result);
00190                 }
00191                 return result;
00192         }
00193         LLStdStringHandle addString(const std::string& s)
00194         {
00195                 return insert(s);
00196         }
00197         
00198 private:
00199         U32 makehash(const std::string& s)
00200         {
00201                 S32 len = (S32)s.size();
00202                 const char* c = s.c_str();
00203                 U32 hashval = 0;
00204                 for (S32 i=0; i<len; i++)
00205                 {
00206                         hashval = ((hashval<<5) + hashval) + *c++;
00207                 }
00208                 return hashval & (mTableSize-1);
00209         }
00210         LLStdStringHandle lookup(U32 hashval, const std::string& s)
00211         {
00212                 string_set_t& stringset = mStringList[hashval];
00213                 LLStdStringHandle handle = &s;
00214                 string_set_t::iterator iter = stringset.find(handle); // compares actual strings
00215                 if (iter != stringset.end())
00216                 {
00217                         return *iter;
00218                 }
00219                 else
00220                 {
00221                         return NULL;
00222                 }
00223         }
00224         
00225 private:
00226         S32 mTableSize;
00227         typedef std::set<LLStdStringHandle, compare_pointer_contents<std::string> > string_set_t;
00228         string_set_t* mStringList; // [mTableSize]
00229 };
00230 
00231 
00232 #endif

Generated on Fri May 16 08:32:09 2008 for SecondLife by  doxygen 1.5.5