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