@@ -143,8 +143,7 @@ class DenseMapBase : public DebugEpochBase {
143
143
144
144
// / Return true if the specified key is in the map, false otherwise.
145
145
bool contains (const_arg_type_t <KeyT> Val) const {
146
- const BucketT *TheBucket;
147
- return LookupBucketFor (Val, TheBucket);
146
+ return doFind (Val) != nullptr ;
148
147
}
149
148
150
149
// / Return 1 if the specified key is in the map, 0 otherwise.
@@ -153,21 +152,17 @@ class DenseMapBase : public DebugEpochBase {
153
152
}
154
153
155
154
iterator find (const_arg_type_t <KeyT> Val) {
156
- BucketT *TheBucket;
157
- if (LookupBucketFor (Val, TheBucket))
158
- return makeIterator (TheBucket,
159
- shouldReverseIterate<KeyT>() ? getBuckets ()
160
- : getBucketsEnd (),
161
- *this , true );
155
+ if (BucketT *Bucket = doFind (Val))
156
+ return makeIterator (
157
+ Bucket, shouldReverseIterate<KeyT>() ? getBuckets () : getBucketsEnd (),
158
+ *this , true );
162
159
return end ();
163
160
}
164
161
const_iterator find (const_arg_type_t <KeyT> Val) const {
165
- const BucketT *TheBucket;
166
- if (LookupBucketFor (Val, TheBucket))
167
- return makeConstIterator (TheBucket,
168
- shouldReverseIterate<KeyT>() ? getBuckets ()
169
- : getBucketsEnd (),
170
- *this , true );
162
+ if (const BucketT *Bucket = doFind (Val))
163
+ return makeConstIterator (
164
+ Bucket, shouldReverseIterate<KeyT>() ? getBuckets () : getBucketsEnd (),
165
+ *this , true );
171
166
return end ();
172
167
}
173
168
@@ -178,31 +173,26 @@ class DenseMapBase : public DebugEpochBase {
178
173
// / type used.
179
174
template <class LookupKeyT >
180
175
iterator find_as (const LookupKeyT &Val) {
181
- BucketT *TheBucket;
182
- if (LookupBucketFor (Val, TheBucket))
183
- return makeIterator (TheBucket,
184
- shouldReverseIterate<KeyT>() ? getBuckets ()
185
- : getBucketsEnd (),
186
- *this , true );
176
+ if (BucketT *Bucket = doFind (Val))
177
+ return makeIterator (
178
+ Bucket, shouldReverseIterate<KeyT>() ? getBuckets () : getBucketsEnd (),
179
+ *this , true );
187
180
return end ();
188
181
}
189
182
template <class LookupKeyT >
190
183
const_iterator find_as (const LookupKeyT &Val) const {
191
- const BucketT *TheBucket;
192
- if (LookupBucketFor (Val, TheBucket))
193
- return makeConstIterator (TheBucket,
194
- shouldReverseIterate<KeyT>() ? getBuckets ()
195
- : getBucketsEnd (),
196
- *this , true );
184
+ if (const BucketT *Bucket = doFind (Val))
185
+ return makeConstIterator (
186
+ Bucket, shouldReverseIterate<KeyT>() ? getBuckets () : getBucketsEnd (),
187
+ *this , true );
197
188
return end ();
198
189
}
199
190
200
191
// / lookup - Return the entry for the specified key, or a default
201
192
// / constructed value if no such entry exists.
202
193
ValueT lookup (const_arg_type_t <KeyT> Val) const {
203
- const BucketT *TheBucket;
204
- if (LookupBucketFor (Val, TheBucket))
205
- return TheBucket->getSecond ();
194
+ if (const BucketT *Bucket = doFind (Val))
195
+ return Bucket->getSecond ();
206
196
return ValueT ();
207
197
}
208
198
@@ -343,8 +333,8 @@ class DenseMapBase : public DebugEpochBase {
343
333
}
344
334
345
335
bool erase (const KeyT &Val) {
346
- BucketT *TheBucket;
347
- if (!LookupBucketFor (Val, TheBucket) )
336
+ BucketT *TheBucket = doFind (Val) ;
337
+ if (!TheBucket)
348
338
return false ; // not in map.
349
339
350
340
TheBucket->getSecond ().~ValueT ();
@@ -643,6 +633,34 @@ class DenseMapBase : public DebugEpochBase {
643
633
return TheBucket;
644
634
}
645
635
636
+ template <typename LookupKeyT> BucketT *doFind (const LookupKeyT &Val) {
637
+ BucketT *BucketsPtr = getBuckets ();
638
+ const unsigned NumBuckets = getNumBuckets ();
639
+ if (NumBuckets == 0 )
640
+ return nullptr ;
641
+
642
+ const KeyT EmptyKey = getEmptyKey ();
643
+ unsigned BucketNo = getHashValue (Val) & (NumBuckets - 1 );
644
+ unsigned ProbeAmt = 1 ;
645
+ while (true ) {
646
+ BucketT *Bucket = BucketsPtr + BucketNo;
647
+ if (LLVM_LIKELY (KeyInfoT::isEqual (Val, Bucket->getFirst ())))
648
+ return Bucket;
649
+ if (LLVM_LIKELY (KeyInfoT::isEqual (Bucket->getFirst (), EmptyKey)))
650
+ return nullptr ;
651
+
652
+ // Otherwise, it's a hash collision or a tombstone, continue quadratic
653
+ // probing.
654
+ BucketNo += ProbeAmt++;
655
+ BucketNo &= NumBuckets - 1 ;
656
+ }
657
+ }
658
+
659
+ template <typename LookupKeyT>
660
+ const BucketT *doFind (const LookupKeyT &Val) const {
661
+ return const_cast <DenseMapBase *>(this )->doFind (Val); // NOLINT
662
+ }
663
+
646
664
// / LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
647
665
// / FoundBucket. If the bucket contains the key and a value, this returns
648
666
// / true, otherwise it returns a bucket with an empty marker or tombstone and
0 commit comments