1//===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the DenseMap class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ADT_DENSEMAP_H
15#define LLVM_ADT_DENSEMAP_H
16
17#include "llvm/ADT/DenseMapInfo.h"
18#include "llvm/ADT/EpochTracker.h"
19#include "llvm/Support/AlignOf.h"
20#include "llvm/Support/Compiler.h"
21#include "llvm/Support/MathExtras.h"
22#include "llvm/Support/type_traits.h"
23#include <algorithm>
24#include <cassert>
25#include <cstddef>
26#include <cstring>
27#include <iterator>
28#include <limits>
29#include <new>
30#include <utility>
31
32namespace llvm {
33
34namespace detail {
35
36// We extend a pair to allow users to override the bucket type with their own
37// implementation without requiring two members.
38template <typename KeyT, typename ValueT>
39struct DenseMapPair : public std::pair<KeyT, ValueT> {
40  KeyT &getFirst() { return std::pair<KeyT, ValueT>::first; }
41  const KeyT &getFirst() const { return std::pair<KeyT, ValueT>::first; }
42  ValueT &getSecond() { return std::pair<KeyT, ValueT>::second; }
43  const ValueT &getSecond() const { return std::pair<KeyT, ValueT>::second; }
44};
45
46} // end namespace detail
47
48template <
49    typename KeyT, typename ValueT, typename KeyInfoT = DenseMapInfo<KeyT>,
50    typename Bucket = detail::DenseMapPair<KeyT, ValueT>, bool IsConst = false>
51class DenseMapIterator;
52
53template <typename DerivedT, typename KeyT, typename ValueT, typename KeyInfoT,
54          typename BucketT>
55class DenseMapBase : public DebugEpochBase {
56public:
57  typedef unsigned size_type;
58  typedef KeyT key_type;
59  typedef ValueT mapped_type;
60  typedef BucketT value_type;
61
62  typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT> iterator;
63  typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT, true>
64      const_iterator;
65  inline iterator begin() {
66    // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
67    return empty() ? end() : iterator(getBuckets(), getBucketsEnd(), *this);
68  }
69  inline iterator end() {
70    return iterator(getBucketsEnd(), getBucketsEnd(), *this, true);
71  }
72  inline const_iterator begin() const {
73    return empty() ? end()
74                   : const_iterator(getBuckets(), getBucketsEnd(), *this);
75  }
76  inline const_iterator end() const {
77    return const_iterator(getBucketsEnd(), getBucketsEnd(), *this, true);
78  }
79
80  LLVM_NODISCARD bool empty() const {
81    return getNumEntries() == 0;
82  }
83  unsigned size() const { return getNumEntries(); }
84
85  /// Grow the densemap so that it can contain at least \p NumEntries items
86  /// before resizing again.
87  void reserve(size_type NumEntries) {
88    auto NumBuckets = getMinBucketToReserveForEntries(NumEntries);
89    incrementEpoch();
90    if (NumBuckets > getNumBuckets())
91      grow(NumBuckets);
92  }
93
94  void clear() {
95    incrementEpoch();
96    if (getNumEntries() == 0 && getNumTombstones() == 0) return;
97
98    // If the capacity of the array is huge, and the # elements used is small,
99    // shrink the array.
100    if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
101      shrink_and_clear();
102      return;
103    }
104
105    const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
106    unsigned NumEntries = getNumEntries();
107    for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
108      if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) {
109        if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) {
110          P->getSecond().~ValueT();
111          --NumEntries;
112        }
113        P->getFirst() = EmptyKey;
114      }
115    }
116    assert(NumEntries == 0 && "Node count imbalance!");
117    setNumEntries(0);
118    setNumTombstones(0);
119  }
120
121  /// Return 1 if the specified key is in the map, 0 otherwise.
122  size_type count(const KeyT &Val) const {
123    const BucketT *TheBucket;
124    return LookupBucketFor(Val, TheBucket) ? 1 : 0;
125  }
126
127  iterator find(const KeyT &Val) {
128    BucketT *TheBucket;
129    if (LookupBucketFor(Val, TheBucket))
130      return iterator(TheBucket, getBucketsEnd(), *this, true);
131    return end();
132  }
133  const_iterator find(const KeyT &Val) const {
134    const BucketT *TheBucket;
135    if (LookupBucketFor(Val, TheBucket))
136      return const_iterator(TheBucket, getBucketsEnd(), *this, true);
137    return end();
138  }
139
140  /// Alternate version of find() which allows a different, and possibly
141  /// less expensive, key type.
142  /// The DenseMapInfo is responsible for supplying methods
143  /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
144  /// type used.
145  template<class LookupKeyT>
146  iterator find_as(const LookupKeyT &Val) {
147    BucketT *TheBucket;
148    if (LookupBucketFor(Val, TheBucket))
149      return iterator(TheBucket, getBucketsEnd(), *this, true);
150    return end();
151  }
152  template<class LookupKeyT>
153  const_iterator find_as(const LookupKeyT &Val) const {
154    const BucketT *TheBucket;
155    if (LookupBucketFor(Val, TheBucket))
156      return const_iterator(TheBucket, getBucketsEnd(), *this, true);
157    return end();
158  }
159
160  /// lookup - Return the entry for the specified key, or a default
161  /// constructed value if no such entry exists.
162  ValueT lookup(const KeyT &Val) const {
163    const BucketT *TheBucket;
164    if (LookupBucketFor(Val, TheBucket))
165      return TheBucket->getSecond();
166    return ValueT();
167  }
168
169  // Inserts key,value pair into the map if the key isn't already in the map.
170  // If the key is already in the map, it returns false and doesn't update the
171  // value.
172  std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
173    return try_emplace(KV.first, KV.second);
174  }
175
176  // Inserts key,value pair into the map if the key isn't already in the map.
177  // If the key is already in the map, it returns false and doesn't update the
178  // value.
179  std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
180    return try_emplace(std::move(KV.first), std::move(KV.second));
181  }
182
183  // Inserts key,value pair into the map if the key isn't already in the map.
184  // The value is constructed in-place if the key is not in the map, otherwise
185  // it is not moved.
186  template <typename... Ts>
187  std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&... Args) {
188    BucketT *TheBucket;
189    if (LookupBucketFor(Key, TheBucket))
190      return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
191                            false); // Already in map.
192
193    // Otherwise, insert the new element.
194    TheBucket =
195        InsertIntoBucket(TheBucket, std::move(Key), std::forward<Ts>(Args)...);
196    return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
197                          true);
198  }
199
200  // Inserts key,value pair into the map if the key isn't already in the map.
201  // The value is constructed in-place if the key is not in the map, otherwise
202  // it is not moved.
203  template <typename... Ts>
204  std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&... Args) {
205    BucketT *TheBucket;
206    if (LookupBucketFor(Key, TheBucket))
207      return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
208                            false); // Already in map.
209
210    // Otherwise, insert the new element.
211    TheBucket = InsertIntoBucket(TheBucket, Key, std::forward<Ts>(Args)...);
212    return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
213                          true);
214  }
215
216  /// Alternate version of insert() which allows a different, and possibly
217  /// less expensive, key type.
218  /// The DenseMapInfo is responsible for supplying methods
219  /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
220  /// type used.
221  template <typename LookupKeyT>
222  std::pair<iterator, bool> insert_as(std::pair<KeyT, ValueT> &&KV,
223                                      const LookupKeyT &Val) {
224    BucketT *TheBucket;
225    if (LookupBucketFor(Val, TheBucket))
226      return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
227                            false); // Already in map.
228
229    // Otherwise, insert the new element.
230    TheBucket = InsertIntoBucketWithLookup(TheBucket, std::move(KV.first),
231                                           std::move(KV.second), Val);
232    return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
233                          true);
234  }
235
236  /// insert - Range insertion of pairs.
237  template<typename InputIt>
238  void insert(InputIt I, InputIt E) {
239    for (; I != E; ++I)
240      insert(*I);
241  }
242
243  bool erase(const KeyT &Val) {
244    BucketT *TheBucket;
245    if (!LookupBucketFor(Val, TheBucket))
246      return false; // not in map.
247
248    TheBucket->getSecond().~ValueT();
249    TheBucket->getFirst() = getTombstoneKey();
250    decrementNumEntries();
251    incrementNumTombstones();
252    return true;
253  }
254  void erase(iterator I) {
255    BucketT *TheBucket = &*I;
256    TheBucket->getSecond().~ValueT();
257    TheBucket->getFirst() = getTombstoneKey();
258    decrementNumEntries();
259    incrementNumTombstones();
260  }
261
262  value_type& FindAndConstruct(const KeyT &Key) {
263    BucketT *TheBucket;
264    if (LookupBucketFor(Key, TheBucket))
265      return *TheBucket;
266
267    return *InsertIntoBucket(TheBucket, Key);
268  }
269
270  ValueT &operator[](const KeyT &Key) {
271    return FindAndConstruct(Key).second;
272  }
273
274  value_type& FindAndConstruct(KeyT &&Key) {
275    BucketT *TheBucket;
276    if (LookupBucketFor(Key, TheBucket))
277      return *TheBucket;
278
279    return *InsertIntoBucket(TheBucket, std::move(Key));
280  }
281
282  ValueT &operator[](KeyT &&Key) {
283    return FindAndConstruct(std::move(Key)).second;
284  }
285
286  /// isPointerIntoBucketsArray - Return true if the specified pointer points
287  /// somewhere into the DenseMap's array of buckets (i.e. either to a key or
288  /// value in the DenseMap).
289  bool isPointerIntoBucketsArray(const void *Ptr) const {
290    return Ptr >= getBuckets() && Ptr < getBucketsEnd();
291  }
292
293  /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
294  /// array.  In conjunction with the previous method, this can be used to
295  /// determine whether an insertion caused the DenseMap to reallocate.
296  const void *getPointerIntoBucketsArray() const { return getBuckets(); }
297
298protected:
299  DenseMapBase() = default;
300
301  void destroyAll() {
302    if (getNumBuckets() == 0) // Nothing to do.
303      return;
304
305    const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
306    for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
307      if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey) &&
308          !KeyInfoT::isEqual(P->getFirst(), TombstoneKey))
309        P->getSecond().~ValueT();
310      P->getFirst().~KeyT();
311    }
312  }
313
314  void initEmpty() {
315    setNumEntries(0);
316    setNumTombstones(0);
317
318    assert((getNumBuckets() & (getNumBuckets()-1)) == 0 &&
319           "# initial buckets must be a power of two!");
320    const KeyT EmptyKey = getEmptyKey();
321    for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B)
322      ::new (&B->getFirst()) KeyT(EmptyKey);
323  }
324
325  /// Returns the number of buckets to allocate to ensure that the DenseMap can
326  /// accommodate \p NumEntries without need to grow().
327  unsigned getMinBucketToReserveForEntries(unsigned NumEntries) {
328    // Ensure that "NumEntries * 4 < NumBuckets * 3"
329    if (NumEntries == 0)
330      return 0;
331    // +1 is required because of the strict equality.
332    // For example if NumEntries is 48, we need to return 401.
333    return NextPowerOf2(NumEntries * 4 / 3 + 1);
334  }
335
336  void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) {
337    initEmpty();
338
339    // Insert all the old elements.
340    const KeyT EmptyKey = getEmptyKey();
341    const KeyT TombstoneKey = getTombstoneKey();
342    for (BucketT *B = OldBucketsBegin, *E = OldBucketsEnd; B != E; ++B) {
343      if (!KeyInfoT::isEqual(B->getFirst(), EmptyKey) &&
344          !KeyInfoT::isEqual(B->getFirst(), TombstoneKey)) {
345        // Insert the key/value into the new table.
346        BucketT *DestBucket;
347        bool FoundVal = LookupBucketFor(B->getFirst(), DestBucket);
348        (void)FoundVal; // silence warning.
349        assert(!FoundVal && "Key already in new map?");
350        DestBucket->getFirst() = std::move(B->getFirst());
351        ::new (&DestBucket->getSecond()) ValueT(std::move(B->getSecond()));
352        incrementNumEntries();
353
354        // Free the value.
355        B->getSecond().~ValueT();
356      }
357      B->getFirst().~KeyT();
358    }
359  }
360
361  template <typename OtherBaseT>
362  void copyFrom(
363      const DenseMapBase<OtherBaseT, KeyT, ValueT, KeyInfoT, BucketT> &other) {
364    assert(&other != this);
365    assert(getNumBuckets() == other.getNumBuckets());
366
367    setNumEntries(other.getNumEntries());
368    setNumTombstones(other.getNumTombstones());
369
370    if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
371      memcpy(getBuckets(), other.getBuckets(),
372             getNumBuckets() * sizeof(BucketT));
373    else
374      for (size_t i = 0; i < getNumBuckets(); ++i) {
375        ::new (&getBuckets()[i].getFirst())
376            KeyT(other.getBuckets()[i].getFirst());
377        if (!KeyInfoT::isEqual(getBuckets()[i].getFirst(), getEmptyKey()) &&
378            !KeyInfoT::isEqual(getBuckets()[i].getFirst(), getTombstoneKey()))
379          ::new (&getBuckets()[i].getSecond())
380              ValueT(other.getBuckets()[i].getSecond());
381      }
382  }
383
384  static unsigned getHashValue(const KeyT &Val) {
385    return KeyInfoT::getHashValue(Val);
386  }
387  template<typename LookupKeyT>
388  static unsigned getHashValue(const LookupKeyT &Val) {
389    return KeyInfoT::getHashValue(Val);
390  }
391  static const KeyT getEmptyKey() {
392    return KeyInfoT::getEmptyKey();
393  }
394  static const KeyT getTombstoneKey() {
395    return KeyInfoT::getTombstoneKey();
396  }
397
398private:
399  unsigned getNumEntries() const {
400    return static_cast<const DerivedT *>(this)->getNumEntries();
401  }
402  void setNumEntries(unsigned Num) {
403    static_cast<DerivedT *>(this)->setNumEntries(Num);
404  }
405  void incrementNumEntries() {
406    setNumEntries(getNumEntries() + 1);
407  }
408  void decrementNumEntries() {
409    setNumEntries(getNumEntries() - 1);
410  }
411  unsigned getNumTombstones() const {
412    return static_cast<const DerivedT *>(this)->getNumTombstones();
413  }
414  void setNumTombstones(unsigned Num) {
415    static_cast<DerivedT *>(this)->setNumTombstones(Num);
416  }
417  void incrementNumTombstones() {
418    setNumTombstones(getNumTombstones() + 1);
419  }
420  void decrementNumTombstones() {
421    setNumTombstones(getNumTombstones() - 1);
422  }
423  const BucketT *getBuckets() const {
424    return static_cast<const DerivedT *>(this)->getBuckets();
425  }
426  BucketT *getBuckets() {
427    return static_cast<DerivedT *>(this)->getBuckets();
428  }
429  unsigned getNumBuckets() const {
430    return static_cast<const DerivedT *>(this)->getNumBuckets();
431  }
432  BucketT *getBucketsEnd() {
433    return getBuckets() + getNumBuckets();
434  }
435  const BucketT *getBucketsEnd() const {
436    return getBuckets() + getNumBuckets();
437  }
438
439  void grow(unsigned AtLeast) {
440    static_cast<DerivedT *>(this)->grow(AtLeast);
441  }
442
443  void shrink_and_clear() {
444    static_cast<DerivedT *>(this)->shrink_and_clear();
445  }
446
447  template <typename KeyArg, typename... ValueArgs>
448  BucketT *InsertIntoBucket(BucketT *TheBucket, KeyArg &&Key,
449                            ValueArgs &&... Values) {
450    TheBucket = InsertIntoBucketImpl(Key, Key, TheBucket);
451
452    TheBucket->getFirst() = std::forward<KeyArg>(Key);
453    ::new (&TheBucket->getSecond()) ValueT(std::forward<ValueArgs>(Values)...);
454    return TheBucket;
455  }
456
457  template <typename LookupKeyT>
458  BucketT *InsertIntoBucketWithLookup(BucketT *TheBucket, KeyT &&Key,
459                                      ValueT &&Value, LookupKeyT &Lookup) {
460    TheBucket = InsertIntoBucketImpl(Key, Lookup, TheBucket);
461
462    TheBucket->getFirst() = std::move(Key);
463    ::new (&TheBucket->getSecond()) ValueT(std::move(Value));
464    return TheBucket;
465  }
466
467  template <typename LookupKeyT>
468  BucketT *InsertIntoBucketImpl(const KeyT &Key, const LookupKeyT &Lookup,
469                                BucketT *TheBucket) {
470    incrementEpoch();
471
472    // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
473    // the buckets are empty (meaning that many are filled with tombstones),
474    // grow the table.
475    //
476    // The later case is tricky.  For example, if we had one empty bucket with
477    // tons of tombstones, failing lookups (e.g. for insertion) would have to
478    // probe almost the entire table until it found the empty bucket.  If the
479    // table completely filled with tombstones, no lookup would ever succeed,
480    // causing infinite loops in lookup.
481    unsigned NewNumEntries = getNumEntries() + 1;
482    unsigned NumBuckets = getNumBuckets();
483    if (LLVM_UNLIKELY(NewNumEntries * 4 >= NumBuckets * 3)) {
484      this->grow(NumBuckets * 2);
485      LookupBucketFor(Lookup, TheBucket);
486      NumBuckets = getNumBuckets();
487    } else if (LLVM_UNLIKELY(NumBuckets-(NewNumEntries+getNumTombstones()) <=
488                             NumBuckets/8)) {
489      this->grow(NumBuckets);
490      LookupBucketFor(Lookup, TheBucket);
491    }
492    assert(TheBucket);
493
494    // Only update the state after we've grown our bucket space appropriately
495    // so that when growing buckets we have self-consistent entry count.
496    incrementNumEntries();
497
498    // If we are writing over a tombstone, remember this.
499    const KeyT EmptyKey = getEmptyKey();
500    if (!KeyInfoT::isEqual(TheBucket->getFirst(), EmptyKey))
501      decrementNumTombstones();
502
503    return TheBucket;
504  }
505
506  /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
507  /// FoundBucket.  If the bucket contains the key and a value, this returns
508  /// true, otherwise it returns a bucket with an empty marker or tombstone and
509  /// returns false.
510  template<typename LookupKeyT>
511  bool LookupBucketFor(const LookupKeyT &Val,
512                       const BucketT *&FoundBucket) const {
513    const BucketT *BucketsPtr = getBuckets();
514    const unsigned NumBuckets = getNumBuckets();
515
516    if (NumBuckets == 0) {
517      FoundBucket = nullptr;
518      return false;
519    }
520
521    // FoundTombstone - Keep track of whether we find a tombstone while probing.
522    const BucketT *FoundTombstone = nullptr;
523    const KeyT EmptyKey = getEmptyKey();
524    const KeyT TombstoneKey = getTombstoneKey();
525    assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
526           !KeyInfoT::isEqual(Val, TombstoneKey) &&
527           "Empty/Tombstone value shouldn't be inserted into map!");
528
529    unsigned BucketNo = getHashValue(Val) & (NumBuckets-1);
530    unsigned ProbeAmt = 1;
531    while (true) {
532      const BucketT *ThisBucket = BucketsPtr + BucketNo;
533      // Found Val's bucket?  If so, return it.
534      if (LLVM_LIKELY(KeyInfoT::isEqual(Val, ThisBucket->getFirst()))) {
535        FoundBucket = ThisBucket;
536        return true;
537      }
538
539      // If we found an empty bucket, the key doesn't exist in the set.
540      // Insert it and return the default value.
541      if (LLVM_LIKELY(KeyInfoT::isEqual(ThisBucket->getFirst(), EmptyKey))) {
542        // If we've already seen a tombstone while probing, fill it in instead
543        // of the empty bucket we eventually probed to.
544        FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
545        return false;
546      }
547
548      // If this is a tombstone, remember it.  If Val ends up not in the map, we
549      // prefer to return it than something that would require more probing.
550      if (KeyInfoT::isEqual(ThisBucket->getFirst(), TombstoneKey) &&
551          !FoundTombstone)
552        FoundTombstone = ThisBucket;  // Remember the first tombstone found.
553
554      // Otherwise, it's a hash collision or a tombstone, continue quadratic
555      // probing.
556      BucketNo += ProbeAmt++;
557      BucketNo &= (NumBuckets-1);
558    }
559  }
560
561  template <typename LookupKeyT>
562  bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) {
563    const BucketT *ConstFoundBucket;
564    bool Result = const_cast<const DenseMapBase *>(this)
565      ->LookupBucketFor(Val, ConstFoundBucket);
566    FoundBucket = const_cast<BucketT *>(ConstFoundBucket);
567    return Result;
568  }
569
570public:
571  /// Return the approximate size (in bytes) of the actual map.
572  /// This is just the raw memory used by DenseMap.
573  /// If entries are pointers to objects, the size of the referenced objects
574  /// are not included.
575  size_t getMemorySize() const {
576    return getNumBuckets() * sizeof(BucketT);
577  }
578};
579
580template <typename KeyT, typename ValueT,
581          typename KeyInfoT = DenseMapInfo<KeyT>,
582          typename BucketT = detail::DenseMapPair<KeyT, ValueT>>
583class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
584                                     KeyT, ValueT, KeyInfoT, BucketT> {
585  // Lift some types from the dependent base class into this class for
586  // simplicity of referring to them.
587  typedef DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT> BaseT;
588  friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
589
590  BucketT *Buckets;
591  unsigned NumEntries;
592  unsigned NumTombstones;
593  unsigned NumBuckets;
594
595public:
596  /// Create a DenseMap wth an optional \p InitialReserve that guarantee that
597  /// this number of elements can be inserted in the map without grow()
598  explicit DenseMap(unsigned InitialReserve = 0) { init(InitialReserve); }
599
600  DenseMap(const DenseMap &other) : BaseT() {
601    init(0);
602    copyFrom(other);
603  }
604
605  DenseMap(DenseMap &&other) : BaseT() {
606    init(0);
607    swap(other);
608  }
609
610  template<typename InputIt>
611  DenseMap(const InputIt &I, const InputIt &E) {
612    init(std::distance(I, E));
613    this->insert(I, E);
614  }
615
616  ~DenseMap() {
617    this->destroyAll();
618    operator delete(Buckets);
619  }
620
621  void swap(DenseMap& RHS) {
622    this->incrementEpoch();
623    RHS.incrementEpoch();
624    std::swap(Buckets, RHS.Buckets);
625    std::swap(NumEntries, RHS.NumEntries);
626    std::swap(NumTombstones, RHS.NumTombstones);
627    std::swap(NumBuckets, RHS.NumBuckets);
628  }
629
630  DenseMap& operator=(const DenseMap& other) {
631    if (&other != this)
632      copyFrom(other);
633    return *this;
634  }
635
636  DenseMap& operator=(DenseMap &&other) {
637    this->destroyAll();
638    operator delete(Buckets);
639    init(0);
640    swap(other);
641    return *this;
642  }
643
644  void copyFrom(const DenseMap& other) {
645    this->destroyAll();
646    operator delete(Buckets);
647    if (allocateBuckets(other.NumBuckets)) {
648      this->BaseT::copyFrom(other);
649    } else {
650      NumEntries = 0;
651      NumTombstones = 0;
652    }
653  }
654
655  void init(unsigned InitNumEntries) {
656    auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries);
657    if (allocateBuckets(InitBuckets)) {
658      this->BaseT::initEmpty();
659    } else {
660      NumEntries = 0;
661      NumTombstones = 0;
662    }
663  }
664
665  void grow(unsigned AtLeast) {
666    unsigned OldNumBuckets = NumBuckets;
667    BucketT *OldBuckets = Buckets;
668
669    allocateBuckets(std::max<unsigned>(64, static_cast<unsigned>(NextPowerOf2(AtLeast-1))));
670    assert(Buckets);
671    if (!OldBuckets) {
672      this->BaseT::initEmpty();
673      return;
674    }
675
676    this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets);
677
678    // Free the old table.
679    operator delete(OldBuckets);
680  }
681
682  void shrink_and_clear() {
683    unsigned OldNumEntries = NumEntries;
684    this->destroyAll();
685
686    // Reduce the number of buckets.
687    unsigned NewNumBuckets = 0;
688    if (OldNumEntries)
689      NewNumBuckets = std::max(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1));
690    if (NewNumBuckets == NumBuckets) {
691      this->BaseT::initEmpty();
692      return;
693    }
694
695    operator delete(Buckets);
696    init(NewNumBuckets);
697  }
698
699private:
700  unsigned getNumEntries() const {
701    return NumEntries;
702  }
703  void setNumEntries(unsigned Num) {
704    NumEntries = Num;
705  }
706
707  unsigned getNumTombstones() const {
708    return NumTombstones;
709  }
710  void setNumTombstones(unsigned Num) {
711    NumTombstones = Num;
712  }
713
714  BucketT *getBuckets() const {
715    return Buckets;
716  }
717
718  unsigned getNumBuckets() const {
719    return NumBuckets;
720  }
721
722  bool allocateBuckets(unsigned Num) {
723    NumBuckets = Num;
724    if (NumBuckets == 0) {
725      Buckets = nullptr;
726      return false;
727    }
728
729    Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
730    return true;
731  }
732};
733
734template <typename KeyT, typename ValueT, unsigned InlineBuckets = 4,
735          typename KeyInfoT = DenseMapInfo<KeyT>,
736          typename BucketT = detail::DenseMapPair<KeyT, ValueT>>
737class SmallDenseMap
738    : public DenseMapBase<
739          SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT, BucketT>, KeyT,
740          ValueT, KeyInfoT, BucketT> {
741  // Lift some types from the dependent base class into this class for
742  // simplicity of referring to them.
743  typedef DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT> BaseT;
744  friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
745  static_assert(isPowerOf2_64(InlineBuckets),
746                "InlineBuckets must be a power of 2.");
747
748  unsigned Small : 1;
749  unsigned NumEntries : 31;
750  unsigned NumTombstones;
751
752  struct LargeRep {
753    BucketT *Buckets;
754    unsigned NumBuckets;
755  };
756
757  /// A "union" of an inline bucket array and the struct representing
758  /// a large bucket. This union will be discriminated by the 'Small' bit.
759  AlignedCharArrayUnion<BucketT[InlineBuckets], LargeRep> storage;
760
761public:
762  explicit SmallDenseMap(unsigned NumInitBuckets = 0) {
763    init(NumInitBuckets);
764  }
765
766  SmallDenseMap(const SmallDenseMap &other) : BaseT() {
767    init(0);
768    copyFrom(other);
769  }
770
771  SmallDenseMap(SmallDenseMap &&other) : BaseT() {
772    init(0);
773    swap(other);
774  }
775
776  template<typename InputIt>
777  SmallDenseMap(const InputIt &I, const InputIt &E) {
778    init(NextPowerOf2(std::distance(I, E)));
779    this->insert(I, E);
780  }
781
782  ~SmallDenseMap() {
783    this->destroyAll();
784    deallocateBuckets();
785  }
786
787  void swap(SmallDenseMap& RHS) {
788    unsigned TmpNumEntries = RHS.NumEntries;
789    RHS.NumEntries = NumEntries;
790    NumEntries = TmpNumEntries;
791    std::swap(NumTombstones, RHS.NumTombstones);
792
793    const KeyT EmptyKey = this->getEmptyKey();
794    const KeyT TombstoneKey = this->getTombstoneKey();
795    if (Small && RHS.Small) {
796      // If we're swapping inline bucket arrays, we have to cope with some of
797      // the tricky bits of DenseMap's storage system: the buckets are not
798      // fully initialized. Thus we swap every key, but we may have
799      // a one-directional move of the value.
800      for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
801        BucketT *LHSB = &getInlineBuckets()[i],
802                *RHSB = &RHS.getInlineBuckets()[i];
803        bool hasLHSValue = (!KeyInfoT::isEqual(LHSB->getFirst(), EmptyKey) &&
804                            !KeyInfoT::isEqual(LHSB->getFirst(), TombstoneKey));
805        bool hasRHSValue = (!KeyInfoT::isEqual(RHSB->getFirst(), EmptyKey) &&
806                            !KeyInfoT::isEqual(RHSB->getFirst(), TombstoneKey));
807        if (hasLHSValue && hasRHSValue) {
808          // Swap together if we can...
809          std::swap(*LHSB, *RHSB);
810          continue;
811        }
812        // Swap separately and handle any assymetry.
813        std::swap(LHSB->getFirst(), RHSB->getFirst());
814        if (hasLHSValue) {
815          ::new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond()));
816          LHSB->getSecond().~ValueT();
817        } else if (hasRHSValue) {
818          ::new (&LHSB->getSecond()) ValueT(std::move(RHSB->getSecond()));
819          RHSB->getSecond().~ValueT();
820        }
821      }
822      return;
823    }
824    if (!Small && !RHS.Small) {
825      std::swap(getLargeRep()->Buckets, RHS.getLargeRep()->Buckets);
826      std::swap(getLargeRep()->NumBuckets, RHS.getLargeRep()->NumBuckets);
827      return;
828    }
829
830    SmallDenseMap &SmallSide = Small ? *this : RHS;
831    SmallDenseMap &LargeSide = Small ? RHS : *this;
832
833    // First stash the large side's rep and move the small side across.
834    LargeRep TmpRep = std::move(*LargeSide.getLargeRep());
835    LargeSide.getLargeRep()->~LargeRep();
836    LargeSide.Small = true;
837    // This is similar to the standard move-from-old-buckets, but the bucket
838    // count hasn't actually rotated in this case. So we have to carefully
839    // move construct the keys and values into their new locations, but there
840    // is no need to re-hash things.
841    for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
842      BucketT *NewB = &LargeSide.getInlineBuckets()[i],
843              *OldB = &SmallSide.getInlineBuckets()[i];
844      ::new (&NewB->getFirst()) KeyT(std::move(OldB->getFirst()));
845      OldB->getFirst().~KeyT();
846      if (!KeyInfoT::isEqual(NewB->getFirst(), EmptyKey) &&
847          !KeyInfoT::isEqual(NewB->getFirst(), TombstoneKey)) {
848        ::new (&NewB->getSecond()) ValueT(std::move(OldB->getSecond()));
849        OldB->getSecond().~ValueT();
850      }
851    }
852
853    // The hard part of moving the small buckets across is done, just move
854    // the TmpRep into its new home.
855    SmallSide.Small = false;
856    new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep));
857  }
858
859  SmallDenseMap& operator=(const SmallDenseMap& other) {
860    if (&other != this)
861      copyFrom(other);
862    return *this;
863  }
864
865  SmallDenseMap& operator=(SmallDenseMap &&other) {
866    this->destroyAll();
867    deallocateBuckets();
868    init(0);
869    swap(other);
870    return *this;
871  }
872
873  void copyFrom(const SmallDenseMap& other) {
874    this->destroyAll();
875    deallocateBuckets();
876    Small = true;
877    if (other.getNumBuckets() > InlineBuckets) {
878      Small = false;
879      new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets()));
880    }
881    this->BaseT::copyFrom(other);
882  }
883
884  void init(unsigned InitBuckets) {
885    Small = true;
886    if (InitBuckets > InlineBuckets) {
887      Small = false;
888      new (getLargeRep()) LargeRep(allocateBuckets(InitBuckets));
889    }
890    this->BaseT::initEmpty();
891  }
892
893  void grow(unsigned AtLeast) {
894    if (AtLeast >= InlineBuckets)
895      AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast-1));
896
897    if (Small) {
898      if (AtLeast < InlineBuckets)
899        return; // Nothing to do.
900
901      // First move the inline buckets into a temporary storage.
902      AlignedCharArrayUnion<BucketT[InlineBuckets]> TmpStorage;
903      BucketT *TmpBegin = reinterpret_cast<BucketT *>(TmpStorage.buffer);
904      BucketT *TmpEnd = TmpBegin;
905
906      // Loop over the buckets, moving non-empty, non-tombstones into the
907      // temporary storage. Have the loop move the TmpEnd forward as it goes.
908      const KeyT EmptyKey = this->getEmptyKey();
909      const KeyT TombstoneKey = this->getTombstoneKey();
910      for (BucketT *P = getBuckets(), *E = P + InlineBuckets; P != E; ++P) {
911        if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey) &&
912            !KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) {
913          assert(size_t(TmpEnd - TmpBegin) < InlineBuckets &&
914                 "Too many inline buckets!");
915          ::new (&TmpEnd->getFirst()) KeyT(std::move(P->getFirst()));
916          ::new (&TmpEnd->getSecond()) ValueT(std::move(P->getSecond()));
917          ++TmpEnd;
918          P->getSecond().~ValueT();
919        }
920        P->getFirst().~KeyT();
921      }
922
923      // Now make this map use the large rep, and move all the entries back
924      // into it.
925      Small = false;
926      new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
927      this->moveFromOldBuckets(TmpBegin, TmpEnd);
928      return;
929    }
930
931    LargeRep OldRep = std::move(*getLargeRep());
932    getLargeRep()->~LargeRep();
933    if (AtLeast <= InlineBuckets) {
934      Small = true;
935    } else {
936      new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
937    }
938
939    this->moveFromOldBuckets(OldRep.Buckets, OldRep.Buckets+OldRep.NumBuckets);
940
941    // Free the old table.
942    operator delete(OldRep.Buckets);
943  }
944
945  void shrink_and_clear() {
946    unsigned OldSize = this->size();
947    this->destroyAll();
948
949    // Reduce the number of buckets.
950    unsigned NewNumBuckets = 0;
951    if (OldSize) {
952      NewNumBuckets = 1 << (Log2_32_Ceil(OldSize) + 1);
953      if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u)
954        NewNumBuckets = 64;
955    }
956    if ((Small && NewNumBuckets <= InlineBuckets) ||
957        (!Small && NewNumBuckets == getLargeRep()->NumBuckets)) {
958      this->BaseT::initEmpty();
959      return;
960    }
961
962    deallocateBuckets();
963    init(NewNumBuckets);
964  }
965
966private:
967  unsigned getNumEntries() const {
968    return NumEntries;
969  }
970  void setNumEntries(unsigned Num) {
971    // NumEntries is hardcoded to be 31 bits wide.
972    assert(Num < (1U << 31) && "Cannot support more than 1<<31 entries");
973    NumEntries = Num;
974  }
975
976  unsigned getNumTombstones() const {
977    return NumTombstones;
978  }
979  void setNumTombstones(unsigned Num) {
980    NumTombstones = Num;
981  }
982
983  const BucketT *getInlineBuckets() const {
984    assert(Small);
985    // Note that this cast does not violate aliasing rules as we assert that
986    // the memory's dynamic type is the small, inline bucket buffer, and the
987    // 'storage.buffer' static type is 'char *'.
988    return reinterpret_cast<const BucketT *>(storage.buffer);
989  }
990  BucketT *getInlineBuckets() {
991    return const_cast<BucketT *>(
992      const_cast<const SmallDenseMap *>(this)->getInlineBuckets());
993  }
994  const LargeRep *getLargeRep() const {
995    assert(!Small);
996    // Note, same rule about aliasing as with getInlineBuckets.
997    return reinterpret_cast<const LargeRep *>(storage.buffer);
998  }
999  LargeRep *getLargeRep() {
1000    return const_cast<LargeRep *>(
1001      const_cast<const SmallDenseMap *>(this)->getLargeRep());
1002  }
1003
1004  const BucketT *getBuckets() const {
1005    return Small ? getInlineBuckets() : getLargeRep()->Buckets;
1006  }
1007  BucketT *getBuckets() {
1008    return const_cast<BucketT *>(
1009      const_cast<const SmallDenseMap *>(this)->getBuckets());
1010  }
1011  unsigned getNumBuckets() const {
1012    return Small ? InlineBuckets : getLargeRep()->NumBuckets;
1013  }
1014
1015  void deallocateBuckets() {
1016    if (Small)
1017      return;
1018
1019    operator delete(getLargeRep()->Buckets);
1020    getLargeRep()->~LargeRep();
1021  }
1022
1023  LargeRep allocateBuckets(unsigned Num) {
1024    assert(Num > InlineBuckets && "Must allocate more buckets than are inline");
1025    LargeRep Rep = {
1026      static_cast<BucketT*>(operator new(sizeof(BucketT) * Num)), Num
1027    };
1028    return Rep;
1029  }
1030};
1031
1032template <typename KeyT, typename ValueT, typename KeyInfoT, typename Bucket,
1033          bool IsConst>
1034class DenseMapIterator : DebugEpochBase::HandleBase {
1035  typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true> ConstIterator;
1036  friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
1037  friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false>;
1038
1039public:
1040  typedef ptrdiff_t difference_type;
1041  typedef typename std::conditional<IsConst, const Bucket, Bucket>::type
1042  value_type;
1043  typedef value_type *pointer;
1044  typedef value_type &reference;
1045  typedef std::forward_iterator_tag iterator_category;
1046
1047private:
1048  pointer Ptr, End;
1049
1050public:
1051  DenseMapIterator() : Ptr(nullptr), End(nullptr) {}
1052
1053  DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch,
1054                   bool NoAdvance = false)
1055      : DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) {
1056    assert(isHandleInSync() && "invalid construction!");
1057    if (!NoAdvance) AdvancePastEmptyBuckets();
1058  }
1059
1060  // Converting ctor from non-const iterators to const iterators. SFINAE'd out
1061  // for const iterator destinations so it doesn't end up as a user defined copy
1062  // constructor.
1063  template <bool IsConstSrc,
1064            typename = typename std::enable_if<!IsConstSrc && IsConst>::type>
1065  DenseMapIterator(
1066      const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc> &I)
1067      : DebugEpochBase::HandleBase(I), Ptr(I.Ptr), End(I.End) {}
1068
1069  reference operator*() const {
1070    assert(isHandleInSync() && "invalid iterator access!");
1071    return *Ptr;
1072  }
1073  pointer operator->() const {
1074    assert(isHandleInSync() && "invalid iterator access!");
1075    return Ptr;
1076  }
1077
1078  bool operator==(const ConstIterator &RHS) const {
1079    assert((!Ptr || isHandleInSync()) && "handle not in sync!");
1080    assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
1081    assert(getEpochAddress() == RHS.getEpochAddress() &&
1082           "comparing incomparable iterators!");
1083    return Ptr == RHS.Ptr;
1084  }
1085  bool operator!=(const ConstIterator &RHS) const {
1086    assert((!Ptr || isHandleInSync()) && "handle not in sync!");
1087    assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
1088    assert(getEpochAddress() == RHS.getEpochAddress() &&
1089           "comparing incomparable iterators!");
1090    return Ptr != RHS.Ptr;
1091  }
1092
1093  inline DenseMapIterator& operator++() {  // Preincrement
1094    assert(isHandleInSync() && "invalid iterator access!");
1095    ++Ptr;
1096    AdvancePastEmptyBuckets();
1097    return *this;
1098  }
1099  DenseMapIterator operator++(int) {  // Postincrement
1100    assert(isHandleInSync() && "invalid iterator access!");
1101    DenseMapIterator tmp = *this; ++*this; return tmp;
1102  }
1103
1104private:
1105  void AdvancePastEmptyBuckets() {
1106    const KeyT Empty = KeyInfoT::getEmptyKey();
1107    const KeyT Tombstone = KeyInfoT::getTombstoneKey();
1108
1109    while (Ptr != End && (KeyInfoT::isEqual(Ptr->getFirst(), Empty) ||
1110                          KeyInfoT::isEqual(Ptr->getFirst(), Tombstone)))
1111      ++Ptr;
1112  }
1113};
1114
1115template<typename KeyT, typename ValueT, typename KeyInfoT>
1116static inline size_t
1117capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
1118  return X.getMemorySize();
1119}
1120
1121} // end namespace llvm
1122
1123#endif // LLVM_ADT_DENSEMAP_H
1124