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