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

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: Fix gtest-related compile error on gcc by removing internal typedefs in iterators 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
« no previous file with comments | « Source/platform/heap/Visitor.h ('k') | Source/wtf/LinkedHashSet.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 368
366 void remove(KeyPeekInType); 369 void remove(KeyPeekInType);
367 void remove(iterator); 370 void remove(iterator);
368 void remove(const_iterator); 371 void remove(const_iterator);
369 void clear(); 372 void clear();
370 373
371 static bool isEmptyBucket(const ValueType& value) { return isHashTraitsE mptyValue<KeyTraits>(Extractor::extract(value)); } 374 static bool isEmptyBucket(const ValueType& value) { return isHashTraitsE mptyValue<KeyTraits>(Extractor::extract(value)); }
372 static bool isDeletedBucket(const ValueType& value) { return KeyTraits:: isDeletedValue(Extractor::extract(value)); } 375 static bool isDeletedBucket(const ValueType& value) { return KeyTraits:: isDeletedValue(Extractor::extract(value)); }
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, KeyPeekInType>(key); }
376 template<typename HashTranslator, typename T> ValueType* lookup(const T& ); 379 template<typename HashTranslator, typename T> ValueType* lookup(T);
380 template<typename HashTranslator, typename T> const ValueType* lookup(T) const;
377 381
378 void trace(typename Allocator::Visitor*); 382 void trace(typename Allocator::Visitor*);
379 383
380 #ifdef ASSERT_ENABLED 384 #ifdef ASSERT_ENABLED
381 int64_t modifications() const { return m_modifications; } 385 int64_t modifications() const { return m_modifications; }
382 void registerModification() { m_modifications++; } 386 void registerModification() { m_modifications++; }
387 // HashTable and collections that build on it do not support
388 // modifications while there is an iterator in use. The exception is
389 // ListHashSet, which has its own iterators that tolerate modification
390 // of the underlying set.
391 void checkModifications(int64_t mods) const { ASSERT(mods == m_modificat ions); }
383 #else 392 #else
384 int64_t modifications() const { return 0; } 393 int64_t modifications() const { return 0; }
385 void registerModification() { } 394 void registerModification() { }
395 void checkModifications(int64_t mods) const { }
386 #endif 396 #endif
387 397
388 private: 398 private:
389 static ValueType* allocateTable(unsigned size); 399 static ValueType* allocateTable(unsigned size);
390 static void deleteAllBucketsAndDeallocate(ValueType* table, unsigned siz e); 400 static void deleteAllBucketsAndDeallocate(ValueType* table, unsigned siz e);
391 401
392 typedef std::pair<ValueType*, bool> LookupType; 402 typedef std::pair<ValueType*, bool> LookupType;
393 typedef std::pair<LookupType, unsigned> FullLookupType; 403 typedef std::pair<LookupType, unsigned> FullLookupType;
394 404
395 LookupType lookupForWriting(const Key& key) { return lookupForWriting<Id entityTranslatorType>(key); }; 405 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 439 #ifdef ASSERT_ENABLED
430 unsigned m_modifications; 440 unsigned m_modifications;
431 #endif 441 #endif
432 442
433 #if DUMP_HASHTABLE_STATS_PER_TABLE 443 #if DUMP_HASHTABLE_STATS_PER_TABLE
434 public: 444 public:
435 mutable OwnPtr<Stats> m_stats; 445 mutable OwnPtr<Stats> m_stats;
436 #endif 446 #endif
437 447
438 template<bool x, typename T, typename U, typename V, typename W, typenam e X, typename Y, typename Z> friend struct WeakProcessingHashTableHelper; 448 template<bool x, typename T, typename U, typename V, typename W, typenam e X, typename Y, typename Z> friend struct WeakProcessingHashTableHelper;
449 template<typename T, typename U, typename V, typename W> friend class Li nkedHashSet;
439 }; 450 };
440 451
441 // Set all the bits to one after the most significant bit: 00110101010 -> 00 111111111. 452 // Set all the bits to one after the most significant bit: 00110101010 -> 00 111111111.
442 template<unsigned size> struct OneifyLowBits; 453 template<unsigned size> struct OneifyLowBits;
443 template<> 454 template<>
444 struct OneifyLowBits<0> { 455 struct OneifyLowBits<0> {
445 static const unsigned value = 0; 456 static const unsigned value = 0;
446 }; 457 };
447 template<unsigned number> 458 template<unsigned number>
448 struct OneifyLowBits { 459 struct OneifyLowBits {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 key = ~key + (key >> 23); 508 key = ~key + (key >> 23);
498 key ^= (key << 12); 509 key ^= (key << 12);
499 key ^= (key >> 7); 510 key ^= (key >> 7);
500 key ^= (key << 2); 511 key ^= (key << 2);
501 key ^= (key >> 20); 512 key ^= (key >> 20);
502 return key; 513 return key;
503 } 514 }
504 515
505 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> 516 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator>
506 template<typename HashTranslator, typename T> 517 template<typename HashTranslator, typename T>
507 inline Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTra its, Allocator>::lookup(const T& key) 518 inline Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTra its, Allocator>::lookup(T key)
508 { 519 {
509 ValueType* table = m_table; 520 return const_cast<Value*>(const_cast<const HashTable*>(this)->lookup<Has hTranslator, T>(key));
521 }
522
523 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator>
524 template<typename HashTranslator, typename T>
525 inline const Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::lookup(T key) const
526 {
527 const ValueType* table = m_table;
510 if (!table) 528 if (!table)
511 return 0; 529 return 0;
512 530
513 size_t k = 0; 531 size_t k = 0;
514 size_t sizeMask = m_tableSizeMask; 532 size_t sizeMask = m_tableSizeMask;
515 unsigned h = HashTranslator::hash(key); 533 unsigned h = HashTranslator::hash(key);
516 size_t i = h & sizeMask; 534 size_t i = h & sizeMask;
517 535
518 #if DUMP_HASHTABLE_STATS 536 #if DUMP_HASHTABLE_STATS
519 atomicIncrement(&HashTableStats::numAccesses); 537 atomicIncrement(&HashTableStats::numAccesses);
520 int probeCount = 0; 538 int probeCount = 0;
521 #endif 539 #endif
522 540
523 #if DUMP_HASHTABLE_STATS_PER_TABLE 541 #if DUMP_HASHTABLE_STATS_PER_TABLE
524 ++m_stats->numAccesses; 542 ++m_stats->numAccesses;
525 int perTableProbeCount = 0; 543 int perTableProbeCount = 0;
526 #endif 544 #endif
527 545
528 while (1) { 546 while (1) {
529 ValueType* entry = table + i; 547 const ValueType* entry = table + i;
530 548
531 // we count on the compiler to optimize out this branch 549 // we count on the compiler to optimize out this branch
532 if (HashFunctions::safeToCompareToEmptyOrDeleted) { 550 if (HashFunctions::safeToCompareToEmptyOrDeleted) {
533 if (HashTranslator::equal(Extractor::extract(*entry), key)) 551 if (HashTranslator::equal(Extractor::extract(*entry), key))
534 return entry; 552 return entry;
535 553
536 if (isEmptyBucket(*entry)) 554 if (isEmptyBucket(*entry))
537 return 0; 555 return 0;
538 } else { 556 } else {
539 if (isEmptyBucket(*entry)) 557 if (isEmptyBucket(*entry))
(...skipping 16 matching lines...) Expand all
556 k = 1 | doubleHash(h); 574 k = 1 | doubleHash(h);
557 i = (i + k) & sizeMask; 575 i = (i + k) & sizeMask;
558 } 576 }
559 } 577 }
560 578
561 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> 579 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator>
562 template<typename HashTranslator, typename T> 580 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) 581 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 { 582 {
565 ASSERT(m_table); 583 ASSERT(m_table);
584 registerModification();
566 585
567 size_t k = 0; 586 size_t k = 0;
568 ValueType* table = m_table; 587 ValueType* table = m_table;
569 size_t sizeMask = m_tableSizeMask; 588 size_t sizeMask = m_tableSizeMask;
570 unsigned h = HashTranslator::hash(key); 589 unsigned h = HashTranslator::hash(key);
571 size_t i = h & sizeMask; 590 size_t i = h & sizeMask;
572 591
573 #if DUMP_HASHTABLE_STATS 592 #if DUMP_HASHTABLE_STATS
574 atomicIncrement(&HashTableStats::numAccesses); 593 atomicIncrement(&HashTableStats::numAccesses);
575 int probeCount = 0; 594 int probeCount = 0;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 k = 1 | doubleHash(h); 637 k = 1 | doubleHash(h);
619 i = (i + k) & sizeMask; 638 i = (i + k) & sizeMask;
620 } 639 }
621 } 640 }
622 641
623 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> 642 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator>
624 template<typename HashTranslator, typename T> 643 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) 644 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 { 645 {
627 ASSERT(m_table); 646 ASSERT(m_table);
647 registerModification();
628 648
629 size_t k = 0; 649 size_t k = 0;
630 ValueType* table = m_table; 650 ValueType* table = m_table;
631 size_t sizeMask = m_tableSizeMask; 651 size_t sizeMask = m_tableSizeMask;
632 unsigned h = HashTranslator::hash(key); 652 unsigned h = HashTranslator::hash(key);
633 size_t i = h & sizeMask; 653 size_t i = h & sizeMask;
634 654
635 #if DUMP_HASHTABLE_STATS 655 #if DUMP_HASHTABLE_STATS
636 atomicIncrement(&HashTableStats::numAccesses); 656 atomicIncrement(&HashTableStats::numAccesses);
637 int probeCount = 0; 657 int probeCount = 0;
(...skipping 590 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) 1248 inline bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTa bleConstIteratorAdapter<T, U>& b)
1229 { 1249 {
1230 return a.m_impl != b.m_impl; 1250 return a.m_impl != b.m_impl;
1231 } 1251 }
1232 1252
1233 } // namespace WTF 1253 } // namespace WTF
1234 1254
1235 #include "wtf/HashIterators.h" 1255 #include "wtf/HashIterators.h"
1236 1256
1237 #endif // WTF_HashTable_h 1257 #endif // WTF_HashTable_h
OLDNEW
« no previous file with comments | « Source/platform/heap/Visitor.h ('k') | Source/wtf/LinkedHashSet.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698