Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(439)

Side by Side Diff: third_party/WebKit/Source/wtf/text/AtomicStringTable.cpp

Issue 2110813003: Move all the AtomicString table into AtomicStringTable. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix comments. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "wtf/text/AtomicStringTable.h" 5 #include "wtf/text/AtomicStringTable.h"
6 6
7 #include "wtf/text/StringHash.h"
8 #include "wtf/text/UTF8.h"
9
7 namespace WTF { 10 namespace WTF {
8 11
12 using namespace Unicode;
13
9 AtomicStringTable::AtomicStringTable() 14 AtomicStringTable::AtomicStringTable()
10 { 15 {
11 for (StringImpl* string : StringImpl::allStaticStrings().values()) 16 for (StringImpl* string : StringImpl::allStaticStrings().values())
12 addStringImpl(string); 17 add(string);
13 } 18 }
14 19
15 AtomicStringTable::~AtomicStringTable() 20 AtomicStringTable::~AtomicStringTable()
16 { 21 {
17 for (StringImpl* string : m_table) { 22 for (StringImpl* string : m_table) {
18 if (!string->isStatic()) { 23 if (!string->isStatic()) {
19 DCHECK(string->isAtomic()); 24 DCHECK(string->isAtomic());
20 string->setIsAtomic(false); 25 string->setIsAtomic(false);
21 } 26 }
22 } 27 }
23 } 28 }
24 29
25 StringImpl* AtomicStringTable::addStringImpl(StringImpl* string) 30 void AtomicStringTable::reserveCapacity(unsigned size)
31 {
32 m_table.reserveCapacityForSize(size);
33 }
34
35 template<typename T, typename HashTranslator>
36 PassRefPtr<StringImpl> AtomicStringTable::addToStringTable(const T& value)
37 {
38 HashSet<StringImpl*>::AddResult addResult = m_table.addWithTranslator<HashTr anslator>(value);
39
40 // If the string is newly-translated, then we need to adopt it.
41 // The boolean in the pair tells us if that is so.
42 return addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult. storedValue;
43 }
44
45 template<typename CharacterType>
46 struct HashTranslatorCharBuffer {
47 const CharacterType* s;
48 unsigned length;
49 };
50
51 typedef HashTranslatorCharBuffer<UChar> UCharBuffer;
52 struct UCharBufferTranslator {
53 static unsigned hash(const UCharBuffer& buf)
54 {
55 return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length);
56 }
57
58 static bool equal(StringImpl* const& str, const UCharBuffer& buf)
59 {
60 return WTF::equal(str, buf.s, buf.length);
61 }
62
63 static void translate(StringImpl*& location, const UCharBuffer& buf, unsigne d hash)
64 {
65 location = StringImpl::create8BitIfPossible(buf.s, buf.length).leakRef() ;
66 location->setHash(hash);
67 location->setIsAtomic(true);
68 }
69 };
70
71 template<typename CharacterType>
72 struct HashAndCharacters {
73 unsigned hash;
74 const CharacterType* characters;
75 unsigned length;
76 };
77
78 template<typename CharacterType>
79 struct HashAndCharactersTranslator {
80 static unsigned hash(const HashAndCharacters<CharacterType>& buffer)
81 {
82 DCHECK(buffer.hash == StringHasher::computeHashAndMaskTop8Bits(buffer.ch aracters, buffer.length));
83 return buffer.hash;
84 }
85
86 static bool equal(StringImpl* const& string, const HashAndCharacters<Charact erType>& buffer)
87 {
88 return WTF::equal(string, buffer.characters, buffer.length);
89 }
90
91 static void translate(StringImpl*& location, const HashAndCharacters<Charact erType>& buffer, unsigned hash)
92 {
93 location = StringImpl::create(buffer.characters, buffer.length).leakRef( );
94 location->setHash(hash);
95 location->setIsAtomic(true);
96 }
97 };
98
99 struct HashAndUTF8Characters {
100 unsigned hash;
101 const char* characters;
102 unsigned length;
103 unsigned utf16Length;
104 };
105
106 struct HashAndUTF8CharactersTranslator {
107 static unsigned hash(const HashAndUTF8Characters& buffer)
108 {
109 return buffer.hash;
110 }
111
112 static bool equal(StringImpl* const& string, const HashAndUTF8Characters& bu ffer)
113 {
114 if (buffer.utf16Length != string->length())
115 return false;
116
117 // If buffer contains only ASCII characters UTF-8 and UTF16 length are t he same.
118 if (buffer.utf16Length != buffer.length) {
119 if (string->is8Bit()) {
120 const LChar* characters8 = string->characters8();
121 return equalLatin1WithUTF8(characters8, characters8 + string->le ngth(), buffer.characters, buffer.characters + buffer.length);
122 }
123 const UChar* characters16 = string->characters16();
124 return equalUTF16WithUTF8(characters16, characters16 + string->lengt h(), buffer.characters, buffer.characters + buffer.length);
125 }
126
127 if (string->is8Bit()) {
128 const LChar* stringCharacters = string->characters8();
129
130 for (unsigned i = 0; i < buffer.length; ++i) {
131 DCHECK(isASCII(buffer.characters[i]));
132 if (stringCharacters[i] != buffer.characters[i])
133 return false;
134 }
135
136 return true;
137 }
138
139 const UChar* stringCharacters = string->characters16();
140
141 for (unsigned i = 0; i < buffer.length; ++i) {
142 DCHECK(isASCII(buffer.characters[i]));
143 if (stringCharacters[i] != buffer.characters[i])
144 return false;
145 }
146
147 return true;
148 }
149
150 static void translate(StringImpl*& location, const HashAndUTF8Characters& bu ffer, unsigned hash)
151 {
152 UChar* target;
153 RefPtr<StringImpl> newString = StringImpl::createUninitialized(buffer.ut f16Length, target);
154
155 bool isAllASCII;
156 const char* source = buffer.characters;
157 if (convertUTF8ToUTF16(&source, source + buffer.length, &target, target + buffer.utf16Length, &isAllASCII) != conversionOK)
158 NOTREACHED();
159
160 if (isAllASCII)
161 newString = StringImpl::create(buffer.characters, buffer.length);
162
163 location = newString.release().leakRef();
164 location->setHash(hash);
165 location->setIsAtomic(true);
166 }
167 };
168
169 PassRefPtr<StringImpl> AtomicStringTable::add(const UChar* s, unsigned length)
170 {
171 if (!s)
172 return nullptr;
173
174 if (!length)
175 return StringImpl::empty();
176
177 UCharBuffer buffer = { s, length };
178 return addToStringTable<UCharBuffer, UCharBufferTranslator>(buffer);
179 }
180
181 PassRefPtr<StringImpl> AtomicStringTable::add(const UChar* s, unsigned length, u nsigned existingHash)
182 {
183 DCHECK(s);
184 DCHECK(existingHash);
185
186 if (!length)
187 return StringImpl::empty();
188
189 HashAndCharacters<UChar> buffer = { existingHash, s, length };
190 return addToStringTable<HashAndCharacters<UChar>, HashAndCharactersTranslato r<UChar>>(buffer);
191 }
192
193 PassRefPtr<StringImpl> AtomicStringTable::add(const UChar* s)
194 {
195 if (!s)
196 return nullptr;
197
198 unsigned length = 0;
199 while (s[length] != UChar(0))
200 ++length;
201
202 if (!length)
203 return StringImpl::empty();
204
205 UCharBuffer buffer = { s, length };
206 return addToStringTable<UCharBuffer, UCharBufferTranslator>(buffer);
207 }
208
209 struct SubstringLocation {
210 StringImpl* baseString;
211 unsigned start;
212 unsigned length;
213 };
214
215 struct SubstringTranslator {
216 static unsigned hash(const SubstringLocation& buffer)
217 {
218 if (buffer.baseString->is8Bit())
219 return StringHasher::computeHashAndMaskTop8Bits(buffer.baseString->c haracters8() + buffer.start, buffer.length);
220 return StringHasher::computeHashAndMaskTop8Bits(buffer.baseString->chara cters16() + buffer.start, buffer.length);
221 }
222
223 static bool equal(StringImpl* const& string, const SubstringLocation& buffer )
224 {
225 if (buffer.baseString->is8Bit())
226 return WTF::equal(string, buffer.baseString->characters8() + buffer. start, buffer.length);
227 return WTF::equal(string, buffer.baseString->characters16() + buffer.sta rt, buffer.length);
228 }
229
230 static void translate(StringImpl*& location, const SubstringLocation& buffer , unsigned hash)
231 {
232 location = buffer.baseString->substring(buffer.start, buffer.length).lea kRef();
233 location->setHash(hash);
234 location->setIsAtomic(true);
235 }
236 };
237
238 PassRefPtr<StringImpl> AtomicStringTable::add(StringImpl* baseString, unsigned s tart, unsigned length)
239 {
240 if (!baseString)
241 return nullptr;
242
243 if (!length || start >= baseString->length())
244 return StringImpl::empty();
245
246 unsigned maxLength = baseString->length() - start;
247 if (length >= maxLength) {
248 if (!start)
249 return add(baseString);
250 length = maxLength;
251 }
252
253 SubstringLocation buffer = { baseString, start, length };
254 return addToStringTable<SubstringLocation, SubstringTranslator>(buffer);
255 }
256
257 typedef HashTranslatorCharBuffer<LChar> LCharBuffer;
258 struct LCharBufferTranslator {
259 static unsigned hash(const LCharBuffer& buf)
260 {
261 return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length);
262 }
263
264 static bool equal(StringImpl* const& str, const LCharBuffer& buf)
265 {
266 return WTF::equal(str, buf.s, buf.length);
267 }
268
269 static void translate(StringImpl*& location, const LCharBuffer& buf, unsigne d hash)
270 {
271 location = StringImpl::create(buf.s, buf.length).leakRef();
272 location->setHash(hash);
273 location->setIsAtomic(true);
274 }
275 };
276
277 PassRefPtr<StringImpl> AtomicStringTable::add(const LChar* s, unsigned length)
278 {
279 if (!s)
280 return nullptr;
281
282 if (!length)
283 return StringImpl::empty();
284
285 LCharBuffer buffer = { s, length };
286 return addToStringTable<LCharBuffer, LCharBufferTranslator>(buffer);
287 }
288
289 StringImpl* AtomicStringTable::add(StringImpl* string)
26 { 290 {
27 if (!string->length()) 291 if (!string->length())
28 return StringImpl::empty(); 292 return StringImpl::empty();
29 293
30 StringImpl* result = *m_table.add(string).storedValue; 294 StringImpl* result = *m_table.add(string).storedValue;
31 295
32 if (!result->isAtomic()) 296 if (!result->isAtomic())
33 result->setIsAtomic(true); 297 result->setIsAtomic(true);
34 298
35 DCHECK(!string->isStatic() || result->isStatic()); 299 DCHECK(!string->isStatic() || result->isStatic());
36 return result; 300 return result;
37 } 301 }
38 302
303 PassRefPtr<StringImpl> AtomicStringTable::addUTF8(const char* charactersStart, c onst char* charactersEnd)
304 {
305 HashAndUTF8Characters buffer;
306 buffer.characters = charactersStart;
307 buffer.hash = calculateStringHashAndLengthFromUTF8MaskingTop8Bits(characters Start, charactersEnd, buffer.length, buffer.utf16Length);
308
309 if (!buffer.hash)
310 return nullptr;
311
312 return addToStringTable<HashAndUTF8Characters, HashAndUTF8CharactersTranslat or>(buffer);
313 }
314
315 template<typename CharacterType>
316 HashSet<StringImpl*>::iterator AtomicStringTable::find(const StringImpl* string)
317 {
318 HashAndCharacters<CharacterType> buffer = { string->existingHash(), string-> getCharacters<CharacterType>(), string->length() };
319 return m_table.find<HashAndCharactersTranslator<CharacterType>>(buffer);
320 }
321
322 void AtomicStringTable::remove(StringImpl* string)
323 {
324 HashSet<StringImpl*>::iterator iterator;
325 if (string->is8Bit())
326 iterator = find<LChar>(string);
327 else
328 iterator = find<UChar>(string);
329 RELEASE_ASSERT(iterator != m_table.end());
330 m_table.remove(iterator);
331 }
332
39 } // namespace WTF 333 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/AtomicStringTable.h ('k') | third_party/WebKit/Source/wtf/text/StringImpl.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698