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/ADT/DenseMapInfo.h"
00018 #include "llvm/Support/AlignOf.h"
00019 #include "llvm/Support/Compiler.h"
00020 #include "llvm/Support/MathExtras.h"
00021 #include "llvm/Support/PointerLikeTypeTraits.h"
00022 #include "llvm/Support/type_traits.h"
00023 #include <algorithm>
00024 #include <cassert>
00025 #include <climits>
00026 #include <cstddef>
00027 #include <cstring>
00028 #include <iterator>
00029 #include <new>
00030 #include <utility>
00031 
00032 namespace llvm {
00033 
00034 template<typename KeyT, typename ValueT,
00035          typename KeyInfoT = DenseMapInfo<KeyT>,
00036          bool IsConst = false>
00037 class DenseMapIterator;
00038 
00039 template<typename DerivedT,
00040          typename KeyT, typename ValueT, typename KeyInfoT>
00041 class DenseMapBase {
00042 protected:
00043   typedef std::pair<KeyT, ValueT> BucketT;
00044 
00045 public:
00046   typedef KeyT key_type;
00047   typedef ValueT mapped_type;
00048   typedef BucketT value_type;
00049 
00050   typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
00051   typedef DenseMapIterator<KeyT, ValueT,
00052                            KeyInfoT, true> const_iterator;
00053   inline iterator begin() {
00054     // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
00055     return empty() ? end() : iterator(getBuckets(), getBucketsEnd());
00056   }
00057   inline iterator end() {
00058     return iterator(getBucketsEnd(), getBucketsEnd(), true);
00059   }
00060   inline const_iterator begin() const {
00061     return empty() ? end() : const_iterator(getBuckets(), getBucketsEnd());
00062   }
00063   inline const_iterator end() const {
00064     return const_iterator(getBucketsEnd(), getBucketsEnd(), true);
00065   }
00066 
00067   bool empty() const { return getNumEntries() == 0; }
00068   unsigned size() const { return getNumEntries(); }
00069 
00070   /// Grow the densemap so that it has at least Size buckets. Does not shrink
00071   void resize(size_t Size) {
00072     if (Size > getNumBuckets())
00073       grow(Size);
00074   }
00075 
00076   void clear() {
00077     if (getNumEntries() == 0 && getNumTombstones() == 0) return;
00078 
00079     // If the capacity of the array is huge, and the # elements used is small,
00080     // shrink the array.
00081     if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
00082       shrink_and_clear();
00083       return;
00084     }
00085 
00086     const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
00087     for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
00088       if (!KeyInfoT::isEqual(P->first, EmptyKey)) {
00089         if (!KeyInfoT::isEqual(P->first, TombstoneKey)) {
00090           P->second.~ValueT();
00091           decrementNumEntries();
00092         }
00093         P->first = EmptyKey;
00094       }
00095     }
00096     assert(getNumEntries() == 0 && "Node count imbalance!");
00097     setNumTombstones(0);
00098   }
00099 
00100   /// count - Return true if the specified key is in the map.
00101   bool count(const KeyT &Val) const {
00102     const BucketT *TheBucket;
00103     return LookupBucketFor(Val, TheBucket);
00104   }
00105 
00106   iterator find(const KeyT &Val) {
00107     BucketT *TheBucket;
00108     if (LookupBucketFor(Val, TheBucket))
00109       return iterator(TheBucket, getBucketsEnd(), true);
00110     return end();
00111   }
00112   const_iterator find(const KeyT &Val) const {
00113     const BucketT *TheBucket;
00114     if (LookupBucketFor(Val, TheBucket))
00115       return const_iterator(TheBucket, getBucketsEnd(), true);
00116     return end();
00117   }
00118 
00119   /// Alternate version of find() which allows a different, and possibly
00120   /// less expensive, key type.
00121   /// The DenseMapInfo is responsible for supplying methods
00122   /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
00123   /// type used.
00124   template<class LookupKeyT>
00125   iterator find_as(const LookupKeyT &Val) {
00126     BucketT *TheBucket;
00127     if (LookupBucketFor(Val, TheBucket))
00128       return iterator(TheBucket, getBucketsEnd(), true);
00129     return end();
00130   }
00131   template<class LookupKeyT>
00132   const_iterator find_as(const LookupKeyT &Val) const {
00133     const BucketT *TheBucket;
00134     if (LookupBucketFor(Val, TheBucket))
00135       return const_iterator(TheBucket, getBucketsEnd(), true);
00136     return end();
00137   }
00138 
00139   /// lookup - Return the entry for the specified key, or a default
00140   /// constructed value if no such entry exists.
00141   ValueT lookup(const KeyT &Val) const {
00142     const BucketT *TheBucket;
00143     if (LookupBucketFor(Val, TheBucket))
00144       return TheBucket->second;
00145     return ValueT();
00146   }
00147 
00148   // Inserts key,value pair into the map if the key isn't already in the map.
00149   // If the key is already in the map, it returns false and doesn't update the
00150   // value.
00151   std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
00152     BucketT *TheBucket;
00153     if (LookupBucketFor(KV.first, TheBucket))
00154       return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
00155                             false); // Already in map.
00156 
00157     // Otherwise, insert the new element.
00158     TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
00159     return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
00160   }
00161 
00162 #if LLVM_HAS_RVALUE_REFERENCES
00163   // Inserts key,value pair into the map if the key isn't already in the map.
00164   // If the key is already in the map, it returns false and doesn't update the
00165   // value.
00166   std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
00167     BucketT *TheBucket;
00168     if (LookupBucketFor(KV.first, TheBucket))
00169       return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
00170                             false); // Already in map.
00171     
00172     // Otherwise, insert the new element.
00173     TheBucket = InsertIntoBucket(std::move(KV.first),
00174                                  std::move(KV.second),
00175                                  TheBucket);
00176     return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
00177   }
00178 #endif
00179   
00180   /// insert - Range insertion of pairs.
00181   template<typename InputIt>
00182   void insert(InputIt I, InputIt E) {
00183     for (; I != E; ++I)
00184       insert(*I);
00185   }
00186 
00187 
00188   bool erase(const KeyT &Val) {
00189     BucketT *TheBucket;
00190     if (!LookupBucketFor(Val, TheBucket))
00191       return false; // not in map.
00192 
00193     TheBucket->second.~ValueT();
00194     TheBucket->first = getTombstoneKey();
00195     decrementNumEntries();
00196     incrementNumTombstones();
00197     return true;
00198   }
00199   void erase(iterator I) {
00200     BucketT *TheBucket = &*I;
00201     TheBucket->second.~ValueT();
00202     TheBucket->first = getTombstoneKey();
00203     decrementNumEntries();
00204     incrementNumTombstones();
00205   }
00206 
00207   value_type& FindAndConstruct(const KeyT &Key) {
00208     BucketT *TheBucket;
00209     if (LookupBucketFor(Key, TheBucket))
00210       return *TheBucket;
00211 
00212     return *InsertIntoBucket(Key, ValueT(), TheBucket);
00213   }
00214 
00215   ValueT &operator[](const KeyT &Key) {
00216     return FindAndConstruct(Key).second;
00217   }
00218 
00219 #if LLVM_HAS_RVALUE_REFERENCES
00220   value_type& FindAndConstruct(KeyT &&Key) {
00221     BucketT *TheBucket;
00222     if (LookupBucketFor(Key, TheBucket))
00223       return *TheBucket;
00224 
00225     return *InsertIntoBucket(Key, ValueT(), TheBucket);
00226   }
00227 
00228   ValueT &operator[](KeyT &&Key) {
00229     return FindAndConstruct(Key).second;
00230   }
00231 #endif
00232 
00233   /// isPointerIntoBucketsArray - Return true if the specified pointer points
00234   /// somewhere into the DenseMap's array of buckets (i.e. either to a key or
00235   /// value in the DenseMap).
00236   bool isPointerIntoBucketsArray(const void *Ptr) const {
00237     return Ptr >= getBuckets() && Ptr < getBucketsEnd();
00238   }
00239 
00240   /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
00241   /// array.  In conjunction with the previous method, this can be used to
00242   /// determine whether an insertion caused the DenseMap to reallocate.
00243   const void *getPointerIntoBucketsArray() const { return getBuckets(); }
00244 
00245 protected:
00246   DenseMapBase() {}
00247 
00248   void destroyAll() {
00249     if (getNumBuckets() == 0) // Nothing to do.
00250       return;
00251 
00252     const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
00253     for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
00254       if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
00255           !KeyInfoT::isEqual(P->first, TombstoneKey))
00256         P->second.~ValueT();
00257       P->first.~KeyT();
00258     }
00259 
00260 #ifndef NDEBUG
00261     memset((void*)getBuckets(), 0x5a, sizeof(BucketT)*getNumBuckets());
00262 #endif
00263   }
00264 
00265   void initEmpty() {
00266     setNumEntries(0);
00267     setNumTombstones(0);
00268 
00269     assert((getNumBuckets() & (getNumBuckets()-1)) == 0 &&
00270            "# initial buckets must be a power of two!");
00271     const KeyT EmptyKey = getEmptyKey();
00272     for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B)
00273       new (&B->first) KeyT(EmptyKey);
00274   }
00275 
00276   void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) {
00277     initEmpty();
00278 
00279     // Insert all the old elements.
00280     const KeyT EmptyKey = getEmptyKey();
00281     const KeyT TombstoneKey = getTombstoneKey();
00282     for (BucketT *B = OldBucketsBegin, *E = OldBucketsEnd; B != E; ++B) {
00283       if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
00284           !KeyInfoT::isEqual(B->first, TombstoneKey)) {
00285         // Insert the key/value into the new table.
00286         BucketT *DestBucket;
00287         bool FoundVal = LookupBucketFor(B->first, DestBucket);
00288         (void)FoundVal; // silence warning.
00289         assert(!FoundVal && "Key already in new map?");
00290         DestBucket->first = llvm_move(B->first);
00291         new (&DestBucket->second) ValueT(llvm_move(B->second));
00292         incrementNumEntries();
00293 
00294         // Free the value.
00295         B->second.~ValueT();
00296       }
00297       B->first.~KeyT();
00298     }
00299 
00300 #ifndef NDEBUG
00301     if (OldBucketsBegin != OldBucketsEnd)
00302       memset((void*)OldBucketsBegin, 0x5a,
00303              sizeof(BucketT) * (OldBucketsEnd - OldBucketsBegin));
00304 #endif
00305   }
00306 
00307   template <typename OtherBaseT>
00308   void copyFrom(const DenseMapBase<OtherBaseT, KeyT, ValueT, KeyInfoT>& other) {
00309     assert(getNumBuckets() == other.getNumBuckets());
00310 
00311     setNumEntries(other.getNumEntries());
00312     setNumTombstones(other.getNumTombstones());
00313 
00314     if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
00315       memcpy(getBuckets(), other.getBuckets(),
00316              getNumBuckets() * sizeof(BucketT));
00317     else
00318       for (size_t i = 0; i < getNumBuckets(); ++i) {
00319         new (&getBuckets()[i].first) KeyT(other.getBuckets()[i].first);
00320         if (!KeyInfoT::isEqual(getBuckets()[i].first, getEmptyKey()) &&
00321             !KeyInfoT::isEqual(getBuckets()[i].first, getTombstoneKey()))
00322           new (&getBuckets()[i].second) ValueT(other.getBuckets()[i].second);
00323       }
00324   }
00325 
00326   void swap(DenseMapBase& RHS) {
00327     std::swap(getNumEntries(), RHS.getNumEntries());
00328     std::swap(getNumTombstones(), RHS.getNumTombstones());
00329   }
00330 
00331   static unsigned getHashValue(const KeyT &Val) {
00332     return KeyInfoT::getHashValue(Val);
00333   }
00334   template<typename LookupKeyT>
00335   static unsigned getHashValue(const LookupKeyT &Val) {
00336     return KeyInfoT::getHashValue(Val);
00337   }
00338   static const KeyT getEmptyKey() {
00339     return KeyInfoT::getEmptyKey();
00340   }
00341   static const KeyT getTombstoneKey() {
00342     return KeyInfoT::getTombstoneKey();
00343   }
00344 
00345 private:
00346   unsigned getNumEntries() const {
00347     return static_cast<const DerivedT *>(this)->getNumEntries();
00348   }
00349   void setNumEntries(unsigned Num) {
00350     static_cast<DerivedT *>(this)->setNumEntries(Num);
00351   }
00352   void incrementNumEntries() {
00353     setNumEntries(getNumEntries() + 1);
00354   }
00355   void decrementNumEntries() {
00356     setNumEntries(getNumEntries() - 1);
00357   }
00358   unsigned getNumTombstones() const {
00359     return static_cast<const DerivedT *>(this)->getNumTombstones();
00360   }
00361   void setNumTombstones(unsigned Num) {
00362     static_cast<DerivedT *>(this)->setNumTombstones(Num);
00363   }
00364   void incrementNumTombstones() {
00365     setNumTombstones(getNumTombstones() + 1);
00366   }
00367   void decrementNumTombstones() {
00368     setNumTombstones(getNumTombstones() - 1);
00369   }
00370   const BucketT *getBuckets() const {
00371     return static_cast<const DerivedT *>(this)->getBuckets();
00372   }
00373   BucketT *getBuckets() {
00374     return static_cast<DerivedT *>(this)->getBuckets();
00375   }
00376   unsigned getNumBuckets() const {
00377     return static_cast<const DerivedT *>(this)->getNumBuckets();
00378   }
00379   BucketT *getBucketsEnd() {
00380     return getBuckets() + getNumBuckets();
00381   }
00382   const BucketT *getBucketsEnd() const {
00383     return getBuckets() + getNumBuckets();
00384   }
00385 
00386   void grow(unsigned AtLeast) {
00387     static_cast<DerivedT *>(this)->grow(AtLeast);
00388   }
00389 
00390   void shrink_and_clear() {
00391     static_cast<DerivedT *>(this)->shrink_and_clear();
00392   }
00393 
00394 
00395   BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
00396                             BucketT *TheBucket) {
00397     TheBucket = InsertIntoBucketImpl(Key, TheBucket);
00398 
00399     TheBucket->first = Key;
00400     new (&TheBucket->second) ValueT(Value);
00401     return TheBucket;
00402   }
00403 
00404 #if LLVM_HAS_RVALUE_REFERENCES
00405   BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
00406                             BucketT *TheBucket) {
00407     TheBucket = InsertIntoBucketImpl(Key, TheBucket);
00408 
00409     TheBucket->first = Key;
00410     new (&TheBucket->second) ValueT(std::move(Value));
00411     return TheBucket;
00412   }
00413 
00414   BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, BucketT *TheBucket) {
00415     TheBucket = InsertIntoBucketImpl(Key, TheBucket);
00416 
00417     TheBucket->first = std::move(Key);
00418     new (&TheBucket->second) ValueT(std::move(Value));
00419     return TheBucket;
00420   }
00421 #endif
00422 
00423   BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) {
00424     // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
00425     // the buckets are empty (meaning that many are filled with tombstones),
00426     // grow the table.
00427     //
00428     // The later case is tricky.  For example, if we had one empty bucket with
00429     // tons of tombstones, failing lookups (e.g. for insertion) would have to
00430     // probe almost the entire table until it found the empty bucket.  If the
00431     // table completely filled with tombstones, no lookup would ever succeed,
00432     // causing infinite loops in lookup.
00433     unsigned NewNumEntries = getNumEntries() + 1;
00434     unsigned NumBuckets = getNumBuckets();
00435     if (NewNumEntries*4 >= NumBuckets*3) {
00436       this->grow(NumBuckets * 2);
00437       LookupBucketFor(Key, TheBucket);
00438       NumBuckets = getNumBuckets();
00439     }
00440     if (NumBuckets-(NewNumEntries+getNumTombstones()) <= NumBuckets/8) {
00441       this->grow(NumBuckets * 2);
00442       LookupBucketFor(Key, TheBucket);
00443     }
00444     assert(TheBucket);
00445 
00446     // Only update the state after we've grown our bucket space appropriately
00447     // so that when growing buckets we have self-consistent entry count.
00448     incrementNumEntries();
00449 
00450     // If we are writing over a tombstone, remember this.
00451     const KeyT EmptyKey = getEmptyKey();
00452     if (!KeyInfoT::isEqual(TheBucket->first, EmptyKey))
00453       decrementNumTombstones();
00454 
00455     return TheBucket;
00456   }
00457 
00458   /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
00459   /// FoundBucket.  If the bucket contains the key and a value, this returns
00460   /// true, otherwise it returns a bucket with an empty marker or tombstone and
00461   /// returns false.
00462   template<typename LookupKeyT>
00463   bool LookupBucketFor(const LookupKeyT &Val,
00464                        const BucketT *&FoundBucket) const {
00465     const BucketT *BucketsPtr = getBuckets();
00466     const unsigned NumBuckets = getNumBuckets();
00467 
00468     if (NumBuckets == 0) {
00469       FoundBucket = 0;
00470       return false;
00471     }
00472 
00473     // FoundTombstone - Keep track of whether we find a tombstone while probing.
00474     const BucketT *FoundTombstone = 0;
00475     const KeyT EmptyKey = getEmptyKey();
00476     const KeyT TombstoneKey = getTombstoneKey();
00477     assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
00478            !KeyInfoT::isEqual(Val, TombstoneKey) &&
00479            "Empty/Tombstone value shouldn't be inserted into map!");
00480 
00481     unsigned BucketNo = getHashValue(Val) & (NumBuckets-1);
00482     unsigned ProbeAmt = 1;
00483     while (1) {
00484       const BucketT *ThisBucket = BucketsPtr + BucketNo;
00485       // Found Val's bucket?  If so, return it.
00486       if (KeyInfoT::isEqual(Val, ThisBucket->first)) {
00487         FoundBucket = ThisBucket;
00488         return true;
00489       }
00490 
00491       // If we found an empty bucket, the key doesn't exist in the set.
00492       // Insert it and return the default value.
00493       if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
00494         // If we've already seen a tombstone while probing, fill it in instead
00495         // of the empty bucket we eventually probed to.
00496         FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
00497         return false;
00498       }
00499 
00500       // If this is a tombstone, remember it.  If Val ends up not in the map, we
00501       // prefer to return it than something that would require more probing.
00502       if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombstone)
00503         FoundTombstone = ThisBucket;  // Remember the first tombstone found.
00504 
00505       // Otherwise, it's a hash collision or a tombstone, continue quadratic
00506       // probing.
00507       BucketNo += ProbeAmt++;
00508       BucketNo &= (NumBuckets-1);
00509     }
00510   }
00511 
00512   template <typename LookupKeyT>
00513   bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) {
00514     const BucketT *ConstFoundBucket;
00515     bool Result = const_cast<const DenseMapBase *>(this)
00516       ->LookupBucketFor(Val, ConstFoundBucket);
00517     FoundBucket = const_cast<BucketT *>(ConstFoundBucket);
00518     return Result;
00519   }
00520 
00521 public:
00522   /// Return the approximate size (in bytes) of the actual map.
00523   /// This is just the raw memory used by DenseMap.
00524   /// If entries are pointers to objects, the size of the referenced objects
00525   /// are not included.
00526   size_t getMemorySize() const {
00527     return getNumBuckets() * sizeof(BucketT);
00528   }
00529 };
00530 
00531 template<typename KeyT, typename ValueT,
00532          typename KeyInfoT = DenseMapInfo<KeyT> >
00533 class DenseMap
00534     : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT>,
00535                           KeyT, ValueT, KeyInfoT> {
00536   // Lift some types from the dependent base class into this class for
00537   // simplicity of referring to them.
00538   typedef DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT> BaseT;
00539   typedef typename BaseT::BucketT BucketT;
00540   friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT>;
00541 
00542   BucketT *Buckets;
00543   unsigned NumEntries;
00544   unsigned NumTombstones;
00545   unsigned NumBuckets;
00546 
00547 public:
00548   explicit DenseMap(unsigned NumInitBuckets = 0) {
00549     init(NumInitBuckets);
00550   }
00551 
00552   DenseMap(const DenseMap &other) : BaseT() {
00553     init(0);
00554     copyFrom(other);
00555   }
00556 
00557 #if LLVM_HAS_RVALUE_REFERENCES
00558   DenseMap(DenseMap &&other) : BaseT() {
00559     init(0);
00560     swap(other);
00561   }
00562 #endif
00563 
00564   template<typename InputIt>
00565   DenseMap(const InputIt &I, const InputIt &E) {
00566     init(NextPowerOf2(std::distance(I, E)));
00567     this->insert(I, E);
00568   }
00569 
00570   ~DenseMap() {
00571     this->destroyAll();
00572     operator delete(Buckets);
00573   }
00574 
00575   void swap(DenseMap& RHS) {
00576     std::swap(Buckets, RHS.Buckets);
00577     std::swap(NumEntries, RHS.NumEntries);
00578     std::swap(NumTombstones, RHS.NumTombstones);
00579     std::swap(NumBuckets, RHS.NumBuckets);
00580   }
00581 
00582   DenseMap& operator=(const DenseMap& other) {
00583     copyFrom(other);
00584     return *this;
00585   }
00586 
00587 #if LLVM_HAS_RVALUE_REFERENCES
00588   DenseMap& operator=(DenseMap &&other) {
00589     this->destroyAll();
00590     operator delete(Buckets);
00591     init(0);
00592     swap(other);
00593     return *this;
00594   }
00595 #endif
00596 
00597   void copyFrom(const DenseMap& other) {
00598     this->destroyAll();
00599     operator delete(Buckets);
00600     if (allocateBuckets(other.NumBuckets)) {
00601       this->BaseT::copyFrom(other);
00602     } else {
00603       NumEntries = 0;
00604       NumTombstones = 0;
00605     }
00606   }
00607 
00608   void init(unsigned InitBuckets) {
00609     if (allocateBuckets(InitBuckets)) {
00610       this->BaseT::initEmpty();
00611     } else {
00612       NumEntries = 0;
00613       NumTombstones = 0;
00614     }
00615   }
00616 
00617   void grow(unsigned AtLeast) {
00618     unsigned OldNumBuckets = NumBuckets;
00619     BucketT *OldBuckets = Buckets;
00620 
00621     allocateBuckets(std::max<unsigned>(64, static_cast<unsigned>(NextPowerOf2(AtLeast-1))));
00622     assert(Buckets);
00623     if (!OldBuckets) {
00624       this->BaseT::initEmpty();
00625       return;
00626     }
00627 
00628     this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets);
00629 
00630     // Free the old table.
00631     operator delete(OldBuckets);
00632   }
00633 
00634   void shrink_and_clear() {
00635     unsigned OldNumEntries = NumEntries;
00636     this->destroyAll();
00637 
00638     // Reduce the number of buckets.
00639     unsigned NewNumBuckets = 0;
00640     if (OldNumEntries)
00641       NewNumBuckets = std::max(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1));
00642     if (NewNumBuckets == NumBuckets) {
00643       this->BaseT::initEmpty();
00644       return;
00645     }
00646 
00647     operator delete(Buckets);
00648     init(NewNumBuckets);
00649   }
00650 
00651 private:
00652   unsigned getNumEntries() const {
00653     return NumEntries;
00654   }
00655   void setNumEntries(unsigned Num) {
00656     NumEntries = Num;
00657   }
00658 
00659   unsigned getNumTombstones() const {
00660     return NumTombstones;
00661   }
00662   void setNumTombstones(unsigned Num) {
00663     NumTombstones = Num;
00664   }
00665 
00666   BucketT *getBuckets() const {
00667     return Buckets;
00668   }
00669 
00670   unsigned getNumBuckets() const {
00671     return NumBuckets;
00672   }
00673 
00674   bool allocateBuckets(unsigned Num) {
00675     NumBuckets = Num;
00676     if (NumBuckets == 0) {
00677       Buckets = 0;
00678       return false;
00679     }
00680 
00681     Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
00682     return true;
00683   }
00684 };
00685 
00686 template<typename KeyT, typename ValueT,
00687          unsigned InlineBuckets = 4,
00688          typename KeyInfoT = DenseMapInfo<KeyT> >
00689 class SmallDenseMap
00690     : public DenseMapBase<SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT>,
00691                           KeyT, ValueT, KeyInfoT> {
00692   // Lift some types from the dependent base class into this class for
00693   // simplicity of referring to them.
00694   typedef DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT> BaseT;
00695   typedef typename BaseT::BucketT BucketT;
00696   friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT>;
00697 
00698   unsigned Small : 1;
00699   unsigned NumEntries : 31;
00700   unsigned NumTombstones;
00701 
00702   struct LargeRep {
00703     BucketT *Buckets;
00704     unsigned NumBuckets;
00705   };
00706 
00707   /// A "union" of an inline bucket array and the struct representing
00708   /// a large bucket. This union will be discriminated by the 'Small' bit.
00709   AlignedCharArrayUnion<BucketT[InlineBuckets], LargeRep> storage;
00710 
00711 public:
00712   explicit SmallDenseMap(unsigned NumInitBuckets = 0) {
00713     init(NumInitBuckets);
00714   }
00715 
00716   SmallDenseMap(const SmallDenseMap &other) {
00717     init(0);
00718     copyFrom(other);
00719   }
00720 
00721 #if LLVM_HAS_RVALUE_REFERENCES
00722   SmallDenseMap(SmallDenseMap &&other) {
00723     init(0);
00724     swap(other);
00725   }
00726 #endif
00727 
00728   template<typename InputIt>
00729   SmallDenseMap(const InputIt &I, const InputIt &E) {
00730     init(NextPowerOf2(std::distance(I, E)));
00731     this->insert(I, E);
00732   }
00733 
00734   ~SmallDenseMap() {
00735     this->destroyAll();
00736     deallocateBuckets();
00737   }
00738 
00739   void swap(SmallDenseMap& RHS) {
00740     unsigned TmpNumEntries = RHS.NumEntries;
00741     RHS.NumEntries = NumEntries;
00742     NumEntries = TmpNumEntries;
00743     std::swap(NumTombstones, RHS.NumTombstones);
00744 
00745     const KeyT EmptyKey = this->getEmptyKey();
00746     const KeyT TombstoneKey = this->getTombstoneKey();
00747     if (Small && RHS.Small) {
00748       // If we're swapping inline bucket arrays, we have to cope with some of
00749       // the tricky bits of DenseMap's storage system: the buckets are not
00750       // fully initialized. Thus we swap every key, but we may have
00751       // a one-directional move of the value.
00752       for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
00753         BucketT *LHSB = &getInlineBuckets()[i],
00754                 *RHSB = &RHS.getInlineBuckets()[i];
00755         bool hasLHSValue = (!KeyInfoT::isEqual(LHSB->first, EmptyKey) &&
00756                             !KeyInfoT::isEqual(LHSB->first, TombstoneKey));
00757         bool hasRHSValue = (!KeyInfoT::isEqual(RHSB->first, EmptyKey) &&
00758                             !KeyInfoT::isEqual(RHSB->first, TombstoneKey));
00759         if (hasLHSValue && hasRHSValue) {
00760           // Swap together if we can...
00761           std::swap(*LHSB, *RHSB);
00762           continue;
00763         }
00764         // Swap separately and handle any assymetry.
00765         std::swap(LHSB->first, RHSB->first);
00766         if (hasLHSValue) {
00767           new (&RHSB->second) ValueT(llvm_move(LHSB->second));
00768           LHSB->second.~ValueT();
00769         } else if (hasRHSValue) {
00770           new (&LHSB->second) ValueT(llvm_move(RHSB->second));
00771           RHSB->second.~ValueT();
00772         }
00773       }
00774       return;
00775     }
00776     if (!Small && !RHS.Small) {
00777       std::swap(getLargeRep()->Buckets, RHS.getLargeRep()->Buckets);
00778       std::swap(getLargeRep()->NumBuckets, RHS.getLargeRep()->NumBuckets);
00779       return;
00780     }
00781 
00782     SmallDenseMap &SmallSide = Small ? *this : RHS;
00783     SmallDenseMap &LargeSide = Small ? RHS : *this;
00784 
00785     // First stash the large side's rep and move the small side across.
00786     LargeRep TmpRep = llvm_move(*LargeSide.getLargeRep());
00787     LargeSide.getLargeRep()->~LargeRep();
00788     LargeSide.Small = true;
00789     // This is similar to the standard move-from-old-buckets, but the bucket
00790     // count hasn't actually rotated in this case. So we have to carefully
00791     // move construct the keys and values into their new locations, but there
00792     // is no need to re-hash things.
00793     for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
00794       BucketT *NewB = &LargeSide.getInlineBuckets()[i],
00795               *OldB = &SmallSide.getInlineBuckets()[i];
00796       new (&NewB->first) KeyT(llvm_move(OldB->first));
00797       OldB->first.~KeyT();
00798       if (!KeyInfoT::isEqual(NewB->first, EmptyKey) &&
00799           !KeyInfoT::isEqual(NewB->first, TombstoneKey)) {
00800         new (&NewB->second) ValueT(llvm_move(OldB->second));
00801         OldB->second.~ValueT();
00802       }
00803     }
00804 
00805     // The hard part of moving the small buckets across is done, just move
00806     // the TmpRep into its new home.
00807     SmallSide.Small = false;
00808     new (SmallSide.getLargeRep()) LargeRep(llvm_move(TmpRep));
00809   }
00810 
00811   SmallDenseMap& operator=(const SmallDenseMap& other) {
00812     copyFrom(other);
00813     return *this;
00814   }
00815 
00816 #if LLVM_HAS_RVALUE_REFERENCES
00817   SmallDenseMap& operator=(SmallDenseMap &&other) {
00818     this->destroyAll();
00819     deallocateBuckets();
00820     init(0);
00821     swap(other);
00822     return *this;
00823   }
00824 #endif
00825 
00826   void copyFrom(const SmallDenseMap& other) {
00827     this->destroyAll();
00828     deallocateBuckets();
00829     Small = true;
00830     if (other.getNumBuckets() > InlineBuckets) {
00831       Small = false;
00832       allocateBuckets(other.getNumBuckets());
00833     }
00834     this->BaseT::copyFrom(other);
00835   }
00836 
00837   void init(unsigned InitBuckets) {
00838     Small = true;
00839     if (InitBuckets > InlineBuckets) {
00840       Small = false;
00841       new (getLargeRep()) LargeRep(allocateBuckets(InitBuckets));
00842     }
00843     this->BaseT::initEmpty();
00844   }
00845 
00846   void grow(unsigned AtLeast) {
00847     if (AtLeast >= InlineBuckets)
00848       AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast-1));
00849 
00850     if (Small) {
00851       if (AtLeast < InlineBuckets)
00852         return; // Nothing to do.
00853 
00854       // First move the inline buckets into a temporary storage.
00855       AlignedCharArrayUnion<BucketT[InlineBuckets]> TmpStorage;
00856       BucketT *TmpBegin = reinterpret_cast<BucketT *>(TmpStorage.buffer);
00857       BucketT *TmpEnd = TmpBegin;
00858 
00859       // Loop over the buckets, moving non-empty, non-tombstones into the
00860       // temporary storage. Have the loop move the TmpEnd forward as it goes.
00861       const KeyT EmptyKey = this->getEmptyKey();
00862       const KeyT TombstoneKey = this->getTombstoneKey();
00863       for (BucketT *P = getBuckets(), *E = P + InlineBuckets; P != E; ++P) {
00864         if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
00865             !KeyInfoT::isEqual(P->first, TombstoneKey)) {
00866           assert(size_t(TmpEnd - TmpBegin) < InlineBuckets &&
00867                  "Too many inline buckets!");
00868           new (&TmpEnd->first) KeyT(llvm_move(P->first));
00869           new (&TmpEnd->second) ValueT(llvm_move(P->second));
00870           ++TmpEnd;
00871           P->second.~ValueT();
00872         }
00873         P->first.~KeyT();
00874       }
00875 
00876       // Now make this map use the large rep, and move all the entries back
00877       // into it.
00878       Small = false;
00879       new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
00880       this->moveFromOldBuckets(TmpBegin, TmpEnd);
00881       return;
00882     }
00883 
00884     LargeRep OldRep = llvm_move(*getLargeRep());
00885     getLargeRep()->~LargeRep();
00886     if (AtLeast <= InlineBuckets) {
00887       Small = true;
00888     } else {
00889       new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
00890     }
00891 
00892     this->moveFromOldBuckets(OldRep.Buckets, OldRep.Buckets+OldRep.NumBuckets);
00893 
00894     // Free the old table.
00895     operator delete(OldRep.Buckets);
00896   }
00897 
00898   void shrink_and_clear() {
00899     unsigned OldSize = this->size();
00900     this->destroyAll();
00901 
00902     // Reduce the number of buckets.
00903     unsigned NewNumBuckets = 0;
00904     if (OldSize) {
00905       NewNumBuckets = 1 << (Log2_32_Ceil(OldSize) + 1);
00906       if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u)
00907         NewNumBuckets = 64;
00908     }
00909     if ((Small && NewNumBuckets <= InlineBuckets) ||
00910         (!Small && NewNumBuckets == getLargeRep()->NumBuckets)) {
00911       this->BaseT::initEmpty();
00912       return;
00913     }
00914 
00915     deallocateBuckets();
00916     init(NewNumBuckets);
00917   }
00918 
00919 private:
00920   unsigned getNumEntries() const {
00921     return NumEntries;
00922   }
00923   void setNumEntries(unsigned Num) {
00924     assert(Num < INT_MAX && "Cannot support more than INT_MAX entries");
00925     NumEntries = Num;
00926   }
00927 
00928   unsigned getNumTombstones() const {
00929     return NumTombstones;
00930   }
00931   void setNumTombstones(unsigned Num) {
00932     NumTombstones = Num;
00933   }
00934 
00935   const BucketT *getInlineBuckets() const {
00936     assert(Small);
00937     // Note that this cast does not violate aliasing rules as we assert that
00938     // the memory's dynamic type is the small, inline bucket buffer, and the
00939     // 'storage.buffer' static type is 'char *'.
00940     return reinterpret_cast<const BucketT *>(storage.buffer);
00941   }
00942   BucketT *getInlineBuckets() {
00943     return const_cast<BucketT *>(
00944       const_cast<const SmallDenseMap *>(this)->getInlineBuckets());
00945   }
00946   const LargeRep *getLargeRep() const {
00947     assert(!Small);
00948     // Note, same rule about aliasing as with getInlineBuckets.
00949     return reinterpret_cast<const LargeRep *>(storage.buffer);
00950   }
00951   LargeRep *getLargeRep() {
00952     return const_cast<LargeRep *>(
00953       const_cast<const SmallDenseMap *>(this)->getLargeRep());
00954   }
00955 
00956   const BucketT *getBuckets() const {
00957     return Small ? getInlineBuckets() : getLargeRep()->Buckets;
00958   }
00959   BucketT *getBuckets() {
00960     return const_cast<BucketT *>(
00961       const_cast<const SmallDenseMap *>(this)->getBuckets());
00962   }
00963   unsigned getNumBuckets() const {
00964     return Small ? InlineBuckets : getLargeRep()->NumBuckets;
00965   }
00966 
00967   void deallocateBuckets() {
00968     if (Small)
00969       return;
00970 
00971     operator delete(getLargeRep()->Buckets);
00972     getLargeRep()->~LargeRep();
00973   }
00974 
00975   LargeRep allocateBuckets(unsigned Num) {
00976     assert(Num > InlineBuckets && "Must allocate more buckets than are inline");
00977     LargeRep Rep = {
00978       static_cast<BucketT*>(operator new(sizeof(BucketT) * Num)), Num
00979     };
00980     return Rep;
00981   }
00982 };
00983 
00984 template<typename KeyT, typename ValueT,
00985          typename KeyInfoT, bool IsConst>
00986 class DenseMapIterator {
00987   typedef std::pair<KeyT, ValueT> Bucket;
00988   typedef DenseMapIterator<KeyT, ValueT,
00989                            KeyInfoT, true> ConstIterator;
00990   friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>;
00991 public:
00992   typedef ptrdiff_t difference_type;
00993   typedef typename conditional<IsConst, const Bucket, Bucket>::type value_type;
00994   typedef value_type *pointer;
00995   typedef value_type &reference;
00996   typedef std::forward_iterator_tag iterator_category;
00997 private:
00998   pointer Ptr, End;
00999 public:
01000   DenseMapIterator() : Ptr(0), End(0) {}
01001 
01002   DenseMapIterator(pointer Pos, pointer E, bool NoAdvance = false)
01003     : Ptr(Pos), End(E) {
01004     if (!NoAdvance) AdvancePastEmptyBuckets();
01005   }
01006 
01007   // If IsConst is true this is a converting constructor from iterator to
01008   // const_iterator and the default copy constructor is used.
01009   // Otherwise this is a copy constructor for iterator.
01010   DenseMapIterator(const DenseMapIterator<KeyT, ValueT,
01011                                           KeyInfoT, false>& I)
01012     : Ptr(I.Ptr), End(I.End) {}
01013 
01014   reference operator*() const {
01015     return *Ptr;
01016   }
01017   pointer operator->() const {
01018     return Ptr;
01019   }
01020 
01021   bool operator==(const ConstIterator &RHS) const {
01022     return Ptr == RHS.operator->();
01023   }
01024   bool operator!=(const ConstIterator &RHS) const {
01025     return Ptr != RHS.operator->();
01026   }
01027 
01028   inline DenseMapIterator& operator++() {  // Preincrement
01029     ++Ptr;
01030     AdvancePastEmptyBuckets();
01031     return *this;
01032   }
01033   DenseMapIterator operator++(int) {  // Postincrement
01034     DenseMapIterator tmp = *this; ++*this; return tmp;
01035   }
01036 
01037 private:
01038   void AdvancePastEmptyBuckets() {
01039     const KeyT Empty = KeyInfoT::getEmptyKey();
01040     const KeyT Tombstone = KeyInfoT::getTombstoneKey();
01041 
01042     while (Ptr != End &&
01043            (KeyInfoT::isEqual(Ptr->first, Empty) ||
01044             KeyInfoT::isEqual(Ptr->first, Tombstone)))
01045       ++Ptr;
01046   }
01047 };
01048 
01049 template<typename KeyT, typename ValueT, typename KeyInfoT>
01050 static inline size_t
01051 capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
01052   return X.getMemorySize();
01053 }
01054 
01055 } // end namespace llvm
01056 
01057 #endif