| 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 503 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 514         { | 514         { | 
| 515             // isAllocationAllowed check should be at the last because it's | 515             // isAllocationAllowed check should be at the last because it's | 
| 516             // expensive. | 516             // expensive. | 
| 517             return m_keyCount * m_minLoad < m_tableSize | 517             return m_keyCount * m_minLoad < m_tableSize | 
| 518                 && m_tableSize > KeyTraits::minimumTableSize | 518                 && m_tableSize > KeyTraits::minimumTableSize | 
| 519                 && Allocator::isAllocationAllowed(); | 519                 && Allocator::isAllocationAllowed(); | 
| 520         } | 520         } | 
| 521         ValueType* expand(ValueType* entry = 0); | 521         ValueType* expand(ValueType* entry = 0); | 
| 522         void shrink() { rehash(m_tableSize / 2, 0); } | 522         void shrink() { rehash(m_tableSize / 2, 0); } | 
| 523 | 523 | 
| 524         ValueType* expandBuffer(unsigned newTableSize, ValueType* entry, bool&); |  | 
| 525         ValueType* rehashTo(ValueType* newTable, unsigned newTableSize, ValueTyp
      e* entry); |  | 
| 526         ValueType* rehash(unsigned newTableSize, ValueType* entry); | 524         ValueType* rehash(unsigned newTableSize, ValueType* entry); | 
| 527         ValueType* reinsert(ValueType&); | 525         ValueType* reinsert(ValueType&); | 
| 528 | 526 | 
| 529         static void initializeBucket(ValueType& bucket); | 527         static void initializeBucket(ValueType& bucket); | 
| 530         static void deleteBucket(ValueType& bucket) { bucket.~ValueType(); Trait
      s::constructDeletedValue(bucket, Allocator::isGarbageCollected); } | 528         static void deleteBucket(ValueType& bucket) { bucket.~ValueType(); Trait
      s::constructDeletedValue(bucket, Allocator::isGarbageCollected); } | 
| 531 | 529 | 
| 532         FullLookupType makeLookupResult(ValueType* position, bool found, unsigne
      d hash) | 530         FullLookupType makeLookupResult(ValueType* position, bool found, unsigne
      d hash) | 
| 533             { return FullLookupType(LookupType(position, found), hash); } | 531             { return FullLookupType(LookupType(position, found), hash); } | 
| 534 | 532 | 
| 535         iterator makeIterator(ValueType* pos) { return iterator(pos, m_table + m
      _tableSize, this); } | 533         iterator makeIterator(ValueType* pos) { return iterator(pos, m_table + m
      _tableSize, this); } | 
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1041             newSize = m_tableSize; | 1039             newSize = m_tableSize; | 
| 1042         } else { | 1040         } else { | 
| 1043             newSize = m_tableSize * 2; | 1041             newSize = m_tableSize * 2; | 
| 1044             RELEASE_ASSERT(newSize > m_tableSize); | 1042             RELEASE_ASSERT(newSize > m_tableSize); | 
| 1045         } | 1043         } | 
| 1046 | 1044 | 
| 1047         return rehash(newSize, entry); | 1045         return rehash(newSize, entry); | 
| 1048     } | 1046     } | 
| 1049 | 1047 | 
| 1050     template<typename Key, typename Value, typename Extractor, typename HashFunc
      tions, typename Traits, typename KeyTraits, typename Allocator> | 1048     template<typename Key, typename Value, typename Extractor, typename HashFunc
      tions, typename Traits, typename KeyTraits, typename Allocator> | 
| 1051     Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Al
      locator>::expandBuffer(unsigned newTableSize, Value* entry, bool& success) | 1049     Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Al
      locator>::rehash(unsigned newTableSize, Value* entry) | 
