LLVM API Documentation
00001 //===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the DenseMap class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_ADT_DENSEMAP_H 00015 #define LLVM_ADT_DENSEMAP_H 00016 00017 #include "llvm/Support/DataTypes.h" 00018 #include "llvm/Support/MathExtras.h" 00019 #include <cassert> 00020 #include <utility> 00021 00022 namespace llvm { 00023 00024 template<typename T> 00025 struct DenseMapInfo { 00026 //static inline T getEmptyKey(); 00027 //static inline T getTombstoneKey(); 00028 //static unsigned getHashValue(const T &Val); 00029 //static bool isEqual(const T &LHS, const T &RHS); 00030 //static bool isPod() 00031 }; 00032 00033 // Provide DenseMapInfo for all pointers. 00034 template<typename T> 00035 struct DenseMapInfo<T*> { 00036 static inline T* getEmptyKey() { return reinterpret_cast<T*>(-1); } 00037 static inline T* getTombstoneKey() { return reinterpret_cast<T*>(-2); } 00038 static unsigned getHashValue(const T *PtrVal) { 00039 return (unsigned((uintptr_t)PtrVal) >> 4) ^ 00040 (unsigned((uintptr_t)PtrVal) >> 9); 00041 } 00042 static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } 00043 static bool isPod() { return true; } 00044 }; 00045 00046 // Provide DenseMapInfo for unsigned ints. 00047 template<> struct DenseMapInfo<unsigned> { 00048 static inline unsigned getEmptyKey() { return ~0; } 00049 static inline unsigned getTombstoneKey() { return ~0 - 1; } 00050 static unsigned getHashValue(const unsigned& Val) { return Val * 37; } 00051 static bool isPod() { return true; } 00052 static bool isEqual(const unsigned& LHS, const unsigned& RHS) { 00053 return LHS == RHS; 00054 } 00055 }; 00056 00057 // Provide DenseMapInfo for unsigned longs. 00058 template<> struct DenseMapInfo<unsigned long> { 00059 static inline unsigned long getEmptyKey() { return ~0L; } 00060 static inline unsigned long getTombstoneKey() { return ~0L - 1L; } 00061 static unsigned getHashValue(const unsigned long& Val) { 00062 return (unsigned)(Val * 37L); 00063 } 00064 static bool isPod() { return true; } 00065 static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) { 00066 return LHS == RHS; 00067 } 00068 }; 00069 00070 // Provide DenseMapInfo for all pairs whose members have info. 00071 template<typename T, typename U> 00072 struct DenseMapInfo<std::pair<T, U> > { 00073 typedef std::pair<T, U> Pair; 00074 typedef DenseMapInfo<T> FirstInfo; 00075 typedef DenseMapInfo<U> SecondInfo; 00076 00077 static inline Pair getEmptyKey() { 00078 return std::make_pair(FirstInfo::getEmptyKey(), 00079 SecondInfo::getEmptyKey()); 00080 } 00081 static inline Pair getTombstoneKey() { 00082 return std::make_pair(FirstInfo::getTombstoneKey(), 00083 SecondInfo::getEmptyKey()); 00084 } 00085 static unsigned getHashValue(const Pair& PairVal) { 00086 uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32 00087 | (uint64_t)SecondInfo::getHashValue(PairVal.second); 00088 key += ~(key << 32); 00089 key ^= (key >> 22); 00090 key += ~(key << 13); 00091 key ^= (key >> 8); 00092 key += (key << 3); 00093 key ^= (key >> 15); 00094 key += ~(key << 27); 00095 key ^= (key >> 31); 00096 return (unsigned)key; 00097 } 00098 static bool isEqual(const Pair& LHS, const Pair& RHS) { return LHS == RHS; } 00099 static bool isPod() { return FirstInfo::isPod() && SecondInfo::isPod(); } 00100 }; 00101 00102 template<typename KeyT, typename ValueT, 00103 typename KeyInfoT = DenseMapInfo<KeyT>, 00104 typename ValueInfoT = DenseMapInfo<ValueT> > 00105 class DenseMapIterator; 00106 template<typename KeyT, typename ValueT, 00107 typename KeyInfoT = DenseMapInfo<KeyT>, 00108 typename ValueInfoT = DenseMapInfo<ValueT> > 00109 class DenseMapConstIterator; 00110 00111 template<typename KeyT, typename ValueT, 00112 typename KeyInfoT = DenseMapInfo<KeyT>, 00113 typename ValueInfoT = DenseMapInfo<ValueT> > 00114 class DenseMap { 00115 typedef std::pair<KeyT, ValueT> BucketT; 00116 unsigned NumBuckets; 00117 BucketT *Buckets; 00118 00119 unsigned NumEntries; 00120 unsigned NumTombstones; 00121 public: 00122 typedef KeyT key_type; 00123 typedef ValueT mapped_type; 00124 typedef BucketT value_type; 00125 00126 DenseMap(const DenseMap& other) { 00127 NumBuckets = 0; 00128 CopyFrom(other); 00129 } 00130 00131 explicit DenseMap(unsigned NumInitBuckets = 64) { 00132 init(NumInitBuckets); 00133 } 00134 00135 ~DenseMap() { 00136 const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); 00137 for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { 00138 if (!KeyInfoT::isEqual(P->first, EmptyKey) && 00139 !KeyInfoT::isEqual(P->first, TombstoneKey)) 00140 P->second.~ValueT(); 00141 P->first.~KeyT(); 00142 } 00143 operator delete(Buckets); 00144 } 00145 00146 typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator; 00147 typedef DenseMapConstIterator<KeyT, ValueT, KeyInfoT> const_iterator; 00148 inline iterator begin() { 00149 return iterator(Buckets, Buckets+NumBuckets); 00150 } 00151 inline iterator end() { 00152 return iterator(Buckets+NumBuckets, Buckets+NumBuckets); 00153 } 00154 inline const_iterator begin() const { 00155 return const_iterator(Buckets, Buckets+NumBuckets); 00156 } 00157 inline const_iterator end() const { 00158 return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets); 00159 } 00160 00161 bool empty() const { return NumEntries == 0; } 00162 unsigned size() const { return NumEntries; } 00163 00164 /// Grow the densemap so that it has at least Size buckets. Does not shrink 00165 void resize(size_t Size) { grow(Size); } 00166 00167 void clear() { 00168 // If the capacity of the array is huge, and the # elements used is small, 00169 // shrink the array. 00170 if (NumEntries * 4 < NumBuckets && NumBuckets > 64) { 00171 shrink_and_clear(); 00172 return; 00173 } 00174 00175 const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); 00176 for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { 00177 if (!KeyInfoT::isEqual(P->first, EmptyKey)) { 00178 if (!KeyInfoT::isEqual(P->first, TombstoneKey)) { 00179 P->second.~ValueT(); 00180 --NumEntries; 00181 } 00182 P->first = EmptyKey; 00183 } 00184 } 00185 assert(NumEntries == 0 && "Node count imbalance!"); 00186 NumTombstones = 0; 00187 } 00188 00189 /// count - Return true if the specified key is in the map. 00190 bool count(const KeyT &Val) const { 00191 BucketT *TheBucket; 00192 return LookupBucketFor(Val, TheBucket); 00193 } 00194 00195 iterator find(const KeyT &Val) { 00196 BucketT *TheBucket; 00197 if (LookupBucketFor(Val, TheBucket)) 00198 return iterator(TheBucket, Buckets+NumBuckets); 00199 return end(); 00200 } 00201 const_iterator find(const KeyT &Val) const { 00202 BucketT *TheBucket; 00203 if (LookupBucketFor(Val, TheBucket)) 00204 return const_iterator(TheBucket, Buckets+NumBuckets); 00205 return end(); 00206 } 00207 00208 /// lookup - Return the entry for the specified key, or a default 00209 /// constructed value if no such entry exists. 00210 ValueT lookup(const KeyT &Val) const { 00211 BucketT *TheBucket; 00212 if (LookupBucketFor(Val, TheBucket)) 00213 return TheBucket->second; 00214 return ValueT(); 00215 } 00216 00217 std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) { 00218 BucketT *TheBucket; 00219 if (LookupBucketFor(KV.first, TheBucket)) 00220 return std::make_pair(iterator(TheBucket, Buckets+NumBuckets), 00221 false); // Already in map. 00222 00223 // Otherwise, insert the new element. 00224 TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket); 00225 return std::make_pair(iterator(TheBucket, Buckets+NumBuckets), 00226 true); 00227 } 00228 00229 /// insert - Range insertion of pairs. 00230 template<typename InputIt> 00231 void insert(InputIt I, InputIt E) { 00232 for (; I != E; ++I) 00233 insert(*I); 00234 } 00235 00236 00237 bool erase(const KeyT &Val) { 00238 BucketT *TheBucket; 00239 if (!LookupBucketFor(Val, TheBucket)) 00240 return false; // not in map. 00241 00242 TheBucket->second.~ValueT(); 00243 TheBucket->first = getTombstoneKey(); 00244 --NumEntries; 00245 ++NumTombstones; 00246 return true; 00247 } 00248 bool erase(iterator I) { 00249 BucketT *TheBucket = &*I; 00250 TheBucket->second.~ValueT(); 00251 TheBucket->first = getTombstoneKey(); 00252 --NumEntries; 00253 ++NumTombstones; 00254 return true; 00255 } 00256 00257 value_type& FindAndConstruct(const KeyT &Key) { 00258 BucketT *TheBucket; 00259 if (LookupBucketFor(Key, TheBucket)) 00260 return *TheBucket; 00261 00262 return *InsertIntoBucket(Key, ValueT(), TheBucket); 00263 } 00264 00265 ValueT &operator[](const KeyT &Key) { 00266 return FindAndConstruct(Key).second; 00267 } 00268 00269 DenseMap& operator=(const DenseMap& other) { 00270 CopyFrom(other); 00271 return *this; 00272 } 00273 00274 private: 00275 void CopyFrom(const DenseMap& other) { 00276 if (NumBuckets != 0 && (!KeyInfoT::isPod() || !ValueInfoT::isPod())) { 00277 const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); 00278 for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { 00279 if (!KeyInfoT::isEqual(P->first, EmptyKey) && 00280 !KeyInfoT::isEqual(P->first, TombstoneKey)) 00281 P->second.~ValueT(); 00282 P->first.~KeyT(); 00283 } 00284 } 00285 00286 NumEntries = other.NumEntries; 00287 NumTombstones = other.NumTombstones; 00288 00289 if (NumBuckets) 00290 operator delete(Buckets); 00291 Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * 00292 other.NumBuckets)); 00293 00294 if (KeyInfoT::isPod() && ValueInfoT::isPod()) 00295 memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT)); 00296 else 00297 for (size_t i = 0; i < other.NumBuckets; ++i) { 00298 new (&Buckets[i].first) KeyT(other.Buckets[i].first); 00299 if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) && 00300 !KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey())) 00301 new (&Buckets[i].second) ValueT(other.Buckets[i].second); 00302 } 00303 NumBuckets = other.NumBuckets; 00304 } 00305 00306 BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value, 00307 BucketT *TheBucket) { 00308 // If the load of the hash table is more than 3/4, or if fewer than 1/8 of 00309 // the buckets are empty (meaning that many are filled with tombstones), 00310 // grow the table. 00311 // 00312 // The later case is tricky. For example, if we had one empty bucket with 00313 // tons of tombstones, failing lookups (e.g. for insertion) would have to 00314 // probe almost the entire table until it found the empty bucket. If the 00315 // table completely filled with tombstones, no lookup would ever succeed, 00316 // causing infinite loops in lookup. 00317 if (NumEntries*4 >= NumBuckets*3 || 00318 NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) { 00319 this->grow(NumBuckets * 2); 00320 LookupBucketFor(Key, TheBucket); 00321 } 00322 ++NumEntries; 00323 00324 // If we are writing over a tombstone, remember this. 00325 if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey())) 00326 --NumTombstones; 00327 00328 TheBucket->first = Key; 00329 new (&TheBucket->second) ValueT(Value); 00330 return TheBucket; 00331 } 00332 00333 static unsigned getHashValue(const KeyT &Val) { 00334 return KeyInfoT::getHashValue(Val); 00335 } 00336 static const KeyT getEmptyKey() { 00337 return KeyInfoT::getEmptyKey(); 00338 } 00339 static const KeyT getTombstoneKey() { 00340 return KeyInfoT::getTombstoneKey(); 00341 } 00342 00343 /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in 00344 /// FoundBucket. If the bucket contains the key and a value, this returns 00345 /// true, otherwise it returns a bucket with an empty marker or tombstone and 00346 /// returns false. 00347 bool LookupBucketFor(const KeyT &Val, BucketT *&FoundBucket) const { 00348 unsigned BucketNo = getHashValue(Val); 00349 unsigned ProbeAmt = 1; 00350 BucketT *BucketsPtr = Buckets; 00351 00352 // FoundTombstone - Keep track of whether we find a tombstone while probing. 00353 BucketT *FoundTombstone = 0; 00354 const KeyT EmptyKey = getEmptyKey(); 00355 const KeyT TombstoneKey = getTombstoneKey(); 00356 assert(!KeyInfoT::isEqual(Val, EmptyKey) && 00357 !KeyInfoT::isEqual(Val, TombstoneKey) && 00358 "Empty/Tombstone value shouldn't be inserted into map!"); 00359 00360 while (1) { 00361 BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1)); 00362 // Found Val's bucket? If so, return it. 00363 if (KeyInfoT::isEqual(ThisBucket->first, Val)) { 00364 FoundBucket = ThisBucket; 00365 return true; 00366 } 00367 00368 // If we found an empty bucket, the key doesn't exist in the set. 00369 // Insert it and return the default value. 00370 if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) { 00371 // If we've already seen a tombstone while probing, fill it in instead 00372 // of the empty bucket we eventually probed to. 00373 if (FoundTombstone) ThisBucket = FoundTombstone; 00374 FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket; 00375 return false; 00376 } 00377 00378 // If this is a tombstone, remember it. If Val ends up not in the map, we 00379 // prefer to return it than something that would require more probing. 00380 if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombstone) 00381 FoundTombstone = ThisBucket; // Remember the first tombstone found. 00382 00383 // Otherwise, it's a hash collision or a tombstone, continue quadratic 00384 // probing. 00385 BucketNo += ProbeAmt++; 00386 } 00387 } 00388 00389 void init(unsigned InitBuckets) { 00390 NumEntries = 0; 00391 NumTombstones = 0; 00392 NumBuckets = InitBuckets; 00393 assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 && 00394 "# initial buckets must be a power of two!"); 00395 Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets)); 00396 // Initialize all the keys to EmptyKey. 00397 const KeyT EmptyKey = getEmptyKey(); 00398 for (unsigned i = 0; i != InitBuckets; ++i) 00399 new (&Buckets[i].first) KeyT(EmptyKey); 00400 } 00401 00402 void grow(unsigned AtLeast) { 00403 unsigned OldNumBuckets = NumBuckets; 00404 BucketT *OldBuckets = Buckets; 00405 00406 // Double the number of buckets. 00407 while (NumBuckets <= AtLeast) 00408 NumBuckets <<= 1; 00409 NumTombstones = 0; 00410 Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets)); 00411 00412 // Initialize all the keys to EmptyKey. 00413 const KeyT EmptyKey = getEmptyKey(); 00414 for (unsigned i = 0, e = NumBuckets; i != e; ++i) 00415 new (&Buckets[i].first) KeyT(EmptyKey); 00416 00417 // Insert all the old elements. 00418 const KeyT TombstoneKey = getTombstoneKey(); 00419 for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) { 00420 if (!KeyInfoT::isEqual(B->first, EmptyKey) && 00421 !KeyInfoT::isEqual(B->first, TombstoneKey)) { 00422 // Insert the key/value into the new table. 00423 BucketT *DestBucket; 00424 bool FoundVal = LookupBucketFor(B->first, DestBucket); 00425 FoundVal = FoundVal; // silence warning. 00426 assert(!FoundVal && "Key already in new map?"); 00427 DestBucket->first = B->first; 00428 new (&DestBucket->second) ValueT(B->second); 00429 00430 // Free the value. 00431 B->second.~ValueT(); 00432 } 00433 B->first.~KeyT(); 00434 } 00435 00436 // Free the old table. 00437 operator delete(OldBuckets); 00438 } 00439 00440 void shrink_and_clear() { 00441 unsigned OldNumBuckets = NumBuckets; 00442 BucketT *OldBuckets = Buckets; 00443 00444 // Reduce the number of buckets. 00445 NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1) 00446 : 64; 00447 NumTombstones = 0; 00448 Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets)); 00449 00450 // Initialize all the keys to EmptyKey. 00451 const KeyT EmptyKey = getEmptyKey(); 00452 for (unsigned i = 0, e = NumBuckets; i != e; ++i) 00453 new (&Buckets[i].first) KeyT(EmptyKey); 00454 00455 // Free the old buckets. 00456 const KeyT TombstoneKey = getTombstoneKey(); 00457 for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) { 00458 if (!KeyInfoT::isEqual(B->first, EmptyKey) && 00459 !KeyInfoT::isEqual(B->first, TombstoneKey)) { 00460 // Free the value. 00461 B->second.~ValueT(); 00462 } 00463 B->first.~KeyT(); 00464 } 00465 00466 // Free the old table. 00467 operator delete(OldBuckets); 00468 00469 NumEntries = 0; 00470 } 00471 }; 00472 00473 template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT> 00474 class DenseMapIterator { 00475 typedef std::pair<KeyT, ValueT> BucketT; 00476 protected: 00477 const BucketT *Ptr, *End; 00478 public: 00479 DenseMapIterator(void) : Ptr(0), End(0) {} 00480 00481 DenseMapIterator(const BucketT *Pos, const BucketT *E) : Ptr(Pos), End(E) { 00482 AdvancePastEmptyBuckets(); 00483 } 00484 00485 std::pair<KeyT, ValueT> &operator*() const { 00486 return *const_cast<BucketT*>(Ptr); 00487 } 00488 std::pair<KeyT, ValueT> *operator->() const { 00489 return const_cast<BucketT*>(Ptr); 00490 } 00491 00492 bool operator==(const DenseMapIterator &RHS) const { 00493 return Ptr == RHS.Ptr; 00494 } 00495 bool operator!=(const DenseMapIterator &RHS) const { 00496 return Ptr != RHS.Ptr; 00497 } 00498 00499 inline DenseMapIterator& operator++() { // Preincrement 00500 ++Ptr; 00501 AdvancePastEmptyBuckets(); 00502 return *this; 00503 } 00504 DenseMapIterator operator++(int) { // Postincrement 00505 DenseMapIterator tmp = *this; ++*this; return tmp; 00506 } 00507 00508 private: 00509 void AdvancePastEmptyBuckets() { 00510 const KeyT Empty = KeyInfoT::getEmptyKey(); 00511 const KeyT Tombstone = KeyInfoT::getTombstoneKey(); 00512 00513 while (Ptr != End && 00514 (KeyInfoT::isEqual(Ptr->first, Empty) || 00515 KeyInfoT::isEqual(Ptr->first, Tombstone))) 00516 ++Ptr; 00517 } 00518 }; 00519 00520 template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT> 00521 class DenseMapConstIterator : public DenseMapIterator<KeyT, ValueT, KeyInfoT> { 00522 public: 00523 DenseMapConstIterator(void) : DenseMapIterator<KeyT, ValueT, KeyInfoT>() {} 00524 DenseMapConstIterator(const std::pair<KeyT, ValueT> *Pos, 00525 const std::pair<KeyT, ValueT> *E) 00526 : DenseMapIterator<KeyT, ValueT, KeyInfoT>(Pos, E) { 00527 } 00528 const std::pair<KeyT, ValueT> &operator*() const { 00529 return *this->Ptr; 00530 } 00531 const std::pair<KeyT, ValueT> *operator->() const { 00532 return this->Ptr; 00533 } 00534 }; 00535 00536 } // end namespace llvm 00537 00538 #endif