fe912404cd9a43cdc4bda366589ea02b426ec6b4
[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 was developed by Chris Lattner and is distributed under
6 // the University of Illinois Open Source 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/DataTypes.h"
18 #include "llvm/Support/MathExtras.h"
19 #include <cassert>
20 #include <utility>
21
22 namespace llvm {
23   
24 template<typename T>
25 struct DenseMapKeyInfo {
26   //static inline T getEmptyKey();
27   //static inline T getTombstoneKey();
28   //static unsigned getHashValue(const T &Val);
29   //static bool isPod()
30 };
31
32 // Provide DenseMapKeyInfo for all pointers.
33 template<typename T>
34 struct DenseMapKeyInfo<T*> {
35   static inline T* getEmptyKey() { return reinterpret_cast<T*>(-1); }
36   static inline T* getTombstoneKey() { return reinterpret_cast<T*>(-2); }
37   static unsigned getHashValue(const T *PtrVal) {
38     return (unsigned(uintptr_t(PtrVal)) >> 4) ^ 
39            (unsigned(uintptr_t(PtrVal)) >> 9);
40   }
41   static bool isPod() { return true; }
42 };
43
44 template<typename KeyT, typename ValueT, 
45          typename KeyInfoT = DenseMapKeyInfo<KeyT> >
46 class DenseMapIterator;
47 template<typename KeyT, typename ValueT,
48          typename KeyInfoT = DenseMapKeyInfo<KeyT> >
49 class DenseMapConstIterator;
50
51 template<typename KeyT, typename ValueT,
52          typename KeyInfoT = DenseMapKeyInfo<KeyT> >
53 class DenseMap {
54   typedef std::pair<KeyT, ValueT> BucketT;
55   unsigned NumBuckets;
56   BucketT *Buckets;
57   
58   unsigned NumEntries;
59   unsigned NumTombstones;
60 public:
61   DenseMap(const DenseMap& other) {
62     NumBuckets = 0;
63     CopyFrom(other);
64   }
65   
66   explicit DenseMap(unsigned NumInitBuckets = 64) {
67     init(NumInitBuckets);
68   }
69   
70   ~DenseMap() {
71     const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
72     for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
73       if (P->first != EmptyKey && P->first != TombstoneKey)
74         P->second.~ValueT();
75       P->first.~KeyT();
76     }
77     delete[] reinterpret_cast<char*>(Buckets);
78   }
79   
80   typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
81   typedef DenseMapConstIterator<KeyT, ValueT, KeyInfoT> const_iterator;
82   inline iterator begin() {
83      return iterator(Buckets, Buckets+NumBuckets);
84   }
85   inline iterator end() {
86     return iterator(Buckets+NumBuckets, Buckets+NumBuckets);
87   }
88   inline const_iterator begin() const {
89     return const_iterator(Buckets, Buckets+NumBuckets);
90   }
91   inline const_iterator end() const {
92     return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets);
93   }
94   
95   bool empty() const { return NumEntries == 0; }
96   unsigned size() const { return NumEntries; }
97   
98   void clear() {
99     // If the capacity of the array is huge, and the # elements used is small,
100     // shrink the array.
101     if (NumEntries * 4 < NumBuckets && NumBuckets > 64) {
102       shrink_and_clear();
103       return;
104     }
105     
106     const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
107     for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
108       if (P->first != EmptyKey) {
109         if (P->first != TombstoneKey) {
110           P->second.~ValueT();
111           --NumEntries;
112         }
113         P->first = EmptyKey;
114       }
115     }
116     assert(NumEntries == 0 && "Node count imbalance!");
117     NumTombstones = 0;
118   }
119
120   /// count - Return true if the specified key is in the map.
121   bool count(const KeyT &Val) const {
122     BucketT *TheBucket;
123     return LookupBucketFor(Val, TheBucket);
124   }
125   
126   iterator find(const KeyT &Val) {
127     BucketT *TheBucket;
128     if (LookupBucketFor(Val, TheBucket))
129       return iterator(TheBucket, Buckets+NumBuckets);
130     return end();
131   }
132   const_iterator find(const KeyT &Val) const {
133     BucketT *TheBucket;
134     if (LookupBucketFor(Val, TheBucket))
135       return const_iterator(TheBucket, Buckets+NumBuckets);
136     return end();
137   }
138   
139   bool insert(const std::pair<KeyT, ValueT> &KV) {
140     BucketT *TheBucket;
141     if (LookupBucketFor(KV.first, TheBucket))
142       return false; // Already in map.
143     
144     // Otherwise, insert the new element.
145     InsertIntoBucket(KV.first, KV.second, TheBucket);
146     return true;
147   }
148   
149   bool erase(const KeyT &Val) {
150     BucketT *TheBucket;
151     if (!LookupBucketFor(Val, TheBucket))
152       return false; // not in map.
153
154     TheBucket->second.~ValueT();
155     TheBucket->first = getTombstoneKey();
156     --NumEntries;
157     ++NumTombstones;
158     return true;
159   }
160   bool erase(iterator I) {
161     BucketT *TheBucket = &*I;
162     TheBucket->second.~ValueT();
163     TheBucket->first = getTombstoneKey();
164     --NumEntries;
165     ++NumTombstones;
166     return true;
167   }
168   
169   ValueT &operator[](const KeyT &Key) {
170     BucketT *TheBucket;
171     if (LookupBucketFor(Key, TheBucket))
172       return TheBucket->second;
173
174     return InsertIntoBucket(Key, ValueT(), TheBucket)->second;
175   }
176   
177   DenseMap& operator=(const DenseMap& other) {
178     CopyFrom(other);
179     return *this;
180   }
181   
182 private:
183   void CopyFrom(const DenseMap& other) {
184     if (NumBuckets != 0 && !KeyInfoT::isPod()) {
185       const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
186       for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
187         if (P->first != EmptyKey && P->first != TombstoneKey)
188           P->second.~ValueT();
189         P->first.~KeyT();
190       }
191     }
192     
193     NumEntries = other.NumEntries;
194     NumTombstones = other.NumTombstones;
195     
196     if (NumBuckets)
197       delete[] reinterpret_cast<char*>(Buckets);
198     Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT) *
199                                                   other.NumBuckets]);
200     
201     if (KeyInfoT::isPod())
202       memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT));
203     else
204       for (size_t i = 0; i < other.NumBuckets; ++i) {
205         new (Buckets[i].first) KeyT(other.Buckets[i].first);
206         new (Buckets[i].second) ValueT(other.Buckets[i].second);
207       }
208     NumBuckets = other.NumBuckets;
209   }
210   
211   BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
212                             BucketT *TheBucket) {
213     // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
214     // the buckets are empty (meaning that many are filled with tombstones),
215     // grow the table.
216     //
217     // The later case is tricky.  For example, if we had one empty bucket with
218     // tons of tombstones, failing lookups (e.g. for insertion) would have to
219     // probe almost the entire table until it found the empty bucket.  If the
220     // table completely filled with tombstones, no lookup would ever succeed,
221     // causing infinite loops in lookup.
222     if (NumEntries*4 >= NumBuckets*3 ||
223         NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {        
224       this->grow();
225       LookupBucketFor(Key, TheBucket);
226     }
227     ++NumEntries;
228     
229     // If we are writing over a tombstone, remember this.
230     if (TheBucket->first != getEmptyKey())
231       --NumTombstones;
232     
233     TheBucket->first = Key;
234     new (&TheBucket->second) ValueT(Value);
235     return TheBucket;
236   }
237
238   static unsigned getHashValue(const KeyT &Val) {
239     return KeyInfoT::getHashValue(Val);
240   }
241   static const KeyT getEmptyKey() {
242     return KeyInfoT::getEmptyKey();
243   }
244   static const KeyT getTombstoneKey() {
245     return KeyInfoT::getTombstoneKey();
246   }
247   
248   /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
249   /// FoundBucket.  If the bucket contains the key and a value, this returns
250   /// true, otherwise it returns a bucket with an empty marker or tombstone and
251   /// returns false.
252   bool LookupBucketFor(const KeyT &Val, BucketT *&FoundBucket) const {
253     unsigned BucketNo = getHashValue(Val);
254     unsigned ProbeAmt = 1;
255     BucketT *BucketsPtr = Buckets;
256     
257     // FoundTombstone - Keep track of whether we find a tombstone while probing.
258     BucketT *FoundTombstone = 0;
259     const KeyT EmptyKey = getEmptyKey();
260     const KeyT TombstoneKey = getTombstoneKey();
261     assert(Val != EmptyKey && Val != TombstoneKey &&
262            "Empty/Tombstone value shouldn't be inserted into map!");
263       
264     while (1) {
265       BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
266       // Found Val's bucket?  If so, return it.
267       if (ThisBucket->first == Val) {
268         FoundBucket = ThisBucket;
269         return true;
270       }
271       
272       // If we found an empty bucket, the key doesn't exist in the set.
273       // Insert it and return the default value.
274       if (ThisBucket->first == EmptyKey) {
275         // If we've already seen a tombstone while probing, fill it in instead
276         // of the empty bucket we eventually probed to.
277         if (FoundTombstone) ThisBucket = FoundTombstone;
278         FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
279         return false;
280       }
281       
282       // If this is a tombstone, remember it.  If Val ends up not in the map, we
283       // prefer to return it than something that would require more probing.
284       if (ThisBucket->first == TombstoneKey && !FoundTombstone)
285         FoundTombstone = ThisBucket;  // Remember the first tombstone found.
286       
287       // Otherwise, it's a hash collision or a tombstone, continue quadratic
288       // probing.
289       BucketNo += ProbeAmt++;
290     }
291   }
292
293   void init(unsigned InitBuckets) {
294     NumEntries = 0;
295     NumTombstones = 0;
296     NumBuckets = InitBuckets;
297     assert(InitBuckets && (InitBuckets & InitBuckets-1) == 0 &&
298            "# initial buckets must be a power of two!");
299     Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*InitBuckets]);
300     // Initialize all the keys to EmptyKey.
301     const KeyT EmptyKey = getEmptyKey();
302     for (unsigned i = 0; i != InitBuckets; ++i)
303       new (&Buckets[i].first) KeyT(EmptyKey);
304   }
305   
306   void grow() {
307     unsigned OldNumBuckets = NumBuckets;
308     BucketT *OldBuckets = Buckets;
309     
310     // Double the number of buckets.
311     NumBuckets <<= 1;
312     NumTombstones = 0;
313     Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*NumBuckets]);
314
315     // Initialize all the keys to EmptyKey.
316     const KeyT EmptyKey = getEmptyKey();
317     for (unsigned i = 0, e = NumBuckets; i != e; ++i)
318       new (&Buckets[i].first) KeyT(EmptyKey);
319
320     // Insert all the old elements.
321     const KeyT TombstoneKey = getTombstoneKey();
322     for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
323       if (B->first != EmptyKey && B->first != TombstoneKey) {
324         // Insert the key/value into the new table.
325         BucketT *DestBucket;
326         bool FoundVal = LookupBucketFor(B->first, DestBucket);
327         FoundVal = FoundVal; // silence warning.
328         assert(!FoundVal && "Key already in new map?");
329         DestBucket->first = B->first;
330         new (&DestBucket->second) ValueT(B->second);
331         
332         // Free the value.
333         B->second.~ValueT();
334       }
335       B->first.~KeyT();
336     }
337     
338     // Free the old table.
339     delete[] reinterpret_cast<char*>(OldBuckets);
340   }
341   
342   void shrink_and_clear() {
343     unsigned OldNumBuckets = NumBuckets;
344     BucketT *OldBuckets = Buckets;
345     
346     // Reduce the number of buckets.
347     NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1)
348                                  : 64;
349     NumTombstones = 0;
350     Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*NumBuckets]);
351
352     // Initialize all the keys to EmptyKey.
353     const KeyT EmptyKey = getEmptyKey();
354     for (unsigned i = 0, e = NumBuckets; i != e; ++i)
355       new (&Buckets[i].first) KeyT(EmptyKey);
356
357     // Free the old buckets.
358     const KeyT TombstoneKey = getTombstoneKey();
359     for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
360       if (B->first != EmptyKey && B->first != TombstoneKey) {
361         // Free the value.
362         B->second.~ValueT();
363       }
364       B->first.~KeyT();
365     }
366     
367     // Free the old table.
368     delete[] reinterpret_cast<char*>(OldBuckets);
369     
370     NumEntries = 0;
371   }
372 };
373
374 template<typename KeyT, typename ValueT, typename KeyInfoT>
375 class DenseMapIterator {
376   typedef std::pair<KeyT, ValueT> BucketT;
377 protected:
378   const BucketT *Ptr, *End;
379 public:
380   DenseMapIterator(const BucketT *Pos, const BucketT *E) : Ptr(Pos), End(E) {
381     AdvancePastEmptyBuckets();
382   }
383   
384   std::pair<KeyT, ValueT> &operator*() const {
385     return *const_cast<BucketT*>(Ptr);
386   }
387   std::pair<KeyT, ValueT> *operator->() const {
388     return const_cast<BucketT*>(Ptr);
389   }
390   
391   bool operator==(const DenseMapIterator &RHS) const {
392     return Ptr == RHS.Ptr;
393   }
394   bool operator!=(const DenseMapIterator &RHS) const {
395     return Ptr != RHS.Ptr;
396   }
397   
398   inline DenseMapIterator& operator++() {          // Preincrement
399     ++Ptr;
400     AdvancePastEmptyBuckets();
401     return *this;
402   }
403   DenseMapIterator operator++(int) {        // Postincrement
404     DenseMapIterator tmp = *this; ++*this; return tmp;
405   }
406   
407 private:
408   void AdvancePastEmptyBuckets() {
409     const KeyT Empty = KeyInfoT::getEmptyKey();
410     const KeyT Tombstone = KeyInfoT::getTombstoneKey();
411
412     while (Ptr != End && (Ptr->first == Empty || Ptr->first == Tombstone))
413       ++Ptr;
414   }
415 };
416
417 template<typename KeyT, typename ValueT, typename KeyInfoT>
418 class DenseMapConstIterator : public DenseMapIterator<KeyT, ValueT, KeyInfoT> {
419 public:
420   DenseMapConstIterator(const std::pair<KeyT, ValueT> *Pos,
421                         const std::pair<KeyT, ValueT> *E)
422     : DenseMapIterator<KeyT, ValueT, KeyInfoT>(Pos, E) {
423   }
424   const std::pair<KeyT, ValueT> &operator*() const {
425     return *this->Ptr;
426   }
427   const std::pair<KeyT, ValueT> *operator->() const {
428     return this->Ptr;
429   }
430 };
431
432 } // end namespace llvm
433
434 #endif