Changeset 196716 in webkit
- Timestamp:
- Feb 17, 2016, 1:17:00 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r196686 r196716 1 2016-02-16 Sam Weinig <sam@webkit.org> 2 3 Add an ensure function on HashMap that takes a key and a function to make the lazy value initialization idiom easier 4 https://bugs.webkit.org/show_bug.cgi?id=134857 5 6 Reviewed by Geoffrey Garen. 7 8 The current idiom for adding a value to a HashMap if the key is not already present, to allow for not 9 unnecessarily constructing the new value if it won't be used, is: 10 11 { 12 auto result = map.add(key, Value()); 13 if (!result.isNewEntry) 14 return result.iterator->value; 15 16 result.iterator->value = createNewValue(); 17 return result.iterator->value; 18 } 19 20 or sometimes 21 22 { 23 auto& value = map.add(key, Value()).iterator->value; 24 if (!value) 25 value = createNewValue(); 26 return value; 27 } 28 29 With this patch, you can now use the new function HashMap::ensure(key, functor). This will allow us to 30 change to using the following idiom: 31 32 { 33 return map.ensure(key, [] { return createNewValue(); }); 34 } 35 36 The passed in functor will only be called if the key is not already present in the HashMap. 37 38 * wtf/HashMap.h: 39 (WTF::HashMapTranslator::translate): 40 (WTF::HashMapEnsureTranslator::hash): 41 (WTF::HashMapEnsureTranslator::equal): 42 (WTF::HashMapEnsureTranslator::translate): 43 (WTF::HashMapTranslatorAdapter::hash): 44 1 45 2016-02-16 Filip Pizlo <fpizlo@apple.com> 2 46 -
trunk/Source/WTF/wtf/HashMap.h
r194496 r196716 119 119 template<typename V> AddResult fastAdd(KeyType&&, V&&); 120 120 121 template<typename Functor> MappedType& ensure(const KeyType&, const Functor&); 122 template<typename Functor> MappedType& ensure(KeyType&&, const Functor&); 123 121 124 bool remove(const KeyType&); 122 125 bool remove(iterator); … … 164 167 AddResult inlineAdd(K&&, V&&); 165 168 169 template<typename K, typename F> 170 MappedType& inlineEnsure(K&&, const F&); 171 166 172 HashTableType m_impl; 167 173 }; … … 178 184 }; 179 185 186 template<typename ValueTraits, typename HashFunctions> 187 struct HashMapEnsureTranslator { 188 template<typename T> static unsigned hash(const T& key) { return HashFunctions::hash(key); } 189 template<typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a, b); } 190 template<typename T, typename U, typename Functor> static void translate(T& location, U&& key, const Functor& functor) 191 { 192 location.key = std::forward<U>(key); 193 location.value = functor(); 194 } 195 }; 196 180 197 template<typename ValueTraits, typename Translator> 181 198 struct HashMapTranslatorAdapter { … … 298 315 299 316 template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> 317 template<typename K, typename F> 318 ALWAYS_INLINE auto HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::inlineEnsure(K&& key, const F& functor) -> MappedType& 319 { 320 return m_impl.template add<HashMapEnsureTranslator<KeyValuePairTraits, HashFunctions>>(std::forward<K>(key), functor).iterator->value; 321 } 322 323 template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> 300 324 template<typename T> 301 325 auto HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::set(const KeyType& key, T&& mapped) -> AddResult … … 346 370 } 347 371 372 template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> 373 template<typename Functor> 374 auto HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::ensure(const KeyType& key, const Functor& functor) -> MappedType& 375 { 376 return inlineEnsure(key, functor); 377 } 378 379 template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> 380 template<typename Functor> 381 auto HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::ensure(KeyType&& key, const Functor& functor) -> MappedType& 382 { 383 return inlineEnsure(WTFMove(key), functor); 384 } 385 348 386 template<typename T, typename U, typename V, typename W, typename MappedTraits> 349 387 auto HashMap<T, U, V, W, MappedTraits>::get(const KeyType& key) const -> MappedPeekType -
trunk/Tools/ChangeLog
r196699 r196716 1 2016-02-16 Sam Weinig <sam@webkit.org> 2 3 Add an ensure function on HashMap that takes a key and a function to make the lazy value initialization idiom easier 4 https://bugs.webkit.org/show_bug.cgi?id=134857 5 6 Reviewed by Geoffrey Garen. 7 8 * TestWebKitAPI/Tests/WTF/HashMap.cpp: 9 Add tests for HashMap::ensure. 10 1 11 2016-02-17 Nan Wang <n_wang@apple.com> 2 12 -
trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp
r194496 r196716 509 509 } 510 510 511 TEST(WTF_HashMap, Ensure) 512 { 513 HashMap<unsigned, unsigned> map; 514 { 515 auto value = map.ensure(1, [] { return 1; }); 516 EXPECT_EQ(1u, value); 517 value = map.ensure(1, [] { return 2; }); 518 EXPECT_EQ(1u, value); 519 } 520 } 521 522 TEST(WTF_HashMap, Ensure_MoveOnlyValues) 523 { 524 HashMap<unsigned, MoveOnly> moveOnlyValues; 525 { 526 auto& value = moveOnlyValues.ensure(1, [] { return MoveOnly(1); }); 527 EXPECT_EQ(1u, value.value()); 528 auto& value2 = moveOnlyValues.ensure(1, [] { return MoveOnly(2); }); 529 EXPECT_EQ(1u, value2.value()); 530 } 531 } 532 533 TEST(WTF_HashMap, Ensure_UniquePointer) 534 { 535 HashMap<unsigned, std::unique_ptr<unsigned>> map; 536 { 537 auto& value = map.ensure(1, [] { return std::make_unique<unsigned>(1); }); 538 EXPECT_EQ(1u, *map.get(1)); 539 EXPECT_EQ(1u, *value.get()); 540 auto& value2 = map.ensure(1, [] { return std::make_unique<unsigned>(2); }); 541 EXPECT_EQ(1u, *map.get(1)); 542 EXPECT_EQ(1u, *value2.get()); 543 } 544 } 545 546 TEST(WTF_HashMap, Ensure_RefPtr) 547 { 548 HashMap<unsigned, RefPtr<RefLogger>> map; 549 550 { 551 DerivedRefLogger a("a"); 552 553 map.ensure(1, [&] { return RefPtr<RefLogger>(&a); }); 554 EXPECT_STREQ("ref(a) ", takeLogStr().c_str()); 555 556 map.ensure(1, [&] { return RefPtr<RefLogger>(&a); }); 557 EXPECT_STREQ("", takeLogStr().c_str()); 558 } 559 } 560 511 561 } // namespace TestWebKitAPI
Note:
See TracChangeset
for help on using the changeset viewer.