| 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 |