DenseMap's move assignment operator needs to return *this
[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/MathExtras.h"
19 #include "llvm/Support/PointerLikeTypeTraits.h"
20 #include "llvm/Support/type_traits.h"
21 #include "llvm/ADT/DenseMapInfo.h"
22 #include <algorithm>
23 #include <iterator>
24 #include <new>
25 #include <utility>
26 #include <cassert>
27 #include <cstddef>
28 #include <cstring>
29
30 namespace llvm {
31
32 template<typename KeyT, typename ValueT,
33          typename KeyInfoT = DenseMapInfo<KeyT>,
34          bool IsConst = false>
35 class DenseMapIterator;
36
37 template<typename KeyT, typename ValueT,
38          typename KeyInfoT = DenseMapInfo<KeyT> >
39 class DenseMap {
40   typedef std::pair<KeyT, ValueT> BucketT;
41   unsigned NumBuckets;
42   BucketT *Buckets;
43
44   unsigned NumEntries;
45   unsigned NumTombstones;
46 public:
47   typedef KeyT key_type;
48   typedef ValueT mapped_type;
49   typedef BucketT value_type;
50
51   DenseMap(const DenseMap &other) {
52     NumBuckets = 0;
53     CopyFrom(other);
54   }
55
56 #if LLVM_USE_RVALUE_REFERENCES
57   DenseMap(DenseMap &&other) {
58     init(0);
59     swap(other);
60   }
61 #endif
62
63   explicit DenseMap(unsigned NumInitBuckets = 0) {
64     init(NumInitBuckets);
65   }
66
67   template<typename InputIt>
68   DenseMap(const InputIt &I, const InputIt &E) {
69     init(NextPowerOf2(std::distance(I, E)));
70     insert(I, E);
71   }
72
73   ~DenseMap() {
74     DestroyAll();
75   }
76
77   typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
78   typedef DenseMapIterator<KeyT, ValueT,
79                            KeyInfoT, true> const_iterator;
80   inline iterator begin() {
81     // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
82     return empty() ? end() : iterator(Buckets, Buckets+NumBuckets);
83   }
84   inline iterator end() {
85     return iterator(Buckets+NumBuckets, Buckets+NumBuckets, true);
86   }
87   inline const_iterator begin() const {
88     return empty() ? end() : const_iterator(Buckets, Buckets+NumBuckets);
89   }
90   inline const_iterator end() const {
91     return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets, true);
92   }
93
94   bool empty() const { return NumEntries == 0; }
95   unsigned size() const { return NumEntries; }
96
97   /// Grow the densemap so that it has at least Size buckets. Does not shrink
98   void resize(size_t Size) {
99     if (Size > NumBuckets)
100       grow(Size);
101   }
102
103   void clear() {
104     if (NumEntries == 0 && NumTombstones == 0) return;
105     
106     // If the capacity of the array is huge, and the # elements used is small,
107     // shrink the array.
108     if (NumEntries * 4 < NumBuckets && NumBuckets > 64) {
109       shrink_and_clear();
110       return;
111     }
112
113     const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
114     for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
115       if (!KeyInfoT::isEqual(P->first, EmptyKey)) {
116         if (!KeyInfoT::isEqual(P->first, TombstoneKey)) {
117           P->second.~ValueT();
118           --NumEntries;
119         }
120         P->first = EmptyKey;
121       }
122     }
123     assert(NumEntries == 0 && "Node count imbalance!");
124     NumTombstones = 0;
125   }
126
127   /// count - Return true if the specified key is in the map.
128   bool count(const KeyT &Val) const {
129     BucketT *TheBucket;
130     return LookupBucketFor(Val, TheBucket);
131   }
132
133   iterator find(const KeyT &Val) {
134     BucketT *TheBucket;
135     if (LookupBucketFor(Val, TheBucket))
136       return iterator(TheBucket, Buckets+NumBuckets, true);
137     return end();
138   }
139   const_iterator find(const KeyT &Val) const {
140     BucketT *TheBucket;
141     if (LookupBucketFor(Val, TheBucket))
142       return const_iterator(TheBucket, Buckets+NumBuckets, true);
143     return end();
144   }
145
146   /// Alternate version of find() which allows a different, and possibly
147   /// less expensive, key type.
148   /// The DenseMapInfo is responsible for supplying methods
149   /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
150   /// type used.
151   template<class LookupKeyT>
152   iterator find_as(const LookupKeyT &Val) {
153     BucketT *TheBucket;
154     if (LookupBucketFor(Val, TheBucket))
155       return iterator(TheBucket, Buckets+NumBuckets, true);
156     return end();
157   }
158   template<class LookupKeyT>
159   const_iterator find_as(const LookupKeyT &Val) const {
160     BucketT *TheBucket;
161     if (LookupBucketFor(Val, TheBucket))
162       return const_iterator(TheBucket, Buckets+NumBuckets, true);
163     return end();
164   }
165
166   /// lookup - Return the entry for the specified key, or a default
167   /// constructed value if no such entry exists.
168   ValueT lookup(const KeyT &Val) const {
169     BucketT *TheBucket;
170     if (LookupBucketFor(Val, TheBucket))
171       return TheBucket->second;
172     return ValueT();
173   }
174
175   // Inserts key,value pair into the map if the key isn't already in the map.
176   // If the key is already in the map, it returns false and doesn't update the
177   // value.
178   std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
179     BucketT *TheBucket;
180     if (LookupBucketFor(KV.first, TheBucket))
181       return std::make_pair(iterator(TheBucket, Buckets+NumBuckets, true),
182                             false); // Already in map.
183
184     // Otherwise, insert the new element.
185     TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
186     return std::make_pair(iterator(TheBucket, Buckets+NumBuckets, true), true);
187   }
188
189   /// insert - Range insertion of pairs.
190   template<typename InputIt>
191   void insert(InputIt I, InputIt E) {
192     for (; I != E; ++I)
193       insert(*I);
194   }
195
196
197   bool erase(const KeyT &Val) {
198     BucketT *TheBucket;
199     if (!LookupBucketFor(Val, TheBucket))
200       return false; // not in map.
201
202     TheBucket->second.~ValueT();
203     TheBucket->first = getTombstoneKey();
204     --NumEntries;
205     ++NumTombstones;
206     return true;
207   }
208   void erase(iterator I) {
209     BucketT *TheBucket = &*I;
210     TheBucket->second.~ValueT();
211     TheBucket->first = getTombstoneKey();
212     --NumEntries;
213     ++NumTombstones;
214   }
215
216   void swap(DenseMap& RHS) {
217     std::swap(NumBuckets, RHS.NumBuckets);
218     std::swap(Buckets, RHS.Buckets);
219     std::swap(NumEntries, RHS.NumEntries);
220     std::swap(NumTombstones, RHS.NumTombstones);
221   }
222
223   value_type& FindAndConstruct(const KeyT &Key) {
224     BucketT *TheBucket;
225     if (LookupBucketFor(Key, TheBucket))
226       return *TheBucket;
227
228     return *InsertIntoBucket(Key, ValueT(), TheBucket);
229   }
230
231   ValueT &operator[](const KeyT &Key) {
232     return FindAndConstruct(Key).second;
233   }
234
235 #if LLVM_USE_RVALUE_REFERENCES
236   value_type& FindAndConstruct(KeyT &&Key) {
237     BucketT *TheBucket;
238     if (LookupBucketFor(Key, TheBucket))
239       return *TheBucket;
240
241     return *InsertIntoBucket(Key, ValueT(), TheBucket);
242   }
243
244   ValueT &operator[](KeyT &&Key) {
245     return FindAndConstruct(Key).second;
246   }
247 #endif
248
249   DenseMap& operator=(const DenseMap& other) {
250     CopyFrom(other);
251     return *this;
252   }
253
254 #if LLVM_USE_RVALUE_REFERENCES
255   DenseMap& operator=(DenseMap &&other) {
256     DestroyAll();
257     init(0);
258     swap(other);
259     return *this;
260   }
261 #endif
262
263   /// isPointerIntoBucketsArray - Return true if the specified pointer points
264   /// somewhere into the DenseMap's array of buckets (i.e. either to a key or
265   /// value in the DenseMap).
266   bool isPointerIntoBucketsArray(const void *Ptr) const {
267     return Ptr >= Buckets && Ptr < Buckets+NumBuckets;
268   }
269
270   /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
271   /// array.  In conjunction with the previous method, this can be used to
272   /// determine whether an insertion caused the DenseMap to reallocate.
273   const void *getPointerIntoBucketsArray() const { return Buckets; }
274
275 private:
276   void DestroyAll() {
277     if (NumBuckets == 0) // Nothing to do.
278       return;
279
280     const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
281     for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
282       if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
283           !KeyInfoT::isEqual(P->first, TombstoneKey))
284         P->second.~ValueT();
285       P->first.~KeyT();
286     }
287
288 #ifndef NDEBUG
289     memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets);
290 #endif
291     operator delete(Buckets);
292   }
293
294   void CopyFrom(const DenseMap& other) {
295     DestroyAll();
296
297     NumEntries = other.NumEntries;
298     NumTombstones = other.NumTombstones;
299     NumBuckets = other.NumBuckets;
300
301     if (NumBuckets == 0) {
302       Buckets = 0;
303       return;
304     }
305
306     Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
307
308     if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
309       memcpy(Buckets, other.Buckets, NumBuckets * sizeof(BucketT));
310     else
311       for (size_t i = 0; i < NumBuckets; ++i) {
312         new (&Buckets[i].first) KeyT(other.Buckets[i].first);
313         if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) &&
314             !KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey()))
315           new (&Buckets[i].second) ValueT(other.Buckets[i].second);
316       }
317   }
318
319   BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
320                             BucketT *TheBucket) {
321     TheBucket = InsertIntoBucketImpl(Key, TheBucket);
322
323     TheBucket->first = Key;
324     new (&TheBucket->second) ValueT(Value);
325     return TheBucket;
326   }
327
328 #if LLVM_USE_RVALUE_REFERENCES
329   BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
330                             BucketT *TheBucket) {
331     TheBucket = InsertIntoBucketImpl(Key, TheBucket);
332
333     TheBucket->first = Key;
334     new (&TheBucket->second) ValueT(std::move(Value));
335     return TheBucket;
336   }
337
338   BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, BucketT *TheBucket) {
339     TheBucket = InsertIntoBucketImpl(Key, TheBucket);
340
341     TheBucket->first = std::move(Key);
342     new (&TheBucket->second) ValueT(std::move(Value));
343     return TheBucket;
344   }
345 #endif
346
347   BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) {
348     // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
349     // the buckets are empty (meaning that many are filled with tombstones),
350     // grow the table.
351     //
352     // The later case is tricky.  For example, if we had one empty bucket with
353     // tons of tombstones, failing lookups (e.g. for insertion) would have to
354     // probe almost the entire table until it found the empty bucket.  If the
355     // table completely filled with tombstones, no lookup would ever succeed,
356     // causing infinite loops in lookup.
357     ++NumEntries;
358     if (NumEntries*4 >= NumBuckets*3) {
359       this->grow(NumBuckets * 2);
360       LookupBucketFor(Key, TheBucket);
361     }
362     if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
363       this->grow(NumBuckets);
364       LookupBucketFor(Key, TheBucket);
365     }
366
367     // If we are writing over a tombstone, remember this.
368     if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
369       --NumTombstones;
370
371     return TheBucket;
372   }
373
374   static unsigned getHashValue(const KeyT &Val) {
375     return KeyInfoT::getHashValue(Val);
376   }
377   template<typename LookupKeyT>
378   static unsigned getHashValue(const LookupKeyT &Val) {
379     return KeyInfoT::getHashValue(Val);
380   }
381   static const KeyT getEmptyKey() {
382     return KeyInfoT::getEmptyKey();
383   }
384   static const KeyT getTombstoneKey() {
385     return KeyInfoT::getTombstoneKey();
386   }
387
388   /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
389   /// FoundBucket.  If the bucket contains the key and a value, this returns
390   /// true, otherwise it returns a bucket with an empty marker or tombstone and
391   /// returns false.
392   template<typename LookupKeyT>
393   bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) const {
394     unsigned BucketNo = getHashValue(Val);
395     unsigned ProbeAmt = 1;
396     BucketT *BucketsPtr = Buckets;
397
398     if (NumBuckets == 0) {
399       FoundBucket = 0;
400       return false;
401     }
402
403     // FoundTombstone - Keep track of whether we find a tombstone while probing.
404     BucketT *FoundTombstone = 0;
405     const KeyT EmptyKey = getEmptyKey();
406     const KeyT TombstoneKey = getTombstoneKey();
407     assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
408            !KeyInfoT::isEqual(Val, TombstoneKey) &&
409            "Empty/Tombstone value shouldn't be inserted into map!");
410
411     while (1) {
412       BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
413       // Found Val's bucket?  If so, return it.
414       if (KeyInfoT::isEqual(Val, ThisBucket->first)) {
415         FoundBucket = ThisBucket;
416         return true;
417       }
418
419       // If we found an empty bucket, the key doesn't exist in the set.
420       // Insert it and return the default value.
421       if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
422         // If we've already seen a tombstone while probing, fill it in instead
423         // of the empty bucket we eventually probed to.
424         if (FoundTombstone) ThisBucket = FoundTombstone;
425         FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
426         return false;
427       }
428
429       // If this is a tombstone, remember it.  If Val ends up not in the map, we
430       // prefer to return it than something that would require more probing.
431       if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombstone)
432         FoundTombstone = ThisBucket;  // Remember the first tombstone found.
433
434       // Otherwise, it's a hash collision or a tombstone, continue quadratic
435       // probing.
436       BucketNo += ProbeAmt++;
437     }
438   }
439
440   void init(unsigned InitBuckets) {
441     NumEntries = 0;
442     NumTombstones = 0;
443     NumBuckets = InitBuckets;
444
445     if (InitBuckets == 0) {
446       Buckets = 0;
447       return;
448     }
449
450     assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 &&
451            "# initial buckets must be a power of two!");
452     Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets));
453     // Initialize all the keys to EmptyKey.
454     const KeyT EmptyKey = getEmptyKey();
455     for (unsigned i = 0; i != InitBuckets; ++i)
456       new (&Buckets[i].first) KeyT(EmptyKey);
457   }
458
459   void grow(unsigned AtLeast) {
460     unsigned OldNumBuckets = NumBuckets;
461     BucketT *OldBuckets = Buckets;
462
463     if (NumBuckets < 64)
464       NumBuckets = 64;
465
466     // Double the number of buckets.
467     while (NumBuckets < AtLeast)
468       NumBuckets <<= 1;
469     NumTombstones = 0;
470     Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
471
472     // Initialize all the keys to EmptyKey.
473     const KeyT EmptyKey = getEmptyKey();
474     for (unsigned i = 0, e = NumBuckets; i != e; ++i)
475       new (&Buckets[i].first) KeyT(EmptyKey);
476
477     // Insert all the old elements.
478     const KeyT TombstoneKey = getTombstoneKey();
479     for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
480       if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
481           !KeyInfoT::isEqual(B->first, TombstoneKey)) {
482         // Insert the key/value into the new table.
483         BucketT *DestBucket;
484         bool FoundVal = LookupBucketFor(B->first, DestBucket);
485         (void)FoundVal; // silence warning.
486         assert(!FoundVal && "Key already in new map?");
487         DestBucket->first = llvm_move(B->first);
488         new (&DestBucket->second) ValueT(llvm_move(B->second));
489
490         // Free the value.
491         B->second.~ValueT();
492       }
493       B->first.~KeyT();
494     }
495
496 #ifndef NDEBUG
497     if (OldNumBuckets)
498       memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
499 #endif
500     // Free the old table.
501     operator delete(OldBuckets);
502   }
503
504   void shrink_and_clear() {
505     unsigned OldNumBuckets = NumBuckets;
506     BucketT *OldBuckets = Buckets;
507
508     // Reduce the number of buckets.
509     NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1)
510                                  : 64;
511     NumTombstones = 0;
512     Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
513
514     // Initialize all the keys to EmptyKey.
515     const KeyT EmptyKey = getEmptyKey();
516     for (unsigned i = 0, e = NumBuckets; i != e; ++i)
517       new (&Buckets[i].first) KeyT(EmptyKey);
518
519     // Free the old buckets.
520     const KeyT TombstoneKey = getTombstoneKey();
521     for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
522       if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
523           !KeyInfoT::isEqual(B->first, TombstoneKey)) {
524         // Free the value.
525         B->second.~ValueT();
526       }
527       B->first.~KeyT();
528     }
529
530 #ifndef NDEBUG
531     memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
532 #endif
533     // Free the old table.
534     operator delete(OldBuckets);
535
536     NumEntries = 0;
537   }
538   
539 public:
540   /// Return the approximate size (in bytes) of the actual map.
541   /// This is just the raw memory used by DenseMap.
542   /// If entries are pointers to objects, the size of the referenced objects
543   /// are not included.
544   size_t getMemorySize() const {
545     return NumBuckets * sizeof(BucketT);
546   }
547 };
548
549 template<typename KeyT, typename ValueT,
550          typename KeyInfoT, bool IsConst>
551 class DenseMapIterator {
552   typedef std::pair<KeyT, ValueT> Bucket;
553   typedef DenseMapIterator<KeyT, ValueT,
554                            KeyInfoT, true> ConstIterator;
555   friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>;
556 public:
557   typedef ptrdiff_t difference_type;
558   typedef typename conditional<IsConst, const Bucket, Bucket>::type value_type;
559   typedef value_type *pointer;
560   typedef value_type &reference;
561   typedef std::forward_iterator_tag iterator_category;
562 private:
563   pointer Ptr, End;
564 public:
565   DenseMapIterator() : Ptr(0), End(0) {}
566
567   DenseMapIterator(pointer Pos, pointer E, bool NoAdvance = false)
568     : Ptr(Pos), End(E) {
569     if (!NoAdvance) AdvancePastEmptyBuckets();
570   }
571
572   // If IsConst is true this is a converting constructor from iterator to
573   // const_iterator and the default copy constructor is used.
574   // Otherwise this is a copy constructor for iterator.
575   DenseMapIterator(const DenseMapIterator<KeyT, ValueT,
576                                           KeyInfoT, false>& I)
577     : Ptr(I.Ptr), End(I.End) {}
578
579   reference operator*() const {
580     return *Ptr;
581   }
582   pointer operator->() const {
583     return Ptr;
584   }
585
586   bool operator==(const ConstIterator &RHS) const {
587     return Ptr == RHS.operator->();
588   }
589   bool operator!=(const ConstIterator &RHS) const {
590     return Ptr != RHS.operator->();
591   }
592
593   inline DenseMapIterator& operator++() {  // Preincrement
594     ++Ptr;
595     AdvancePastEmptyBuckets();
596     return *this;
597   }
598   DenseMapIterator operator++(int) {  // Postincrement
599     DenseMapIterator tmp = *this; ++*this; return tmp;
600   }
601
602 private:
603   void AdvancePastEmptyBuckets() {
604     const KeyT Empty = KeyInfoT::getEmptyKey();
605     const KeyT Tombstone = KeyInfoT::getTombstoneKey();
606
607     while (Ptr != End &&
608            (KeyInfoT::isEqual(Ptr->first, Empty) ||
609             KeyInfoT::isEqual(Ptr->first, Tombstone)))
610       ++Ptr;
611   }
612 };
613   
614 template<typename KeyT, typename ValueT, typename KeyInfoT>
615 static inline size_t
616 capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
617   return X.getMemorySize();
618 }
619
620 } // end namespace llvm
621
622 #endif