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

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

Issue 138643003: Simpler return value of HashTable::add/HashMap:add and others (Closed)
Patch Set: Daily master update (now with base url?) Created 6 years, 10 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
« no previous file with comments | « Source/wtf/HashMap.h ('k') | Source/wtf/InstanceCounter.cpp » ('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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 template<typename T> struct Mover<T, true> { static void move(T& from, T& to ) { hashTableSwap(from, to); } }; 198 template<typename T> struct Mover<T, true> { static void move(T& from, T& to ) { hashTableSwap(from, to); } };
199 template<typename T> struct Mover<T, false> { static void move(T& from, T& t o) { to = from; } }; 199 template<typename T> struct Mover<T, false> { static void move(T& from, T& t o) { to = from; } };
200 200
201 template<typename HashFunctions> class IdentityHashTranslator { 201 template<typename HashFunctions> class IdentityHashTranslator {
202 public: 202 public:
203 template<typename T> static unsigned hash(const T& key) { return HashFun ctions::hash(key); } 203 template<typename T> static unsigned hash(const T& key) { return HashFun ctions::hash(key); }
204 template<typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a, b); } 204 template<typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a, b); }
205 template<typename T, typename U, typename V> static void translate(T& lo cation, const U&, const V& value) { location = value; } 205 template<typename T, typename U, typename V> static void translate(T& lo cation, const U&, const V& value) { location = value; }
206 }; 206 };
207 207
208 template<typename IteratorType> struct HashTableAddResult { 208 template<typename ValueType> struct HashTableAddResult {
209 HashTableAddResult(IteratorType iter, bool isNewEntry) : iterator(iter), isNewEntry(isNewEntry) { } 209 HashTableAddResult(ValueType* storedValue, bool isNewEntry) : storedValu e(storedValue), isNewEntry(isNewEntry) { }
210 IteratorType iterator; 210 ValueType* storedValue;
211 bool isNewEntry; 211 bool isNewEntry;
212 }; 212 };
213 213
214 template<typename Value, typename Extractor, typename KeyTraits> 214 template<typename Value, typename Extractor, typename KeyTraits>
215 struct HashTableHelper { 215 struct HashTableHelper {
216 static bool isEmptyBucket(const Value& value) { return isHashTraitsEmpty Value<KeyTraits>(Extractor::extract(value)); } 216 static bool isEmptyBucket(const Value& value) { return isHashTraitsEmpty Value<KeyTraits>(Extractor::extract(value)); }
217 static bool isDeletedBucket(const Value& value) { return KeyTraits::isDe letedValue(Extractor::extract(value)); } 217 static bool isDeletedBucket(const Value& value) { return KeyTraits::isDe letedValue(Extractor::extract(value)); }
218 static bool isEmptyOrDeletedBucket(const Value& value) { return isEmptyB ucket(value) || isDeletedBucket(value); } 218 static bool isEmptyOrDeletedBucket(const Value& value) { return isEmptyB ucket(value) || isDeletedBucket(value); }
219 }; 219 };
220 220
221 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> 221 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator>
222 class HashTable { 222 class HashTable {
223 public: 223 public:
224 typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator> iterator; 224 typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator> iterator;
225 typedef HashTableConstIterator<Key, Value, Extractor, HashFunctions, Tra its, KeyTraits, Allocator> const_iterator; 225 typedef HashTableConstIterator<Key, Value, Extractor, HashFunctions, Tra its, KeyTraits, Allocator> const_iterator;
226 typedef Traits ValueTraits; 226 typedef Traits ValueTraits;
227 typedef Key KeyType; 227 typedef Key KeyType;
228 typedef typename KeyTraits::PeekInType KeyPeekInType; 228 typedef typename KeyTraits::PeekInType KeyPeekInType;
229 typedef typename KeyTraits::PassInType KeyPassInType; 229 typedef typename KeyTraits::PassInType KeyPassInType;
230 typedef Value ValueType; 230 typedef Value ValueType;
231 typedef typename Traits::PeekInType ValuePeekInType; 231 typedef typename Traits::PeekInType ValuePeekInType;
232 typedef IdentityHashTranslator<HashFunctions> IdentityTranslatorType; 232 typedef IdentityHashTranslator<HashFunctions> IdentityTranslatorType;
233 typedef HashTableAddResult<iterator> AddResult; 233 typedef HashTableAddResult<ValueType> AddResult;
234 234
235 #if DUMP_HASHTABLE_STATS_PER_TABLE 235 #if DUMP_HASHTABLE_STATS_PER_TABLE
236 struct Stats { 236 struct Stats {
237 Stats() 237 Stats()
238 : numAccesses(0) 238 : numAccesses(0)
239 , numRehashes(0) 239 , numRehashes(0)
240 , numRemoves(0) 240 , numRemoves(0)
241 , numReinserts(0) 241 , numReinserts(0)
242 , maxCollisions(0) 242 , maxCollisions(0)
243 , numCollisions(0) 243 , numCollisions(0)
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 ValueType* entry; 680 ValueType* entry;
681 while (1) { 681 while (1) {
682 entry = table + i; 682 entry = table + i;
683 683
684 // we count on the compiler to optimize out this branch 684 // we count on the compiler to optimize out this branch
685 if (HashFunctions::safeToCompareToEmptyOrDeleted) { 685 if (HashFunctions::safeToCompareToEmptyOrDeleted) {
686 if (isEmptyBucket(*entry)) 686 if (isEmptyBucket(*entry))
687 break; 687 break;
688 688
689 if (HashTranslator::equal(Extractor::extract(*entry), key)) 689 if (HashTranslator::equal(Extractor::extract(*entry), key))
690 return AddResult(makeKnownGoodIterator(entry), false); 690 return AddResult(entry, false);
691 691
692 if (isDeletedBucket(*entry)) 692 if (isDeletedBucket(*entry))
693 deletedEntry = entry; 693 deletedEntry = entry;
694 } else { 694 } else {
695 if (isEmptyBucket(*entry)) 695 if (isEmptyBucket(*entry))
696 break; 696 break;
697 697
698 if (isDeletedBucket(*entry)) 698 if (isDeletedBucket(*entry))
699 deletedEntry = entry; 699 deletedEntry = entry;
700 else if (HashTranslator::equal(Extractor::extract(*entry), key)) 700 else if (HashTranslator::equal(Extractor::extract(*entry), key))
701 return AddResult(makeKnownGoodIterator(entry), false); 701 return AddResult(entry, false);
702 } 702 }
703 #if DUMP_HASHTABLE_STATS 703 #if DUMP_HASHTABLE_STATS
704 ++probeCount; 704 ++probeCount;
705 HashTableStats::recordCollisionAtCount(probeCount); 705 HashTableStats::recordCollisionAtCount(probeCount);
706 #endif 706 #endif
707 707
708 #if DUMP_HASHTABLE_STATS_PER_TABLE 708 #if DUMP_HASHTABLE_STATS_PER_TABLE
709 ++perTableProbeCount; 709 ++perTableProbeCount;
710 m_stats->recordCollisionAtCount(perTableProbeCount); 710 m_stats->recordCollisionAtCount(perTableProbeCount);
711 #endif 711 #endif
(...skipping 12 matching lines...) Expand all
724 HashTranslator::translate(*entry, key, extra); 724 HashTranslator::translate(*entry, key, extra);
725 725
726 ++m_keyCount; 726 ++m_keyCount;
727 727
728 if (shouldExpand()) { 728 if (shouldExpand()) {
729 // FIXME: This makes an extra copy on expand. Probably not that bad since 729 // FIXME: This makes an extra copy on expand. Probably not that bad since
730 // expand is rare, but would be better to have a version of expand t hat can 730 // expand is rare, but would be better to have a version of expand t hat can
731 // follow a pivot entry and return the new position. 731 // follow a pivot entry and return the new position.
732 typename WTF::RemoveReference<KeyPassInType>::Type enteredKey = Extr actor::extract(*entry); 732 typename WTF::RemoveReference<KeyPassInType>::Type enteredKey = Extr actor::extract(*entry);
733 expand(); 733 expand();
734 AddResult result(find(enteredKey), true); 734 iterator findResult = find(enteredKey);
735 ASSERT(result.iterator != end()); 735 ASSERT(findResult != end());
736 ValueType* resultValue = findResult.get();
737 AddResult result(resultValue, true);
736 return result; 738 return result;
737 } 739 }
738 740
739 return AddResult(makeKnownGoodIterator(entry), true); 741 return AddResult(entry, true);
740 } 742 }
741 743
742 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> 744 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator>
743 template<typename HashTranslator, typename T, typename Extra> 745 template<typename HashTranslator, typename T, typename Extra>
744 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) 746 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)
745 { 747 {
746 if (!m_table) 748 if (!m_table)
747 expand(); 749 expand();
748 750
749 FullLookupType lookupResult = fullLookupForWriting<HashTranslator>(key); 751 FullLookupType lookupResult = fullLookupForWriting<HashTranslator>(key);
750 752
751 ValueType* entry = lookupResult.first.first; 753 ValueType* entry = lookupResult.first.first;
752 bool found = lookupResult.first.second; 754 bool found = lookupResult.first.second;
753 unsigned h = lookupResult.second; 755 unsigned h = lookupResult.second;
754 756
755 if (found) 757 if (found)
756 return AddResult(makeKnownGoodIterator(entry), false); 758 return AddResult(entry, false);
757 759
758 if (isDeletedBucket(*entry)) { 760 if (isDeletedBucket(*entry)) {
759 initializeBucket(*entry); 761 initializeBucket(*entry);
760 --m_deletedCount; 762 --m_deletedCount;
761 } 763 }
762 764
763 HashTranslator::translate(*entry, key, extra, h); 765 HashTranslator::translate(*entry, key, extra, h);
764 ++m_keyCount; 766 ++m_keyCount;
765 if (shouldExpand()) { 767 if (shouldExpand()) {
766 // FIXME: This makes an extra copy on expand. Probably not that bad since 768 // FIXME: This makes an extra copy on expand. Probably not that bad since
767 // expand is rare, but would be better to have a version of expand t hat can 769 // expand is rare, but would be better to have a version of expand t hat can
768 // follow a pivot entry and return the new position. 770 // follow a pivot entry and return the new position.
769 typename WTF::RemoveReference<KeyPassInType>::Type enteredKey = Extr actor::extract(*entry); 771 typename WTF::RemoveReference<KeyPassInType>::Type enteredKey = Extr actor::extract(*entry);
770 expand(); 772 expand();
771 AddResult result(find(enteredKey), true); 773 iterator findResult = find(enteredKey);
772 ASSERT(result.iterator != end()); 774 ASSERT(findResult != end());
775 ValueType* resultValue = findResult.get();
776 AddResult result(resultValue, true);
773 return result; 777 return result;
774 } 778 }
775 779
776 return AddResult(makeKnownGoodIterator(entry), true); 780 return AddResult(entry, true);
777 } 781 }
778 782
779 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator> 783 template<typename Key, typename Value, typename Extractor, typename HashFunc tions, typename Traits, typename KeyTraits, typename Allocator>
780 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait s, Allocator>::reinsert(ValueType& entry) 784 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait s, Allocator>::reinsert(ValueType& entry)
781 { 785 {
782 ASSERT(m_table); 786 ASSERT(m_table);
783 ASSERT(!lookupForWriting(Extractor::extract(entry)).second); 787 ASSERT(!lookupForWriting(Extractor::extract(entry)).second);
784 ASSERT(!isDeletedBucket(*(lookupForWriting(Extractor::extract(entry)).fi rst))); 788 ASSERT(!isDeletedBucket(*(lookupForWriting(Extractor::extract(entry)).fi rst)));
785 #if DUMP_HASHTABLE_STATS 789 #if DUMP_HASHTABLE_STATS
786 atomicIncrement(&HashTableStats::numReinserts); 790 atomicIncrement(&HashTableStats::numReinserts);
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 inline bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTa bleConstIteratorAdapter<T, U>& b) 1164 inline bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTa bleConstIteratorAdapter<T, U>& b)
1161 { 1165 {
1162 return a.m_impl != b.m_impl; 1166 return a.m_impl != b.m_impl;
1163 } 1167 }
1164 1168
1165 } // namespace WTF 1169 } // namespace WTF
1166 1170
1167 #include "wtf/HashIterators.h" 1171 #include "wtf/HashIterators.h"
1168 1172
1169 #endif // WTF_HashTable_h 1173 #endif // WTF_HashTable_h
OLDNEW
« no previous file with comments | « Source/wtf/HashMap.h ('k') | Source/wtf/InstanceCounter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698