DenseMap: Provide a move ctor and move semantics for operator[] and FindAndConstruct.
[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   }
260 #endif
261
262   /// isPointerIntoBucketsArray - Return true if the specified pointer points
263   /// somewhere into the DenseMap's array of buckets (i.e. either to a key or
264   /// value in the DenseMap).
265   bool isPointerIntoBucketsArray(const void *Ptr) const {
266     return Ptr >= Buckets && Ptr < Buckets+NumBuckets;
267   }
268
269   /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
270   /// array.  In conjunction with the previous method, this can be used to
271   /// determine whether an insertion caused the DenseMap to reallocate.
272   const void *getPointerIntoBucketsArray() const { return Buckets; }
273
274 private:
275   void DestroyAll() {
276     const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
277     for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
278       if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
279           !KeyInfoT::isEqual(P->first, TombstoneKey))
280         P->second.~ValueT();
281       P->first.~KeyT();
282     }
283
284     if (NumBuckets) {
285 #ifndef NDEBUG
286       memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets);
287 #endif
288       operator delete(Buckets);
289     }
290   }
291
292   void CopyFrom(const DenseMap& other) {
293     DestroyAll();
294
295     NumEntries = other.NumEntries;
296     NumTombstones = other.NumTombstones;
297     NumBuckets = other.NumBuckets;
298
299     if (NumBuckets == 0) {
300       Buckets = 0;
301       return;
302     }
303
304     Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
305
306     if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
307       memcpy(Buckets, other.Buckets, NumBuckets * sizeof(BucketT));
308     else
309       for (size_t i = 0; i < NumBuckets; ++i) {
310         new (&Buckets[i].first) KeyT(other.Buckets[i].first);
311         if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) &&
312             !KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey()))
313           new (&Buckets[i].second) ValueT(other.Buckets[i].second);
314       }
315   }
316
317   BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
318                             BucketT *TheBucket) {
319     TheBucket = InsertIntoBucketImpl(Key, TheBucket);
320
321     TheBucket->first = Key;
322     new (&TheBucket->second) ValueT(Value);
323     return TheBucket;
324   }
325
326 #if LLVM_USE_RVALUE_REFERENCES
327   BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
328                             BucketT *TheBucket) {
329     TheBucket = InsertIntoBucketImpl(Key, TheBucket);
330
331     TheBucket->first = Key;
332     new (&TheBucket->second) ValueT(std::move(Value));
333     return TheBucket;
334   }
335
336   BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, BucketT *TheBucket) {
337     TheBucket = InsertIntoBucketImpl(Key, TheBucket);
338
339     TheBucket->first = std::move(Key);
340     new (&TheBucket->second) ValueT(std::move(Value));
341     return TheBucket;
342   }
343 #endif
344
345   BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) {
346     // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
347     // the buckets are empty (meaning that many are filled with tombstones),
348     // grow the table.
349     //
350     // The later case is tricky.  For example, if we had one empty bucket with
351     // tons of tombstones, failing lookups (e.g. for insertion) would have to
352     // probe almost the entire table until it found the empty bucket.  If the
353     // table completely filled with tombstones, no lookup would ever succeed,
354     // causing infinite loops in lookup.
355     ++NumEntries;
356     if (NumEntries*4 >= NumBuckets*3) {
357       this->grow(NumBuckets * 2);
358       LookupBucketFor(Key, TheBucket);
359     }
360     if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
361       this->grow(NumBuckets);
362       LookupBucketFor(Key, TheBucket);
363     }
364
365     // If we are writing over a tombstone, remember this.
366     if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
367       --NumTombstones;
368
369     return TheBucket;
370   }
371
372   static unsigned getHashValue(const KeyT &Val) {
373     return KeyInfoT::getHashValue(Val);
374   }
375   template<typename LookupKeyT>
376   static unsigned getHashValue(const LookupKeyT &Val) {
377     return KeyInfoT::getHashValue(Val);
378   }
379   static const KeyT getEmptyKey() {
380     return KeyInfoT::getEmptyKey();
381   }
382   static const KeyT getTombstoneKey() {
383     return KeyInfoT::getTombstoneKey();
384   }
385
386   /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
387   /// FoundBucket.  If the bucket contains the key and a value, this returns
388   /// true, otherwise it returns a bucket with an empty marker or tombstone and
389   /// returns false.
390   template<typename LookupKeyT>
391   bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) const {
392     unsigned BucketNo = getHashValue(Val);
393     unsigned ProbeAmt = 1;
394     BucketT *BucketsPtr = Buckets;
395
396     if (NumBuckets == 0) {
397       FoundBucket = 0;
398       return false;
399     }
400
401     // FoundTombstone - Keep track of whether we find a tombstone while probing.
402     BucketT *FoundTombstone = 0;
403     const KeyT EmptyKey = getEmptyKey();
404     const KeyT TombstoneKey = getTombstoneKey();
405     assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
406            !KeyInfoT::isEqual(Val, TombstoneKey) &&
407            "Empty/Tombstone value shouldn't be inserted into map!");
408
409     while (1) {
410       BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
411       // Found Val's bucket?  If so, return it.
412       if (KeyInfoT::isEqual(Val, ThisBucket->first)) {
413         FoundBucket = ThisBucket;
414         return true;
415       }
416
417       // If we found an empty bucket, the key doesn't exist in the set.
418       // Insert it and return the default value.
419       if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
420         // If we've already seen a tombstone while probing, fill it in instead
421         // of the empty bucket we eventually probed to.
422         if (FoundTombstone) ThisBucket = FoundTombstone;
423         FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
424         return false;
425       }
426
427       // If this is a tombstone, remember it.  If Val ends up not in the map, we
428       // prefer to return it than something that would require more probing.
429       if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombstone)
430         FoundTombstone = ThisBucket;  // Remember the first tombstone found.
431
432       // Otherwise, it's a hash collision or a tombstone, continue quadratic
433       // probing.
434       BucketNo += ProbeAmt++;
435     }
436   }
437
438   void init(unsigned InitBuckets) {
439     NumEntries = 0;
440     NumTombstones = 0;
441     NumBuckets = InitBuckets;
442
443     if (InitBuckets == 0) {
444       Buckets = 0;
445       return;
446     }
447
448     assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 &&
449            "# initial buckets must be a power of two!");
450     Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets));
451     // Initialize all the keys to EmptyKey.
452     const KeyT EmptyKey = getEmptyKey();
453     for (unsigned i = 0; i != InitBuckets; ++i)
454       new (&Buckets[i].first) KeyT(EmptyKey);
455   }
456
457   void grow(unsigned AtLeast) {
458     unsigned OldNumBuckets = NumBuckets;
459     BucketT *OldBuckets = Buckets;
460
461     if (NumBuckets < 64)
462       NumBuckets = 64;
463
464     // Double the number of buckets.
465     while (NumBuckets < AtLeast)
466       NumBuckets <<= 1;
467     NumTombstones = 0;
468     Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
469
470     // Initialize all the keys to EmptyKey.
471     const KeyT EmptyKey = getEmptyKey();
472     for (unsigned i = 0, e = NumBuckets; i != e; ++i)
473       new (&Buckets[i].first) KeyT(EmptyKey);
474
475     // Insert all the old elements.
476     const KeyT TombstoneKey = getTombstoneKey();
477     for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
478       if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
479           !KeyInfoT::isEqual(B->first, TombstoneKey)) {
480         // Insert the key/value into the new table.
481         BucketT *DestBucket;
482         bool FoundVal = LookupBucketFor(B->first, DestBucket);
483         (void)FoundVal; // silence warning.
484         assert(!FoundVal && "Key already in new map?");
485         DestBucket->first = llvm_move(B->first);
486         new (&DestBucket->second) ValueT(llvm_move(B->second));
487
488         // Free the value.
489         B->second.~ValueT();
490       }
491       B->first.~KeyT();
492     }
493
494 #ifndef NDEBUG
495     if (OldNumBuckets)
496       memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
497 #endif
498     // Free the old table.
499     operator delete(OldBuckets);
500   }
501
502   void shrink_and_clear() {
503     unsigned OldNumBuckets = NumBuckets;
504     BucketT *OldBuckets = Buckets;
505
506     // Reduce the number of buckets.
507     NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1)
508                                  : 64;
509     NumTombstones = 0;
510     Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
511
512     // Initialize all the keys to EmptyKey.
513     const KeyT EmptyKey = getEmptyKey();
514     for (unsigned i = 0, e = NumBuckets; i != e; ++i)
515       new (&Buckets[i].first) KeyT(EmptyKey);
516
517     // Free the old buckets.
518     const KeyT TombstoneKey = getTombstoneKey();
519     for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
520       if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
521           !KeyInfoT::isEqual(B->first, TombstoneKey)) {
522         // Free the value.
523         B->second.~ValueT();
524       }
525       B->first.~KeyT();
526     }
527
528 #ifndef NDEBUG
529     memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
530 #endif
531     // Free the old table.
532     operator delete(OldBuckets);
533
534     NumEntries = 0;
535   }
536   
537 public:
538   /// Return the approximate size (in bytes) of the actual map.
539   /// This is just the raw memory used by DenseMap.
540   /// If entries are pointers to objects, the size of the referenced objects
541   /// are not included.
542   size_t getMemorySize() const {
543     return NumBuckets * sizeof(BucketT);
544   }
545 };
546
547 template<typename KeyT, typename ValueT,
548          typename KeyInfoT, bool IsConst>
549 class DenseMapIterator {
550   typedef std::pair<KeyT, ValueT> Bucket;
551   typedef DenseMapIterator<KeyT, ValueT,
552                            KeyInfoT, true> ConstIterator;
553   friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>;
554 public:
555   typedef ptrdiff_t difference_type;
556   typedef typename conditional<IsConst, const Bucket, Bucket>::type value_type;
557   typedef value_type *pointer;
558   typedef value_type &reference;
559   typedef std::forward_iterator_tag iterator_category;
560 private:
561   pointer Ptr, End;
562 public:
563   DenseMapIterator() : Ptr(0), End(0) {}
564
565   DenseMapIterator(pointer Pos, pointer E, bool NoAdvance = false)
566     : Ptr(Pos), End(E) {
567     if (!NoAdvance) AdvancePastEmptyBuckets();
568   }
569
570   // If IsConst is true this is a converting constructor from iterator to
571   // const_iterator and the default copy constructor is used.
572   // Otherwise this is a copy constructor for iterator.
573   DenseMapIterator(const DenseMapIterator<KeyT, ValueT,
574                                           KeyInfoT, false>& I)
575     : Ptr(I.Ptr), End(I.End) {}
576
577   reference operator*() const {
578     return *Ptr;
579   }
580   pointer operator->() const {
581     return Ptr;
582   }
583
584   bool operator==(const ConstIterator &RHS) const {
585     return Ptr == RHS.operator->();
586   }
587   bool operator!=(const ConstIterator &RHS) const {
588     return Ptr != RHS.operator->();
589   }
590
591   inline DenseMapIterator& operator++() {  // Preincrement
592     ++Ptr;
593     AdvancePastEmptyBuckets();
594     return *this;
595   }
596   DenseMapIterator operator++(int) {  // Postincrement
597     DenseMapIterator tmp = *this; ++*this; return tmp;
598   }
599
600 private:
601   void AdvancePastEmptyBuckets() {
602     const KeyT Empty = KeyInfoT::getEmptyKey();
603     const KeyT Tombstone = KeyInfoT::getTombstoneKey();
604
605     while (Ptr != End &&
606            (KeyInfoT::isEqual(Ptr->first, Empty) ||
607             KeyInfoT::isEqual(Ptr->first, Tombstone)))
608       ++Ptr;
609   }
610 };
611   
612 template<typename KeyT, typename ValueT, typename KeyInfoT>
613 static inline size_t
614 capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
615   return X.getMemorySize();
616 }
617
618 } // end namespace llvm
619
620 #endif