LLVM API Documentation

DenseMap.h

Go to the documentation of this file.
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