OLD | NEW |
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" | 7 #include "wtf/text/StringHash.h" |
8 #include "wtf/text/UTF8.h" | 8 #include "wtf/text/UTF8.h" |
9 | 9 |
10 namespace WTF { | 10 namespace WTF { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 } | 61 } |
62 | 62 |
63 static void translate(StringImpl*& location, const UCharBuffer& buf, unsigne
d hash) | 63 static void translate(StringImpl*& location, const UCharBuffer& buf, unsigne
d hash) |
64 { | 64 { |
65 location = StringImpl::create8BitIfPossible(buf.s, buf.length).leakRef()
; | 65 location = StringImpl::create8BitIfPossible(buf.s, buf.length).leakRef()
; |
66 location->setHash(hash); | 66 location->setHash(hash); |
67 location->setIsAtomic(true); | 67 location->setIsAtomic(true); |
68 } | 68 } |
69 }; | 69 }; |
70 | 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 { | 71 struct HashAndUTF8Characters { |
100 unsigned hash; | 72 unsigned hash; |
101 const char* characters; | 73 const char* characters; |
102 unsigned length; | 74 unsigned length; |
103 unsigned utf16Length; | 75 unsigned utf16Length; |
104 }; | 76 }; |
105 | 77 |
106 struct HashAndUTF8CharactersTranslator { | 78 struct HashAndUTF8CharactersTranslator { |
107 static unsigned hash(const HashAndUTF8Characters& buffer) | 79 static unsigned hash(const HashAndUTF8Characters& buffer) |
108 { | 80 { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 if (!s) | 143 if (!s) |
172 return nullptr; | 144 return nullptr; |
173 | 145 |
174 if (!length) | 146 if (!length) |
175 return StringImpl::empty(); | 147 return StringImpl::empty(); |
176 | 148 |
177 UCharBuffer buffer = { s, length }; | 149 UCharBuffer buffer = { s, length }; |
178 return addToStringTable<UCharBuffer, UCharBufferTranslator>(buffer); | 150 return addToStringTable<UCharBuffer, UCharBufferTranslator>(buffer); |
179 } | 151 } |
180 | 152 |
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; | 153 typedef HashTranslatorCharBuffer<LChar> LCharBuffer; |
258 struct LCharBufferTranslator { | 154 struct LCharBufferTranslator { |
259 static unsigned hash(const LCharBuffer& buf) | 155 static unsigned hash(const LCharBuffer& buf) |
260 { | 156 { |
261 return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length); | 157 return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length); |
262 } | 158 } |
263 | 159 |
264 static bool equal(StringImpl* const& str, const LCharBuffer& buf) | 160 static bool equal(StringImpl* const& str, const LCharBuffer& buf) |
265 { | 161 { |
266 return WTF::equal(str, buf.s, buf.length); | 162 return WTF::equal(str, buf.s, buf.length); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 HashAndUTF8Characters buffer; | 201 HashAndUTF8Characters buffer; |
306 buffer.characters = charactersStart; | 202 buffer.characters = charactersStart; |
307 buffer.hash = calculateStringHashAndLengthFromUTF8MaskingTop8Bits(characters
Start, charactersEnd, buffer.length, buffer.utf16Length); | 203 buffer.hash = calculateStringHashAndLengthFromUTF8MaskingTop8Bits(characters
Start, charactersEnd, buffer.length, buffer.utf16Length); |
308 | 204 |
309 if (!buffer.hash) | 205 if (!buffer.hash) |
310 return nullptr; | 206 return nullptr; |
311 | 207 |
312 return addToStringTable<HashAndUTF8Characters, HashAndUTF8CharactersTranslat
or>(buffer); | 208 return addToStringTable<HashAndUTF8Characters, HashAndUTF8CharactersTranslat
or>(buffer); |
313 } | 209 } |
314 | 210 |
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) | 211 void AtomicStringTable::remove(StringImpl* string) |
323 { | 212 { |
324 HashSet<StringImpl*>::iterator iterator; | 213 DCHECK(string->isAtomic()); |
325 if (string->is8Bit()) | 214 auto iterator = m_table.find(string); |
326 iterator = find<LChar>(string); | |
327 else | |
328 iterator = find<UChar>(string); | |
329 RELEASE_ASSERT(iterator != m_table.end()); | 215 RELEASE_ASSERT(iterator != m_table.end()); |
330 m_table.remove(iterator); | 216 m_table.remove(iterator); |
331 } | 217 } |
332 | 218 |
333 } // namespace WTF | 219 } // namespace WTF |
OLD | NEW |