| 1052     { |  | 
| 1053         success = false; |  | 
| 1054         ASSERT(m_tableSize < newTableSize); |  | 
| 1055         if (!Allocator::expandHashTableBacking(m_table, newTableSize * sizeof(Va
      lueType))) |  | 
| 1056             return 0; |  | 
| 1057 |  | 
| 1058         success = true; |  | 
| 1059 |  | 
| 1060         Value* newEntry = nullptr; |  | 
| 1061         unsigned oldTableSize = m_tableSize; |  | 
| 1062         ValueType* originalTable = m_table; |  | 
| 1063 |  | 
| 1064         ValueType* temporaryTable = allocateTable(oldTableSize); |  | 
| 1065         for (unsigned i = 0; i < oldTableSize; i++) { |  | 
| 1066             if (&m_table[i] == entry) |  | 
| 1067                 newEntry = &temporaryTable[i]; |  | 
| 1068             Mover<ValueType, Allocator, Traits::needsDestruction>::move(m_table[
      i], temporaryTable[i]); |  | 
| 1069         } |  | 
| 1070         m_table = temporaryTable; |  | 
| 1071 |  | 
| 1072         if (Traits::emptyValueIsZero) { |  | 
| 1073             memset(originalTable, 0, newTableSize * sizeof(ValueType)); |  | 
| 1074         } else { |  | 
| 1075             for (unsigned i = 0; i < newTableSize; i++) |  | 
| 1076                 initializeBucket(originalTable[i]); |  | 
| 1077         } |  | 
| 1078         newEntry = rehashTo(originalTable, newTableSize, newEntry); |  | 
| 1079         deleteAllBucketsAndDeallocate(temporaryTable, oldTableSize); |  | 
| 1080 |  | 
| 1081         return newEntry; |  | 
| 1082     } |  | 
| 1083 |  | 
| 1084 template<typename Key, typename Value, typename Extractor, typename HashFunction
      s, typename Traits, typename KeyTraits, typename Allocator> |  | 
| 1085     Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Al
      locator>::rehashTo(ValueType* newTable, unsigned newTableSize, Value* entry) |  | 
