@@ -69,24 +69,14 @@ class DenseMapBase {
69
69
setNumTombstones (0 );
70
70
}
71
71
72
+ // / Return true if the specified key is in the map, false otherwise.
73
+ bool contains (const KeyT &Key) const { return doFind (Key) != nullptr ; }
74
+
72
75
// / Return 1 if the specified key is in the map, 0 otherwise.
73
- size_type count (const KeyT &Key) const {
74
- const BucketT *TheBucket;
75
- return LookupBucketFor (Key, TheBucket) ? 1 : 0 ;
76
- }
76
+ size_type count (const KeyT &Key) const { return contains (Key) ? 1 : 0 ; }
77
77
78
- value_type *find (const KeyT &Key) {
79
- BucketT *TheBucket;
80
- if (LookupBucketFor (Key, TheBucket))
81
- return TheBucket;
82
- return nullptr ;
83
- }
84
- const value_type *find (const KeyT &Key) const {
85
- const BucketT *TheBucket;
86
- if (LookupBucketFor (Key, TheBucket))
87
- return TheBucket;
88
- return nullptr ;
89
- }
78
+ value_type *find (const KeyT &Key) { return doFind (Key); }
79
+ const value_type *find (const KeyT &Key) const { return doFind (Key); }
90
80
91
81
// / Alternate version of find() which allows a different, and possibly
92
82
// / less expensive, key type.
@@ -95,25 +85,18 @@ class DenseMapBase {
95
85
// / type used.
96
86
template <class LookupKeyT >
97
87
value_type *find_as (const LookupKeyT &Key) {
98
- BucketT *TheBucket;
99
- if (LookupBucketFor (Key, TheBucket))
100
- return TheBucket;
101
- return nullptr ;
88
+ return doFind (Key);
102
89
}
103
90
template <class LookupKeyT >
104
91
const value_type *find_as (const LookupKeyT &Key) const {
105
- const BucketT *TheBucket;
106
- if (LookupBucketFor (Key, TheBucket))
107
- return TheBucket;
108
- return nullptr ;
92
+ return doFind (Key);
109
93
}
110
94
111
95
// / lookup - Return the entry for the specified key, or a default
112
96
// / constructed value if no such entry exists.
113
97
ValueT lookup (const KeyT &Key) const {
114
- const BucketT *TheBucket;
115
- if (LookupBucketFor (Key, TheBucket))
116
- return TheBucket->getSecond ();
98
+ if (const BucketT *Bucket = doFind (Key))
99
+ return Bucket->getSecond ();
117
100
return ValueT ();
118
101
}
119
102
@@ -184,8 +167,8 @@ class DenseMapBase {
184
167
}
185
168
186
169
bool erase (const KeyT &Val) {
187
- BucketT *TheBucket;
188
- if (!LookupBucketFor (Val, TheBucket) )
170
+ BucketT *TheBucket = doFind (Val) ;
171
+ if (!TheBucket)
189
172
return false ; // not in map.
190
173
191
174
TheBucket->getSecond ().~ValueT ();
@@ -449,6 +432,35 @@ class DenseMapBase {
449
432
return TheBucket;
450
433
}
451
434
435
+ template <typename LookupKeyT>
436
+ BucketT *doFind (const LookupKeyT &Val) {
437
+ BucketT *BucketsPtr = getBuckets ();
438
+ const unsigned NumBuckets = getNumBuckets ();
439
+ if (NumBuckets == 0 )
440
+ return nullptr ;
441
+
442
+ const KeyT EmptyKey = getEmptyKey ();
443
+ unsigned BucketNo = getHashValue (Val) & (NumBuckets - 1 );
444
+ unsigned ProbeAmt = 1 ;
445
+ while (true ) {
446
+ BucketT *Bucket = BucketsPtr + BucketNo;
447
+ if (LIKELY (KeyInfoT::isEqual (Val, Bucket->getFirst ())))
448
+ return Bucket;
449
+ if (LIKELY (KeyInfoT::isEqual (Bucket->getFirst (), EmptyKey)))
450
+ return nullptr ;
451
+
452
+ // Otherwise, it's a hash collision or a tombstone, continue quadratic
453
+ // probing.
454
+ BucketNo += ProbeAmt++;
455
+ BucketNo &= NumBuckets - 1 ;
456
+ }
457
+ }
458
+
459
+ template <typename LookupKeyT>
460
+ const BucketT *doFind (const LookupKeyT &Val) const {
461
+ return const_cast <DenseMapBase *>(this )->doFind (Val);
462
+ }
463
+
452
464
// / LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
453
465
// / FoundBucket. If the bucket contains the key and a value, this returns
454
466
// / true, otherwise it returns a bucket with an empty marker or tombstone and
0 commit comments