Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 #endif | 56 #endif |
| 57 | 57 |
| 58 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> | 58 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> |
| 59 class HashTable; | 59 class HashTable; |
| 60 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> | 60 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> |
| 61 class HashTableIterator; | 61 class HashTableIterator; |
| 62 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> | 62 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> |
| 63 class HashTableConstIterator; | 63 class HashTableConstIterator; |
| 64 template<typename Value, typename HashFunctions, typename HashTraits, typena me Allocator> | |
| 65 class LinkedHashSet; | |
|
Mikhail
2014/04/03 07:56:44
Why is LinkedHashSet needs to be declared here?
Mads Ager (chromium)
2014/04/03 09:24:35
For the friend declaration below?
Erik Corry
2014/04/10 10:47:37
Yes.
| |
| 64 template<bool x, typename T, typename U, typename V, typename W, typename X, typename Y, typename Z> | 66 template<bool x, typename T, typename U, typename V, typename W, typename X, typename Y, typename Z> |
| 65 struct WeakProcessingHashTableHelper; | 67 struct WeakProcessingHashTableHelper; |
| 66 | 68 |
| 67 typedef enum { HashItemKnownGood } HashItemKnownGoodTag; | 69 typedef enum { HashItemKnownGood } HashItemKnownGoodTag; |
| 68 | 70 |
| 69 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> | 71 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> |
| 70 class HashTableConstIterator { | 72 class HashTableConstIterator { |
| 71 private: | 73 private: |
| 72 typedef HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait s, Allocator> HashTableType; | 74 typedef HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait s, Allocator> HashTableType; |
| 73 typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator> iterator; | 75 typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator> iterator; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 97 } | 99 } |
| 98 | 100 |
| 99 HashTableConstIterator(PointerType position, PointerType endPosition, co nst HashTableType* container, HashItemKnownGoodTag) | 101 HashTableConstIterator(PointerType position, PointerType endPosition, co nst HashTableType* container, HashItemKnownGoodTag) |
| 100 : m_position(position) | 102 : m_position(position) |
| 101 , m_endPosition(endPosition) | 103 , m_endPosition(endPosition) |
| 102 #ifdef ASSERT_ENABLED | 104 #ifdef ASSERT_ENABLED |
| 103 , m_container(container) | 105 , m_container(container) |
| 104 , m_containerModifications(container->modifications()) | 106 , m_containerModifications(container->modifications()) |
| 105 #endif | 107 #endif |
| 106 { | 108 { |
| 109 ASSERT(m_containerModifications == m_container->modifications()); | |
| 107 } | 110 } |
| 108 | 111 |
| 109 void checkModifications() const | 112 void checkModifications() const |
| 110 { | 113 { |
| 111 // HashTable and collections that build on it do not support | 114 // HashTable and collections that build on it do not support |
| 112 // modifications while there is an iterator in use. The exception | 115 // modifications while there is an iterator in use. The exception |
| 113 // is ListHashSet, which has its own iterators that tolerate | 116 // is ListHashSet, which has its own iterators that tolerate |
| 114 // modification of the underlying set. | 117 // modification of the underlying set. |
| 115 ASSERT(m_containerModifications == m_container->modifications()); | 118 ASSERT(m_containerModifications == m_container->modifications()); |
| 116 } | 119 } |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 static bool isEmptyOrDeletedBucket(const ValueType& value) { return Hash TableHelper<ValueType, Extractor, KeyTraits>:: isEmptyOrDeletedBucket(value); } | 376 static bool isEmptyOrDeletedBucket(const ValueType& value) { return Hash TableHelper<ValueType, Extractor, KeyTraits>:: isEmptyOrDeletedBucket(value); } |
| 374 | 377 |
| 375 ValueType* lookup(KeyPeekInType key) { return lookup<IdentityTranslatorT ype>(key); } | 378 ValueType* lookup(KeyPeekInType key) { return lookup<IdentityTranslatorT ype>(key); } |
| 376 template<typename HashTranslator, typename T> ValueType* lookup(const T& ); | 379 template<typename HashTranslator, typename T> ValueType* lookup(const T& ); |
| 377 | 380 |
| 378 void trace(typename Allocator::Visitor*); | 381 void trace(typename Allocator::Visitor*); |
| 379 | 382 |
| 380 #ifdef ASSERT_ENABLED | 383 #ifdef ASSERT_ENABLED |
| 381 int64_t modifications() const { return m_modifications; } | 384 int64_t modifications() const { return m_modifications; } |
| 382 void registerModification() { m_modifications++; } | 385 void registerModification() { m_modifications++; } |
| 386 void checkModifications(int64_t mods) const { } | |
|
Mikhail
2014/04/03 07:56:44
Looks like the changes in this file are unnecessar
Mads Ager (chromium)
2014/04/03 09:24:35
mods -> modifications.
Also, you should probably
Erik Corry
2014/04/10 10:47:37
No, rather the opposite, the checkModifications me
Erik Corry
2014/04/10 10:47:37
Nice catch!
| |
| 383 #else | 387 #else |
| 384 int64_t modifications() const { return 0; } | 388 int64_t modifications() const { return 0; } |
| 385 void registerModification() { } | 389 void registerModification() { } |
| 390 // HashTable and collections that build on it do not support | |
| 391 // modifications while there is an iterator in use. The exception is | |
| 392 // ListHashSet, which has its own iterators that tolerate modification | |
| 393 // of the underlying set. | |
| 394 void checkModifications(int64_t mods) const { ASSERT(mods == m_modificat ions); } | |
| 386 #endif | 395 #endif |
| 387 | 396 |
| 388 private: | 397 private: |
| 389 static ValueType* allocateTable(unsigned size); | 398 static ValueType* allocateTable(unsigned size); |
| 390 static void deleteAllBucketsAndDeallocate(ValueType* table, unsigned siz e); | 399 static void deleteAllBucketsAndDeallocate(ValueType* table, unsigned siz e); |
| 391 | 400 |
| 392 typedef std::pair<ValueType*, bool> LookupType; | 401 typedef std::pair<ValueType*, bool> LookupType; |
| 393 typedef std::pair<LookupType, unsigned> FullLookupType; | 402 typedef std::pair<LookupType, unsigned> FullLookupType; |
| 394 | 403 |
| 395 LookupType lookupForWriting(const Key& key) { return lookupForWriting<Id entityTranslatorType>(key); }; | 404 LookupType lookupForWriting(const Key& key) { return lookupForWriting<Id entityTranslatorType>(key); }; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 #ifdef ASSERT_ENABLED | 438 #ifdef ASSERT_ENABLED |
| 430 unsigned m_modifications; | 439 unsigned m_modifications; |
| 431 #endif | 440 #endif |
| 432 | 441 |
| 433 #if DUMP_HASHTABLE_STATS_PER_TABLE | 442 #if DUMP_HASHTABLE_STATS_PER_TABLE |
| 434 public: | 443 public: |
| 435 mutable OwnPtr<Stats> m_stats; | 444 mutable OwnPtr<Stats> m_stats; |
| 436 #endif | 445 #endif |
| 437 | 446 |
| 438 template<bool x, typename T, typename U, typename V, typename W, typenam e X, typename Y, typename Z> friend struct WeakProcessingHashTableHelper; | 447 template<bool x, typename T, typename U, typename V, typename W, typenam e X, typename Y, typename Z> friend struct WeakProcessingHashTableHelper; |
| 448 template<typename T, typename U, typename V, typename W> friend class Li nkedHashSet; | |
| 439 }; | 449 }; |
| 440 | 450 |
| 441 // Set all the bits to one after the most significant bit: 00110101010 -> 00 111111111. | 451 // Set all the bits to one after the most significant bit: 00110101010 -> 00 111111111. |
| 442 template<unsigned size> struct OneifyLowBits; | 452 template<unsigned size> struct OneifyLowBits; |
| 443 template<> | 453 template<> |
| 444 struct OneifyLowBits<0> { | 454 struct OneifyLowBits<0> { |
| 445 static const unsigned value = 0; | 455 static const unsigned value = 0; |
| 446 }; | 456 }; |
| 447 template<unsigned number> | 457 template<unsigned number> |
| 448 struct OneifyLowBits { | 458 struct OneifyLowBits { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 k = 1 | doubleHash(h); | 566 k = 1 | doubleHash(h); |
| 557 i = (i + k) & sizeMask; | 567 i = (i + k) & sizeMask; |
| 558 } | 568 } |
| 559 } | 569 } |
| 560 | 570 |
| 561 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> | 571 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> |
| 562 template<typename HashTranslator, typename T> | 572 template<typename HashTranslator, typename T> |
| 563 inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT raits, Allocator>::LookupType HashTable<Key, Value, Extractor, HashFunctions, Tr aits, KeyTraits, Allocator>::lookupForWriting(const T& key) | 573 inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT raits, Allocator>::LookupType HashTable<Key, Value, Extractor, HashFunctions, Tr aits, KeyTraits, Allocator>::lookupForWriting(const T& key) |
| 564 { | 574 { |
| 565 ASSERT(m_table); | 575 ASSERT(m_table); |
| 576 registerModification(); | |
| 566 | 577 |
| 567 size_t k = 0; | 578 size_t k = 0; |
| 568 ValueType* table = m_table; | 579 ValueType* table = m_table; |
| 569 size_t sizeMask = m_tableSizeMask; | 580 size_t sizeMask = m_tableSizeMask; |
| 570 unsigned h = HashTranslator::hash(key); | 581 unsigned h = HashTranslator::hash(key); |
| 571 size_t i = h & sizeMask; | 582 size_t i = h & sizeMask; |
| 572 | 583 |
| 573 #if DUMP_HASHTABLE_STATS | 584 #if DUMP_HASHTABLE_STATS |
| 574 atomicIncrement(&HashTableStats::numAccesses); | 585 atomicIncrement(&HashTableStats::numAccesses); |
| 575 int probeCount = 0; | 586 int probeCount = 0; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 618 k = 1 | doubleHash(h); | 629 k = 1 | doubleHash(h); |
| 619 i = (i + k) & sizeMask; | 630 i = (i + k) & sizeMask; |
| 620 } | 631 } |
| 621 } | 632 } |
| 622 | 633 |
| 623 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> | 634 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> |
| 624 template<typename HashTranslator, typename T> | 635 template<typename HashTranslator, typename T> |
| 625 inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT raits, Allocator>::FullLookupType HashTable<Key, Value, Extractor, HashFunctions , Traits, KeyTraits, Allocator>::fullLookupForWriting(const T& key) | 636 inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT raits, Allocator>::FullLookupType HashTable<Key, Value, Extractor, HashFunctions , Traits, KeyTraits, Allocator>::fullLookupForWriting(const T& key) |
| 626 { | 637 { |
| 627 ASSERT(m_table); | 638 ASSERT(m_table); |
| 639 registerModification(); | |
| 628 | 640 |
| 629 size_t k = 0; | 641 size_t k = 0; |
| 630 ValueType* table = m_table; | 642 ValueType* table = m_table; |
| 631 size_t sizeMask = m_tableSizeMask; | 643 size_t sizeMask = m_tableSizeMask; |
| 632 unsigned h = HashTranslator::hash(key); | 644 unsigned h = HashTranslator::hash(key); |
| 633 size_t i = h & sizeMask; | 645 size_t i = h & sizeMask; |
| 634 | 646 |
| 635 #if DUMP_HASHTABLE_STATS | 647 #if DUMP_HASHTABLE_STATS |
| 636 atomicIncrement(&HashTableStats::numAccesses); | 648 atomicIncrement(&HashTableStats::numAccesses); |
| 637 int probeCount = 0; | 649 int probeCount = 0; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 704 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> | 716 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> |
| 705 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait s, Allocator>::initializeBucket(ValueType& bucket) | 717 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait s, Allocator>::initializeBucket(ValueType& bucket) |
| 706 { | 718 { |
| 707 HashTableBucketInitializer<Traits::emptyValueIsZero>::template initializ e<Traits>(bucket); | 719 HashTableBucketInitializer<Traits::emptyValueIsZero>::template initializ e<Traits>(bucket); |
| 708 } | 720 } |
| 709 | 721 |
| 710 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> | 722 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> |
| 711 template<typename HashTranslator, typename T, typename Extra> | 723 template<typename HashTranslator, typename T, typename Extra> |
| 712 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, Ke yTraits, Allocator>::add(const T& key, const Extra& extra) | 724 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, Ke yTraits, Allocator>::add(const T& key, const Extra& extra) |
| 713 { | 725 { |
| 726 registerModification(); | |
| 714 if (!m_table) | 727 if (!m_table) |
| 715 expand(); | 728 expand(); |
| 716 | 729 |
| 717 ASSERT(m_table); | 730 ASSERT(m_table); |
| 718 | 731 |
| 719 size_t k = 0; | 732 size_t k = 0; |
| 720 ValueType* table = m_table; | 733 ValueType* table = m_table; |
| 721 size_t sizeMask = m_tableSizeMask; | 734 size_t sizeMask = m_tableSizeMask; |
| 722 unsigned h = HashTranslator::hash(key); | 735 unsigned h = HashTranslator::hash(key); |
| 723 size_t i = h & sizeMask; | 736 size_t i = h & sizeMask; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 786 if (shouldExpand()) | 799 if (shouldExpand()) |
| 787 entry = expand(entry); | 800 entry = expand(entry); |
| 788 | 801 |
| 789 return AddResult(entry, true); | 802 return AddResult(entry, true); |
| 790 } | 803 } |
| 791 | 804 |
| 792 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> | 805 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> |
| 793 template<typename HashTranslator, typename T, typename Extra> | 806 template<typename HashTranslator, typename T, typename Extra> |
| 794 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, Ke yTraits, Allocator>::addPassingHashCode(const T& key, const Extra& extra) | 807 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, Ke yTraits, Allocator>::addPassingHashCode(const T& key, const Extra& extra) |
| 795 { | 808 { |
| 809 registerModification(); | |
| 796 if (!m_table) | 810 if (!m_table) |
| 797 expand(); | 811 expand(); |
| 798 | 812 |
| 799 FullLookupType lookupResult = fullLookupForWriting<HashTranslator>(key); | 813 FullLookupType lookupResult = fullLookupForWriting<HashTranslator>(key); |
| 800 | 814 |
| 801 ValueType* entry = lookupResult.first.first; | 815 ValueType* entry = lookupResult.first.first; |
| 802 bool found = lookupResult.first.second; | 816 bool found = lookupResult.first.second; |
| 803 unsigned h = lookupResult.second; | 817 unsigned h = lookupResult.second; |
| 804 | 818 |
| 805 if (found) | 819 if (found) |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1228 inline bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTa bleConstIteratorAdapter<T, U>& b) | 1242 inline bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTa bleConstIteratorAdapter<T, U>& b) |
| 1229 { | 1243 { |
| 1230 return a.m_impl != b.m_impl; | 1244 return a.m_impl != b.m_impl; |
| 1231 } | 1245 } |
| 1232 | 1246 |
| 1233 } // namespace WTF | 1247 } // namespace WTF |
| 1234 | 1248 |
| 1235 #include "wtf/HashIterators.h" | 1249 #include "wtf/HashIterators.h" |
| 1236 | 1250 |
| 1237 #endif // WTF_HashTable_h | 1251 #endif // WTF_HashTable_h |
| OLD | NEW |