Add lengthof and endof templates that hide a lot of sizeof computations.
[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 (NumEntries != 0) {
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     memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT));
201     
202     NumBuckets = other.NumBuckets;
203   }
204   
205   BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
206                             BucketT *TheBucket) {
207     // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
208     // the buckets are empty (meaning that many are filled with tombstones),
209     // grow the table.
210     //
211     // The later case is tricky.  For example, if we had one empty bucket with
212     // tons of tombstones, failing lookups (e.g. for insertion) would have to
213     // probe almost the entire table until it found the empty bucket.  If the
214     // table completely filled with tombstones, no lookup would ever succeed,
215     // causing infinite loops in lookup.
216     if (NumEntries*4 >= NumBuckets*3 ||
217         NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {        
218       this->grow();
219       LookupBucketFor(Key, TheBucket);
220     }
221     ++NumEntries;
222     
223     // If we are writing over a tombstone, remember this.
224     if (TheBucket->first != getEmptyKey())
225       --NumTombstones;
226     
227     TheBucket->first = Key;
228     new (&TheBucket->second) ValueT(Value);
229     return TheBucket;
230   }
231
232   static unsigned getHashValue(const KeyT &Val) {
233     return KeyInfoT::getHashValue(Val);
234   }
235   static const KeyT getEmptyKey() {
236     return KeyInfoT::getEmptyKey();
237   }
238   static const KeyT getTombstoneKey() {
239     return KeyInfoT::getTombstoneKey();
240   }
241   
242   /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
243   /// FoundBucket.  If the bucket contains the key and a value, this returns
244   /// true, otherwise it returns a bucket with an empty marker or tombstone and
245   /// returns false.
246   bool LookupBucketFor(const KeyT &Val, BucketT *&FoundBucket) const {
247     unsigned BucketNo = getHashValue(Val);
248     unsigned ProbeAmt = 1;
249     BucketT *BucketsPtr = Buckets;
250     
251     // FoundTombstone - Keep track of whether we find a tombstone while probing.
252     BucketT *FoundTombstone = 0;
253     const KeyT EmptyKey = getEmptyKey();
254     const KeyT TombstoneKey = getTombstoneKey();
255     assert(Val != EmptyKey && Val != TombstoneKey &&
256            "Empty/Tombstone value shouldn't be inserted into map!");
257       
258     while (1) {
259       BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
260       // Found Val's bucket?  If so, return it.
261       if (ThisBucket->first == Val) {
262         FoundBucket = ThisBucket;
263         return true;
264       }
265       
266       // If we found an empty bucket, the key doesn't exist in the set.
267       // Insert it and return the default value.
268       if (ThisBucket->first == EmptyKey) {
269         // If we've already seen a tombstone while probing, fill it in instead
270         // of the empty bucket we eventually probed to.
271         if (FoundTombstone) ThisBucket = FoundTombstone;
272         FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
273         return false;
274       }
275       
276       // If this is a tombstone, remember it.  If Val ends up not in the map, we
277       // prefer to return it than something that would require more probing.
278       if (ThisBucket->first == TombstoneKey && !FoundTombstone)
279         FoundTombstone = ThisBucket;  // Remember the first tombstone found.
280       
281       // Otherwise, it's a hash collision or a tombstone, continue quadratic
282       // probing.
283       BucketNo += ProbeAmt++;
284     }
285   }
286
287   void init(unsigned InitBuckets) {
288     NumEntries = 0;
289     NumTombstones = 0;
290     NumBuckets = InitBuckets;
291     assert(InitBuckets && (InitBuckets & InitBuckets-1) == 0 &&
292            "# initial buckets must be a power of two!");
293     Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*InitBuckets]);
294     // Initialize all the keys to EmptyKey.
295     const KeyT EmptyKey = getEmptyKey();
296     for (unsigned i = 0; i != InitBuckets; ++i)
297       new (&Buckets[i].first) KeyT(EmptyKey);
298   }
299   
300   void grow() {
301     unsigned OldNumBuckets = NumBuckets;
302     BucketT *OldBuckets = Buckets;
303     
304     // Double the number of buckets.
305     NumBuckets <<= 1;
306     NumTombstones = 0;
307     Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*NumBuckets]);
308
309     // Initialize all the keys to EmptyKey.
310     const KeyT EmptyKey = getEmptyKey();
311     for (unsigned i = 0, e = NumBuckets; i != e; ++i)
312       new (&Buckets[i].first) KeyT(EmptyKey);
313
314     // Insert all the old elements.
315     const KeyT TombstoneKey = getTombstoneKey();
316     for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
317       if (B->first != EmptyKey && B->first != TombstoneKey) {
318         // Insert the key/value into the new table.
319         BucketT *DestBucket;
320         bool FoundVal = LookupBucketFor(B->first, DestBucket);
321         FoundVal = FoundVal; // silence warning.
322         assert(!FoundVal && "Key already in new map?");
323         DestBucket->first = B->first;
324         new (&DestBucket->second) ValueT(B->second);
325         
326         // Free the value.
327         B->second.~ValueT();
328       }
329       B->first.~KeyT();
330     }
331     
332     // Free the old table.
333     delete[] reinterpret_cast<char*>(OldBuckets);
334   }
335   
336   void shrink_and_clear() {
337     unsigned OldNumBuckets = NumBuckets;
338     BucketT *OldBuckets = Buckets;
339     
340     // Reduce the number of buckets.
341     NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1)
342                                  : 64;
343     NumTombstones = 0;
344     Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*NumBuckets]);
345
346     // Initialize all the keys to EmptyKey.
347     const KeyT EmptyKey = getEmptyKey();
348     for (unsigned i = 0, e = NumBuckets; i != e; ++i)
349       new (&Buckets[i].first) KeyT(EmptyKey);
350
351     // Free the old buckets.
352     const KeyT TombstoneKey = getTombstoneKey();
353     for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
354       if (B->first != EmptyKey && B->first != TombstoneKey) {
355         // Free the value.
356         B->second.~ValueT();
357       }
358       B->first.~KeyT();
359     }
360     
361     // Free the old table.
362     delete[] reinterpret_cast<char*>(OldBuckets);
363     
364     NumEntries = 0;
365   }
366 };
367
368 template<typename KeyT, typename ValueT, typename KeyInfoT>
369 class DenseMapIterator {
370   typedef std::pair<KeyT, ValueT> BucketT;
371 protected:
372   const BucketT *Ptr, *End;
373 public:
374   DenseMapIterator(const BucketT *Pos, const BucketT *E) : Ptr(Pos), End(E) {
375     AdvancePastEmptyBuckets();
376   }
377   
378   std::pair<KeyT, ValueT> &operator*() const {
379     return *const_cast<BucketT*>(Ptr);
380   }
381   std::pair<KeyT, ValueT> *operator->() const {
382     return const_cast<BucketT*>(Ptr);
383   }
384   
385   bool operator==(const DenseMapIterator &RHS) const {
386     return Ptr == RHS.Ptr;
387   }
388   bool operator!=(const DenseMapIterator &RHS) const {
389     return Ptr != RHS.Ptr;
390   }
391   
392   inline DenseMapIterator& operator++() {          // Preincrement
393     ++Ptr;
394     AdvancePastEmptyBuckets();
395     return *this;
396   }
397   DenseMapIterator operator++(int) {        // Postincrement
398     DenseMapIterator tmp = *this; ++*this; return tmp;
399   }
400   
401 private:
402   void AdvancePastEmptyBuckets() {
403     const KeyT Empty = KeyInfoT::getEmptyKey();
404     const KeyT Tombstone = KeyInfoT::getTombstoneKey();
405
406     while (Ptr != End && (Ptr->first == Empty || Ptr->first == Tombstone))
407       ++Ptr;
408   }
409 };
410
411 template<typename KeyT, typename ValueT, typename KeyInfoT>
412 class DenseMapConstIterator : public DenseMapIterator<KeyT, ValueT, KeyInfoT> {
413 public:
414   DenseMapConstIterator(const std::pair<KeyT, ValueT> *Pos,
415                         const std::pair<KeyT, ValueT> *E)
416     : DenseMapIterator<KeyT, ValueT, KeyInfoT>(Pos, E) {
417   }
418   const std::pair<KeyT, ValueT> &operator*() const {
419     return *this->Ptr;
420   }
421   const std::pair<KeyT, ValueT> *operator->() const {
422     return this->Ptr;
423   }
424 };
425
426 } // end namespace llvm
427
428 #endif