1616import com .google .common .annotations .VisibleForTesting ;
1717import com .google .common .base .Preconditions ;
1818import com .google .errorprone .annotations .CheckReturnValue ;
19- import java .util .Arrays ;
2019import java .util .BitSet ;
2120import javax .annotation .Nullable ;
2221
@@ -154,14 +153,33 @@ private static int nonNullCount(Object[] attrValues) {
154153 return numSet ;
155154 }
156155
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+
157175 /**
158176 * A frozen implementation of AttributeContainer which supports RuleClasses with up to 126
159177 * attributes.
160178 */
161179 @ VisibleForTesting
162180 static final class Small extends Frozen {
163181
164- private int maxAttrCount ;
182+ private final int maxAttrCount ;
165183
166184 // Conceptually an AttributeContainer is an unordered set of triples
167185 // (attribute, value, explicit).
@@ -219,25 +237,6 @@ private Small(Object[] attrValues, BitSet explicitAttrs) {
219237 }
220238 }
221239
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-
241240 /**
242241 * Returns true iff the value of the specified attribute is explicitly set in the BUILD file. In
243242 * addition, this method return false if the rule has no attribute with the given name.
@@ -247,7 +246,7 @@ boolean isAttributeValueExplicitlySpecified(int attrIndex) {
247246 if (attrIndex < 0 ) {
248247 return false ;
249248 }
250- int stateIndex = getStateIndex (attrIndex );
249+ int stateIndex = getStateIndex (state , 0 , attrIndex , 0x7f );
251250 return stateIndex >= 0 && (state [stateIndex ] & 0x80 ) != 0 ;
252251 }
253252
@@ -258,7 +257,7 @@ Object getAttributeValue(int attrIndex) {
258257 throw new IndexOutOfBoundsException (
259258 "Maximum valid attrIndex is " + (maxAttrCount - 1 ) + ". Given " + attrIndex );
260259 }
261- int stateIndex = getStateIndex (attrIndex );
260+ int stateIndex = getStateIndex (state , 0 , attrIndex , 0x7f );
262261 return stateIndex < 0 ? null : values [stateIndex ];
263262 }
264263 }
@@ -308,16 +307,16 @@ private static int prefixSize(int attrCount) {
308307 /** Set the specified bit in the byte array. Assumes bitIndex is a valid index. */
309308 private static void setBit (byte [] bits , int bitIndex ) {
310309 int idx = (bitIndex + 1 );
311- byte explicitByte = bits [idx >> 3 ];
310+ int explicitByte = bits [idx >> 3 ];
312311 byte mask = (byte ) (1 << (idx & 0x07 ));
313312 bits [idx >> 3 ] = (byte ) (explicitByte | mask );
314313 }
315314
316315 /** Get the specified bit in the byte array. Assumes bitIndex is a valid index. */
317316 private static boolean getBit (byte [] bits , int bitIndex ) {
318317 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 ));
321320 return (explicitByte & mask ) != 0 ;
322321 }
323322
@@ -374,7 +373,7 @@ Object getAttributeValue(int attrIndex) {
374373 "Maximum valid attrIndex is " + (maxAttrCount - 1 ) + ". Given " + attrIndex );
375374 }
376375 int p = prefixSize (maxAttrCount );
377- int stateIndex = Arrays . binarySearch (state , p , state . length , ( byte ) attrIndex );
376+ int stateIndex = getStateIndex (state , p , attrIndex , 0xff );
378377 return stateIndex < 0 ? null : values [stateIndex - p ];
379378 }
380379 }
0 commit comments