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