@@ -76,23 +76,28 @@ class WeakLookupTable<Element: Identifiable & AnyObject> {
76
76
/// '_minimalBucketCount(for: capacity)'
77
77
private static func _bucketCount( for capacity: Int ,
78
78
from current: Int = 2 ) -> Int {
79
- // Make sure it's representable.
80
- precondition ( capacity <= ( Int . max >> 1 ) + 1 )
81
79
// Bucket count must always be power of 2.
82
80
precondition ( ( current & ( current - 1 ) ) == 0 )
83
81
// Minimum is 2 to guarantee at least 1 hole.
84
82
precondition ( current >= 2 )
85
83
86
84
let minimalBucketCount = _minimalBucketCount ( for: capacity)
85
+
86
+ // Make sure it's representable. If 'minimalBucketCount' here is over
87
+ // 0x4000_..., the bucket count must be 0x8000_... thus overflows.
88
+ precondition ( minimalBucketCount <= ( Int . max >> 1 ) + 1 )
89
+
87
90
var bucketCount = current
88
91
while bucketCount < minimalBucketCount {
92
+ // '&*=' for performance. Guaranteed by above 'precondition()'.
89
93
bucketCount &*= 2
90
94
}
91
95
return bucketCount
92
96
}
93
97
94
98
private var _bucketMask : Int {
95
99
@inline ( __always) get {
100
+ // '&-' for performance. We know 'bucketCount >= 2'.
96
101
return bucketCount &- 1
97
102
}
98
103
}
@@ -116,6 +121,7 @@ class WeakLookupTable<Element: Identifiable & AnyObject> {
116
121
if obj. id == id {
117
122
return ( bucket, true )
118
123
}
124
+ // '&+' for performance. 'bucketCount' is 0x4000_... or below.
119
125
bucket = ( bucket &+ 1 ) & _bucketMask
120
126
}
121
127
}
@@ -157,6 +163,7 @@ class WeakLookupTable<Element: Identifiable & AnyObject> {
157
163
private func _countOccupiedBuckets( ) -> Int {
158
164
var count = 0
159
165
for i in 0 ..< bucketCount where buckets [ i] . value != nil {
166
+ // '&+=' for performance. 'bucketCount' is 0x4000_... or below.
160
167
count &+= 1
161
168
}
162
169
return count
@@ -165,13 +172,18 @@ class WeakLookupTable<Element: Identifiable & AnyObject> {
165
172
/// Reserves enough space to store a single new object. Returns true if
166
173
/// resizing happened.
167
174
private func _ensurePlusOneCapacity( ) -> Bool {
175
+ // '&+' for performance. 'estimatedCount' is always less than 'bucketCount'
176
+ // which is 0x4000_... or below.
168
177
if bucketCount >= WeakLookupTable < Element >
169
178
. _minimalBucketCount ( for: estimatedCount &+ 1 ) {
170
179
return false
171
180
}
172
181
173
182
// Slow path.
174
183
estimatedCount = _countOccupiedBuckets ( )
184
+ // '&+' for performance. We know 'estimatedCount' derived by
185
+ // '_countOccupiedBuckets()' is equal to or less than previous
186
+ // 'estimatedCount'.
175
187
return reserveCapacity ( estimatedCount &+ 1 )
176
188
}
177
189
@@ -187,6 +199,7 @@ class WeakLookupTable<Element: Identifiable & AnyObject> {
187
199
pos = _findHole ( obj. id) . pos
188
200
}
189
201
buckets [ pos] . value = obj
202
+ // '&+=' for performance. '_ensurePlusOneCapacity()' ensures it's safe.
190
203
estimatedCount &+= 1
191
204
return true
192
205
}
@@ -205,6 +218,7 @@ class WeakLookupTable<Element: Identifiable & AnyObject> {
205
218
if let obj = buckets [ bucket] . value, obj. id == id {
206
219
return obj
207
220
}
221
+ // '&+' for performance. 'bucketCount' is 0x4000_... or below.
208
222
bucket = ( bucket &+ 1 ) & _bucketMask
209
223
} while bucket != idealBucket
210
224
0 commit comments