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