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 |