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