16
16
import com .google .common .annotations .VisibleForTesting ;
17
17
import com .google .common .base .Preconditions ;
18
18
import com .google .errorprone .annotations .CheckReturnValue ;
19
- import java .util .Arrays ;
20
19
import java .util .BitSet ;
21
20
import javax .annotation .Nullable ;
22
21
@@ -154,14 +153,33 @@ private static int nonNullCount(Object[] attrValues) {
154
153
return numSet ;
155
154
}
156
155
156
+ /** Returns index into state array for attrIndex, or -1 if not found */
157
+ private static int getStateIndex (byte [] state , int start , int attrIndex , int mask ) {
158
+ // Binary search, treating values as unsigned bytes.
159
+ int lo = start ;
160
+ int hi = state .length - 1 ;
161
+ while (hi >= lo ) {
162
+ int mid = (lo + hi ) / 2 ;
163
+ int midAttrIndex = state [mid ] & mask ;
164
+ if (midAttrIndex == attrIndex ) {
165
+ return mid ;
166
+ } else if (midAttrIndex < attrIndex ) {
167
+ lo = mid + 1 ;
168
+ } else {
169
+ hi = mid - 1 ;
170
+ }
171
+ }
172
+ return -1 ;
173
+ }
174
+
157
175
/**
158
176
* A frozen implementation of AttributeContainer which supports RuleClasses with up to 126
159
177
* attributes.
160
178
*/
161
179
@ VisibleForTesting
162
180
static final class Small extends Frozen {
163
181
164
- private int maxAttrCount ;
182
+ private final int maxAttrCount ;
165
183
166
184
// Conceptually an AttributeContainer is an unordered set of triples
167
185
// (attribute, value, explicit).
@@ -219,25 +237,6 @@ private Small(Object[] attrValues, BitSet explicitAttrs) {
219
237
}
220
238
}
221
239
222
- /** Returns index into state array for attrIndex, or -1 if not found */
223
- private int getStateIndex (int attrIndex ) {
224
- // Binary search on the bottom 7 bits.
225
- int lo = 0 ;
226
- int hi = state .length - 1 ;
227
- while (hi >= lo ) {
228
- int mid = (lo + hi ) / 2 ;
229
- int midAttrIndex = state [mid ] & 0x7f ;
230
- if (midAttrIndex == attrIndex ) {
231
- return mid ;
232
- } else if (midAttrIndex < attrIndex ) {
233
- lo = mid + 1 ;
234
- } else {
235
- hi = mid - 1 ;
236
- }
237
- }
238
- return -1 ;
239
- }
240
-
241
240
/**
242
241
* Returns true iff the value of the specified attribute is explicitly set in the BUILD file. In
243
242
* addition, this method return false if the rule has no attribute with the given name.
@@ -247,7 +246,7 @@ boolean isAttributeValueExplicitlySpecified(int attrIndex) {
247
246
if (attrIndex < 0 ) {
248
247
return false ;
249
248
}
250
- int stateIndex = getStateIndex (attrIndex );
249
+ int stateIndex = getStateIndex (state , 0 , attrIndex , 0x7f );
251
250
return stateIndex >= 0 && (state [stateIndex ] & 0x80 ) != 0 ;
252
251
}
253
252
@@ -258,7 +257,7 @@ Object getAttributeValue(int attrIndex) {
258
257
throw new IndexOutOfBoundsException (
259
258
"Maximum valid attrIndex is " + (maxAttrCount - 1 ) + ". Given " + attrIndex );
260
259
}
261
- int stateIndex = getStateIndex (attrIndex );
260
+ int stateIndex = getStateIndex (state , 0 , attrIndex , 0x7f );
262
261
return stateIndex < 0 ? null : values [stateIndex ];
263
262
}
264
263
}
@@ -308,16 +307,16 @@ private static int prefixSize(int attrCount) {
308
307
/** Set the specified bit in the byte array. Assumes bitIndex is a valid index. */
309
308
private static void setBit (byte [] bits , int bitIndex ) {
310
309
int idx = (bitIndex + 1 );
311
- byte explicitByte = bits [idx >> 3 ];
310
+ int explicitByte = bits [idx >> 3 ];
312
311
byte mask = (byte ) (1 << (idx & 0x07 ));
313
312
bits [idx >> 3 ] = (byte ) (explicitByte | mask );
314
313
}
315
314
316
315
/** Get the specified bit in the byte array. Assumes bitIndex is a valid index. */
317
316
private static boolean getBit (byte [] bits , int bitIndex ) {
318
317
int idx = (bitIndex + 1 );
319
- byte explicitByte = bits [idx >> 3 ];
320
- byte mask = (byte ) (1 << (idx & 0x07 ));
318
+ int explicitByte = bits [idx >> 3 ];
319
+ int mask = (byte ) (1 << (idx & 0x07 ));
321
320
return (explicitByte & mask ) != 0 ;
322
321
}
323
322
@@ -374,7 +373,7 @@ Object getAttributeValue(int attrIndex) {
374
373
"Maximum valid attrIndex is " + (maxAttrCount - 1 ) + ". Given " + attrIndex );
375
374
}
376
375
int p = prefixSize (maxAttrCount );
377
- int stateIndex = Arrays . binarySearch (state , p , state . length , ( byte ) attrIndex );
376
+ int stateIndex = getStateIndex (state , p , attrIndex , 0xff );
378
377
return stateIndex < 0 ? null : values [stateIndex - p ];
379
378
}
380
379
}
0 commit comments