| 1086     { | 1050     { | 
| 1087         unsigned oldTableSize = m_tableSize; | 1051         unsigned oldTableSize = m_tableSize; | 
| 1088         ValueType* oldTable = m_table; | 1052         ValueType* oldTable = m_table; | 
| 1089 | 1053 | 
| 1090 #if DUMP_HASHTABLE_STATS | 1054 #if DUMP_HASHTABLE_STATS | 
| 1091         if (oldTableSize != 0) | 1055         if (oldTableSize != 0) | 
| 1092             atomicIncrement(&HashTableStats::numRehashes); | 1056             atomicIncrement(&HashTableStats::numRehashes); | 
| 1093 #endif | 1057 #endif | 
| 1094 | 1058 | 
| 1095 #if DUMP_HASHTABLE_STATS_PER_TABLE | 1059 #if DUMP_HASHTABLE_STATS_PER_TABLE | 
| 1096         if (oldTableSize != 0) | 1060         if (oldTableSize != 0) | 
| 1097             ++m_stats->numRehashes; | 1061             ++m_stats->numRehashes; | 
| 1098 #endif | 1062 #endif | 
| 1099 | 1063 | 
| 1100         m_table = newTable; | 1064         m_table = allocateTable(newTableSize); | 
| 1101         m_tableSize = newTableSize; | 1065         m_tableSize = newTableSize; | 
| 1102 | 1066 | 
| 1103         Value* newEntry = 0; | 1067         Value* newEntry = 0; | 
| 1104         for (unsigned i = 0; i != oldTableSize; ++i) { | 1068         for (unsigned i = 0; i != oldTableSize; ++i) { | 
| 1105             if (isEmptyOrDeletedBucket(oldTable[i])) { | 1069             if (isEmptyOrDeletedBucket(oldTable[i])) { | 
| 1106                 ASSERT(&oldTable[i] != entry); | 1070                 ASSERT(&oldTable[i] != entry); | 
| 1107                 continue; | 1071                 continue; | 
| 1108             } | 1072             } | 
|  | 1073 | 
| 1109             Value* reinsertedEntry = reinsert(oldTable[i]); | 1074             Value* reinsertedEntry = reinsert(oldTable[i]); | 
| 1110             if (&oldTable[i] == entry) { | 1075             if (&oldTable[i] == entry) { | 
| 1111                 ASSERT(!newEntry); | 1076                 ASSERT(!newEntry); | 
| 1112                 newEntry = reinsertedEntry; | 1077                 newEntry = reinsertedEntry; | 
| 1113             } | 1078             } | 
| 1114         } | 1079         } | 
| 1115 | 1080 | 
| 1116         m_deletedCount = 0; | 1081         m_deletedCount = 0; | 
| 1117 | 1082 | 
| 1118         return newEntry; |  | 
| 1119     } |  | 
| 1120 |  | 
| 1121     template<typename Key, typename Value, typename Extractor, typename HashFunc
      tions, typename Traits, typename KeyTraits, typename Allocator> |  | 
| 1122     Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Al
      locator>::rehash(unsigned newTableSize, Value* entry) |  | 
| 1123     { |  | 
| 1124         unsigned oldTableSize = m_tableSize; |  | 
| 1125         ValueType* oldTable = m_table; |  | 
| 1126 |  | 
| 1127 #if DUMP_HASHTABLE_STATS |  | 
| 1128         if (oldTableSize != 0) |  | 
| 1129             atomicIncrement(&HashTableStats::numRehashes); |  | 
| 1130 #endif |  | 
| 1131 |  | 
| 1132 #if DUMP_HASHTABLE_STATS_PER_TABLE |  | 
| 1133         if (oldTableSize != 0) |  | 
| 1134             ++m_stats->numRehashes; |  | 
| 1135 #endif |  | 
| 1136 |  | 
| 1137         // The Allocator::isGarbageCollected check is not needed. |  | 
| 1138         // The check is just a static hint for a compiler to indicate that |  | 
| 1139         // Base::expandBuffer returns false if Allocator is a DefaultAllocator. |  | 
| 1140         if (Allocator::isGarbageCollected && newTableSize > oldTableSize) { |  | 
| 1141             bool success; |  | 
| 1142             Value* newEntry = expandBuffer(newTableSize, entry, success); |  | 
| 1143             if (success) |  | 
| 1144                 return newEntry; |  | 
| 1145         } |  | 
| 1146 |  | 
| 1147         ValueType* newTable = allocateTable(newTableSize); |  | 
| 1148         Value* newEntry = rehashTo(newTable, newTableSize, entry); |  | 
| 1149         deleteAllBucketsAndDeallocate(oldTable, oldTableSize); | 1083         deleteAllBucketsAndDeallocate(oldTable, oldTableSize); | 
| 1150 | 1084 | 
| 1151         return newEntry; | 1085         return newEntry; | 
| 1152     } | 1086     } | 
| 1153 | 1087 | 
| 1154     template<typename Key, typename Value, typename Extractor, typename HashFunc
      tions, typename Traits, typename KeyTraits, typename Allocator> | 1088     template<typename Key, typename Value, typename Extractor, typename HashFunc
      tions, typename Traits, typename KeyTraits, typename Allocator> | 
| 1155     void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allo
      cator>::clear() | 1089     void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allo
      cator>::clear() | 
| 1156     { | 1090     { | 
| 1157         registerModification(); | 1091         registerModification(); | 
| 1158         if (!m_table) | 1092         if (!m_table) | 
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1444         CollectionIterator end(toBeRemoved.end()); | 1378         CollectionIterator end(toBeRemoved.end()); | 
| 1445         for (CollectionIterator it(toBeRemoved.begin()); it != end; ++it) | 1379         for (CollectionIterator it(toBeRemoved.begin()); it != end; ++it) | 
| 1446             collection.remove(*it); | 1380             collection.remove(*it); | 
| 1447     } | 1381     } | 
| 1448 | 1382 | 
| 1449 } // namespace WTF | 1383 } // namespace WTF | 
| 1450 | 1384 | 
| 1451 #include "wtf/HashIterators.h" | 1385 #include "wtf/HashIterators.h" | 
| 1452 | 1386 | 
| 1453 #endif // WTF_HashTable_h | 1387 #endif // WTF_HashTable_h | 
| OLD | NEW | 
|---|