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

Side by Side Diff: third_party/WebKit/Source/wtf/HashTable.h

Issue 1764973002: WTF::HashTable: Implement move semantics for keys and values. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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 /* 1 /*
2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2008 David Levin <levin@chromium.org> 3 * Copyright (C) 2008 David Levin <levin@chromium.org>
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 new (NotNull, &to) T(std::move(from)); 267 new (NotNull, &to) T(std::move(from));
268 Allocator::leaveGCForbiddenScope(); 268 Allocator::leaveGCForbiddenScope();
269 } 269 }
270 }; 270 };
271 271
272 template <typename HashFunctions> class IdentityHashTranslator { 272 template <typename HashFunctions> class IdentityHashTranslator {
273 STATIC_ONLY(IdentityHashTranslator); 273 STATIC_ONLY(IdentityHashTranslator);
274 public: 274 public:
275 template <typename T> static unsigned hash(const T& key) { return HashFuncti ons::hash(key); } 275 template <typename T> static unsigned hash(const T& key) { return HashFuncti ons::hash(key); }
276 template <typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a, b); } 276 template <typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a, b); }
277 template <typename T, typename U, typename V> static void translate(T& locat ion, const U&, const V& value) { location = value; } 277 template <typename T, typename U, typename V> static void translate(T& locat ion, U&&, V&& value) { location = std::forward<V>(value); }
278 }; 278 };
279 279
280 template <typename HashTableType, typename ValueType> struct HashTableAddResult final { 280 template <typename HashTableType, typename ValueType> struct HashTableAddResult final {
281 STACK_ALLOCATED(); 281 STACK_ALLOCATED();
282 HashTableAddResult(const HashTableType* container, ValueType* storedValue, b ool isNewEntry) 282 HashTableAddResult(const HashTableType* container, ValueType* storedValue, b ool isNewEntry)
283 : storedValue(storedValue) 283 : storedValue(storedValue)
284 , isNewEntry(isNewEntry) 284 , isNewEntry(isNewEntry)
285 #if ENABLE(SECURITY_ASSERT) 285 #if ENABLE(SECURITY_ASSERT)
286 , m_container(container) 286 , m_container(container)
287 , m_containerModifications(container->modifications()) 287 , m_containerModifications(container->modifications())
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 void reserveCapacityForSize(unsigned size); 455 void reserveCapacityForSize(unsigned size);
456 456
457 AddResult add(ValuePassInType value) 457 AddResult add(ValuePassInType value)
458 { 458 {
459 return add<IdentityTranslatorType>(Extractor::extract(value), value); 459 return add<IdentityTranslatorType>(Extractor::extract(value), value);
460 } 460 }
461 461
462 // A special version of add() that finds the object by hashing and comparing 462 // A special version of add() that finds the object by hashing and comparing
463 // with some other type, to avoid the cost of type conversion if the object 463 // with some other type, to avoid the cost of type conversion if the object
464 // is already in the table. 464 // is already in the table.
465 template <typename HashTranslator, typename T, typename Extra> AddResult add (const T& key, const Extra&); 465 template <typename HashTranslator, typename T, typename Extra> AddResult add (T&& key, Extra&&);
466 template <typename HashTranslator, typename T, typename Extra> AddResult add PassingHashCode(const T& key, const Extra&); 466 template <typename HashTranslator, typename T, typename Extra> AddResult add PassingHashCode(const T& key, const Extra&);
467 467
468 iterator find(KeyPeekInType key) { return find<IdentityTranslatorType>(key); } 468 iterator find(KeyPeekInType key) { return find<IdentityTranslatorType>(key); }
469 const_iterator find(KeyPeekInType key) const { return find<IdentityTranslato rType>(key); } 469 const_iterator find(KeyPeekInType key) const { return find<IdentityTranslato rType>(key); }
470 bool contains(KeyPeekInType key) const { return contains<IdentityTranslatorT ype>(key); } 470 bool contains(KeyPeekInType key) const { return contains<IdentityTranslatorT ype>(key); }
471 471
472 template <typename HashTranslator, typename T> iterator find(const T&); 472 template <typename HashTranslator, typename T> iterator find(const T&);
473 template <typename HashTranslator, typename T> const_iterator find(const T&) const; 473 template <typename HashTranslator, typename T> const_iterator find(const T&) const;
474 template <typename HashTranslator, typename T> bool contains(const T&) const ; 474 template <typename HashTranslator, typename T> bool contains(const T&) const ;
475 475
476 void remove(KeyPeekInType); 476 void remove(KeyPeekInType);
477 void remove(iterator); 477 void remove(iterator);
478 void remove(const_iterator); 478 void remove(const_iterator);
479 void clear(); 479 void clear();
480 480
481 static bool isEmptyBucket(const ValueType& value) { return isHashTraitsEmpty Value<KeyTraits>(Extractor::extract(value)); } 481 static bool isEmptyBucket(const ValueType& value) { return isHashTraitsEmpty Value<KeyTraits>(Extractor::extract(value)); }
482 static bool isDeletedBucket(const ValueType& value) { return KeyTraits::isDe letedValue(Extractor::extract(value)); } 482 static bool isDeletedBucket(const ValueType& value) { return KeyTraits::isDe letedValue(Extractor::extract(value)); }
483 static bool isEmptyOrDeletedBucket(const ValueType& value) { return HashTabl eHelper<ValueType, Extractor, KeyTraits>:: isEmptyOrDeletedBucket(value); } 483 static bool isEmptyOrDeletedBucket(const ValueType& value) { return HashTabl eHelper<ValueType, Extractor, KeyTraits>:: isEmptyOrDeletedBucket(value); }
484 484
485 ValueType* lookup(KeyPeekInType key) { return lookup<IdentityTranslatorType, KeyPeekInType>(key); } 485 ValueType* lookup(KeyPeekInType key) { return lookup<IdentityTranslatorType, KeyPeekInType>(key); }
486 template <typename HashTranslator, typename T> ValueType* lookup(T); 486 template <typename HashTranslator, typename T> ValueType* lookup(const T&);
Mikhail 2016/03/04 12:58:02 why not T&& ?
Yuta Kitamura 2016/03/04 13:55:37 This is used to calculate the hash value of T, so
487 template <typename HashTranslator, typename T> const ValueType* lookup(T) co nst; 487 template <typename HashTranslator, typename T> const ValueType* lookup(const T&) const;
488 488
489 template <typename VisitorDispatcher> void trace(VisitorDispatcher); 489 template <typename VisitorDispatcher> void trace(VisitorDispatcher);
490 490
491 #if ENABLE(ASSERT) 491 #if ENABLE(ASSERT)
492 bool accessForbidden() const { return m_accessForbidden; } 492 bool accessForbidden() const { return m_accessForbidden; }
493 int64_t modifications() const { return m_modifications; } 493 int64_t modifications() const { return m_modifications; }
494 void registerModification() { m_modifications++; } 494 void registerModification() { m_modifications++; }
495 // HashTable and collections that build on it do not support modifications 495 // HashTable and collections that build on it do not support modifications
496 // while there is an iterator in use. The exception is ListHashSet, which 496 // while there is an iterator in use. The exception is ListHashSet, which
497 // has its own iterators that tolerate modification of the underlying set. 497 // has its own iterators that tolerate modification of the underlying set.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 newCapacity = KeyTraits::minimumTableSize; 627 newCapacity = KeyTraits::minimumTableSize;
628 628
629 if (newCapacity > capacity()) { 629 if (newCapacity > capacity()) {
630 RELEASE_ASSERT(!static_cast<int>(newCapacity >> 31)); // HashTable capac ity should not overflow 32bit int. 630 RELEASE_ASSERT(!static_cast<int>(newCapacity >> 31)); // HashTable capac ity should not overflow 32bit int.
631 rehash(newCapacity, 0); 631 rehash(newCapacity, 0);
632 } 632 }
633 } 633 }
634 634
635 template <typename Key, typename Value, typename Extractor, typename HashFunctio ns, typename Traits, typename KeyTraits, typename Allocator> 635 template <typename Key, typename Value, typename Extractor, typename HashFunctio ns, typename Traits, typename KeyTraits, typename Allocator>
636 template <typename HashTranslator, typename T> 636 template <typename HashTranslator, typename T>
637 inline Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::lookup(T key) 637 inline Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::lookup(const T& key)
638 { 638 {
639 return const_cast<Value*>(const_cast<const HashTable*>(this)->lookup<HashTra nslator, T>(key)); 639 return const_cast<Value*>(const_cast<const HashTable*>(this)->lookup<HashTra nslator>(key));
640 } 640 }
641 641
642 template <typename Key, typename Value, typename Extractor, typename HashFunctio ns, typename Traits, typename KeyTraits, typename Allocator> 642 template <typename Key, typename Value, typename Extractor, typename HashFunctio ns, typename Traits, typename KeyTraits, typename Allocator>
643 template <typename HashTranslator, typename T> 643 template <typename HashTranslator, typename T>
644 inline const Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT raits, Allocator>::lookup(T key) const 644 inline const Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT raits, Allocator>::lookup(const T& key) const
645 { 645 {
646 ASSERT(!m_accessForbidden); 646 ASSERT(!m_accessForbidden);
647 ASSERT((HashTableKeyChecker<HashTranslator, KeyTraits, HashFunctions::safeTo CompareToEmptyOrDeleted>::checkKey(key))); 647 ASSERT((HashTableKeyChecker<HashTranslator, KeyTraits, HashFunctions::safeTo CompareToEmptyOrDeleted>::checkKey(key)));
648 const ValueType* table = m_table; 648 const ValueType* table = m_table;
649 if (!table) 649 if (!table)
650 return nullptr; 650 return nullptr;
651 651
652 size_t k = 0; 652 size_t k = 0;
653 size_t sizeMask = tableSizeMask(); 653 size_t sizeMask = tableSizeMask();
654 unsigned h = HashTranslator::hash(key); 654 unsigned h = HashTranslator::hash(key);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 }; 788 };
789 789
790 template <typename Key, typename Value, typename Extractor, typename HashFunctio ns, typename Traits, typename KeyTraits, typename Allocator> 790 template <typename Key, typename Value, typename Extractor, typename HashFunctio ns, typename Traits, typename KeyTraits, typename Allocator>
791 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, A llocator>::initializeBucket(ValueType& bucket) 791 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, A llocator>::initializeBucket(ValueType& bucket)
792 { 792 {
793 HashTableBucketInitializer<Traits::emptyValueIsZero>::template initialize<Tr aits>(bucket); 793 HashTableBucketInitializer<Traits::emptyValueIsZero>::template initialize<Tr aits>(bucket);
794 } 794 }
795 795
796 template <typename Key, typename Value, typename Extractor, typename HashFunctio ns, typename Traits, typename KeyTraits, typename Allocator> 796 template <typename Key, typename Value, typename Extractor, typename HashFunctio ns, typename Traits, typename KeyTraits, typename Allocator>
797 template <typename HashTranslator, typename T, typename Extra> 797 template <typename HashTranslator, typename T, typename Extra>
798 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allo cator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTra its, Allocator>::add(const T& key, const Extra& extra) 798 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allo cator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTra its, Allocator>::add(T&& key, Extra&& extra)
799 { 799 {
800 ASSERT(!m_accessForbidden); 800 ASSERT(!m_accessForbidden);
801 ASSERT(Allocator::isAllocationAllowed()); 801 ASSERT(Allocator::isAllocationAllowed());
802 if (!m_table) 802 if (!m_table)
803 expand(); 803 expand();
804 804
805 ASSERT(m_table); 805 ASSERT(m_table);
806 806
807 ValueType* table = m_table; 807 ValueType* table = m_table;
808 size_t k = 0; 808 size_t k = 0;
809 size_t sizeMask = tableSizeMask(); 809 size_t sizeMask = tableSizeMask();
810 unsigned h = HashTranslator::hash(key); 810 unsigned h = HashTranslator::hash(key);
tzik 2016/03/04 15:29:59 This is not directly related to this CL, but it ma
Yuta Kitamura 2016/03/07 04:36:27 I don't plan to do that in this patch, but sounds
811 size_t i = h & sizeMask; 811 size_t i = h & sizeMask;
812 812
813 UPDATE_ACCESS_COUNTS(); 813 UPDATE_ACCESS_COUNTS();
814 814
815 ValueType* deletedEntry = nullptr; 815 ValueType* deletedEntry = nullptr;
816 ValueType* entry; 816 ValueType* entry;
817 while (1) { 817 while (1) {
818 entry = table + i; 818 entry = table + i;
819 819
820 if (isEmptyBucket(*entry)) 820 if (isEmptyBucket(*entry))
(...skipping 20 matching lines...) Expand all
841 registerModification(); 841 registerModification();
842 842
843 if (deletedEntry) { 843 if (deletedEntry) {
844 // Overwrite any data left over from last use, using placement new or 844 // Overwrite any data left over from last use, using placement new or
845 // memset. 845 // memset.
846 initializeBucket(*deletedEntry); 846 initializeBucket(*deletedEntry);
847 entry = deletedEntry; 847 entry = deletedEntry;
848 --m_deletedCount; 848 --m_deletedCount;
849 } 849 }
850 850
851 HashTranslator::translate(*entry, key, extra); 851 HashTranslator::translate(*entry, std::forward<T>(key), std::forward<Extra>( extra));
852 ASSERT(!isEmptyOrDeletedBucket(*entry)); 852 ASSERT(!isEmptyOrDeletedBucket(*entry));
853 853
854 ++m_keyCount; 854 ++m_keyCount;
855 855
856 if (shouldExpand()) 856 if (shouldExpand())
857 entry = expand(entry); 857 entry = expand(entry);
858 858
859 return AddResult(this, entry, true); 859 return AddResult(this, entry, true);
860 } 860 }
861 861
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 CollectionIterator end(toBeRemoved.end()); 1495 CollectionIterator end(toBeRemoved.end());
1496 for (CollectionIterator it(toBeRemoved.begin()); it != end; ++it) 1496 for (CollectionIterator it(toBeRemoved.begin()); it != end; ++it)
1497 collection.remove(*it); 1497 collection.remove(*it);
1498 } 1498 }
1499 1499
1500 } // namespace WTF 1500 } // namespace WTF
1501 1501
1502 #include "wtf/HashIterators.h" 1502 #include "wtf/HashIterators.h"
1503 1503
1504 #endif // WTF_HashTable_h 1504 #endif // WTF_HashTable_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698