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

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

Issue 223373002: Create HeapLinkedHashSet and LinkedHashSet, ordered heap-friendly hash sets. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Remove inadvertent changes Created 6 years, 8 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 | Annotate | Revision Log
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698