update dev300-m58
[ooovba.git] / applied_patches / 0031-sal-strintern-speed.diff
blobed9eead2070f72995381f61ed9dc359ac241fe99
1 Index: sal/rtl/source/hash.cxx
2 ===================================================================
3 RCS file: /cvs/porting/sal/rtl/source/hash.cxx,v
4 retrieving revision 1.3
5 diff -u -r1.3 hash.cxx
6 --- sal/rtl/source/hash.cxx 19 Apr 2007 11:56:36 -0000 1.3
7 +++ sal/rtl/source/hash.cxx 15 Jun 2007 09:06:33 -0000
8 @@ -34,12 +34,15 @@
9 ************************************************************************/
11 // MARKER(update_precomp.py): autogen include statement, do not remove
12 -#include "precompiled_sal.hxx"
13 -#include "rtl/allocator.hxx"
14 +// #include "precompiled_sal.hxx"
16 #include "hash.h"
17 #include "strimp.h"
18 +#include <osl/diagnose.h>
20 +#if 0
22 +#include "rtl/allocator.hxx"
24 #include <hash_set>
26 @@ -121,3 +123,192 @@
28 pHash->erase(pString);
31 +#else
33 +// --------------------------- start here ---------------------------
35 +struct StringHashTableImpl {
36 + sal_uInt32 nEntries;
37 + sal_uInt32 nSize;
38 + rtl_uString **pData;
39 +};
41 +// Better / smaller / faster hash set ....
43 +// TODO: add bottom bit-set list terminator to string list
45 +static sal_uInt32
46 +getNextSize (sal_uInt32 nSize)
48 + // Sedgewick - Algorithms in C P577.
49 + static const sal_uInt32 nPrimes[] = { 1021, 2039, 4093, 8191, 16381, 32749,
50 + 65521, 131071,262139, 524287, 1048573,
51 + 2097143, 4194301, 8388593, 16777213,
52 + 33554393, 67108859, 134217689 };
53 + #define NUM_PRIMES (sizeof (nPrimes)/ sizeof (nPrimes[0]))
54 + for (int i = 0; i < NUM_PRIMES; i++)
55 + {
56 + if (nPrimes[i] > nSize)
57 + return nPrimes[i];
58 + }
59 + return nSize * 2;
62 +static sal_uInt32
63 +hashString (rtl_uString *pString)
65 + return (sal_uInt32) rtl_ustr_hashCode_WithLength (pString->buffer,
66 + pString->length);
69 +StringHashTable *
70 +rtl_str_hash_new (sal_uInt32 nSize)
72 + StringHashTable *pHash = (StringHashTable *)malloc (sizeof (StringHashTable));
74 + pHash->nEntries = 0;
75 + pHash->nSize = getNextSize (nSize);
76 + pHash->pData = (rtl_uString **) calloc (sizeof (rtl_uString *), pHash->nSize);
78 + return pHash;
81 +static void
82 +rtl_str_hash_insert_nonequal (StringHashTable *pHash,
83 + rtl_uString *pString)
85 + sal_uInt32 nHash = hashString (pString);
86 + sal_uInt32 n;
87 + rtl_uString *pHashStr;
89 + n = nHash % pHash->nSize;
90 + while ((pHashStr = pHash->pData[n]) != NULL) {
91 + n++;
92 + if (n >= pHash->nSize)
93 + n = 0;
94 + }
95 + pHash->pData[n] = pString;
98 +static void
99 +rtl_str_hash_resize (StringHashTable *pHash,
100 + sal_uInt32 nNewSize)
102 + sal_uInt32 i;
103 + StringHashTable *pNewHash;
105 + OSL_ASSERT (nNewSize > pHash->nEntries);
107 + pNewHash = rtl_str_hash_new (nNewSize);
109 + for (i = 0; i < pHash->nSize; i++)
111 + if (pHash->pData[i] != NULL)
112 + rtl_str_hash_insert_nonequal (pNewHash, pHash->pData[i]);
114 + pNewHash->nEntries = pHash->nEntries;
115 + free (pHash->pData);
116 + *pHash = *pNewHash;
117 + pNewHash->pData = NULL;
118 + rtl_str_hash_free (pNewHash);
121 +void
122 +rtl_str_hash_free (StringHashTable *pHash)
124 + if (!pHash)
125 + return;
126 + if (pHash->pData)
127 + free (pHash->pData);
128 + free (pHash);
131 +static int
132 +compareEqual (rtl_uString *pStringA, rtl_uString *pStringB)
134 + if (pStringA == pStringB)
135 + return 1;
136 + if (pStringA->length != pStringB->length)
137 + return 0;
138 + return !rtl_ustr_compare_WithLength( pStringA->buffer, pStringA->length,
139 + pStringB->buffer, pStringB->length);
142 +rtl_uString *
143 +rtl_str_hash_intern (StringHashTable *pHash,
144 + rtl_uString *pString,
145 + int can_return)
147 + sal_uInt32 nHash = hashString (pString);
148 + sal_uInt32 n;
149 + rtl_uString *pHashStr;
151 + // Should we resize ?
152 + if (pHash->nEntries >= pHash->nSize/2)
153 + rtl_str_hash_resize (pHash, getNextSize(pHash->nSize));
155 + n = nHash % pHash->nSize;
156 + while ((pHashStr = pHash->pData[n]) != NULL) {
157 + if (compareEqual (pHashStr, pString))
159 + rtl_uString_acquire (pHashStr);
160 + return pHashStr;
162 + n++;
163 + if (n >= pHash->nSize)
164 + n = 0;
167 + if (!can_return)
169 + rtl_uString *pCopy = NULL;
170 + rtl_uString_newFromString( &pCopy, pString );
171 + pString = pCopy;
172 + if (!pString)
173 + return NULL;
176 + if (!SAL_STRING_IS_STATIC (pString))
177 + pString->refCount |= SAL_STRING_INTERN_FLAG;
178 + pHash->pData[n] = pString;
179 + pHash->nEntries++;
181 + return pString;
184 +void
185 +rtl_str_hash_remove (StringHashTable *pHash,
186 + rtl_uString *pString)
188 + sal_uInt32 n;
189 + sal_uInt32 nHash = hashString (pString);
190 + rtl_uString *pHashStr;
192 + n = nHash % pHash->nSize;
193 + while ((pHashStr = pHash->pData[n]) != NULL) {
194 + if (compareEqual (pHashStr, pString))
195 + break;
196 + n++;
197 + if (n >= pHash->nSize)
198 + n = 0;
200 + OSL_ASSERT (pHash->pData[n] != 0);
201 + if (pHash->pData[n] == NULL)
202 + return;
204 + pHash->pData[n++] = NULL;
205 + pHash->nEntries--;
207 + while ((pHashStr = pHash->pData[n]) != NULL) {
208 + pHash->pData[n] = NULL;
209 + // FIXME: rather unsophisticated and N^2 in chain-length, but robust.
210 + rtl_str_hash_insert_nonequal (pHash, pHashStr);
211 + n++;
212 + if (n >= pHash->nSize)
213 + n = 0;
215 + // FIXME: Should we down-size ?
218 +#endif