Add ObjectId getByte for random access
Processing git notes requires random access to part of the raw data of each ObjectId... which isn't easy because ObjectIds are stored with an internal representation of 5 ints. Expose random access to the individual data bytes through new methods, avoiding the need to convert first to a byte[20]. Change-Id: I99e64700b27fc0c95aa14ef8ad46a0e8832d4441 Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
c27e1daa55
commit
b22a4e8488
|
@ -47,7 +47,7 @@
|
|||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class T0001_ObjectId extends TestCase {
|
||||
public class ObjectIdTest extends TestCase {
|
||||
public void test001_toString() {
|
||||
final String x = "def4c620bc3713bb1bb26b808ec9312548e73946";
|
||||
final ObjectId oid = ObjectId.fromString(x);
|
||||
|
@ -108,4 +108,18 @@ public void test011_toString() {
|
|||
final ObjectId oid = ObjectId.fromString(x);
|
||||
assertEquals(x.toLowerCase(), oid.name());
|
||||
}
|
||||
|
||||
public void testGetByte() {
|
||||
byte[] raw = new byte[20];
|
||||
for (int i = 0; i < 20; i++)
|
||||
raw[i] = (byte) (0xa0 + i);
|
||||
ObjectId id = ObjectId.fromRaw(raw);
|
||||
|
||||
assertEquals(raw[0] & 0xff, id.getFirstByte());
|
||||
assertEquals(raw[0] & 0xff, id.getByte(0));
|
||||
assertEquals(raw[1] & 0xff, id.getByte(1));
|
||||
|
||||
for (int i = 2; i < 20; i++)
|
||||
assertEquals("index " + i, raw[i] & 0xff, id.getByte(i));
|
||||
}
|
||||
}
|
|
@ -97,14 +97,60 @@ public static boolean equals(final AnyObjectId firstObjectId,
|
|||
int w5;
|
||||
|
||||
/**
|
||||
* For ObjectIdMap
|
||||
* Get the first 8 bits of the ObjectId.
|
||||
*
|
||||
* @return a discriminator usable for a fan-out style map
|
||||
* This is a faster version of {@code getByte(0)}.
|
||||
*
|
||||
* @return a discriminator usable for a fan-out style map. Returned values
|
||||
* are unsigned and thus are in the range [0,255] rather than the
|
||||
* signed byte range of [-128, 127].
|
||||
*/
|
||||
public final int getFirstByte() {
|
||||
return w1 >>> 24;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any byte from the ObjectId.
|
||||
*
|
||||
* Callers hard-coding {@code getByte(0)} should instead use the much faster
|
||||
* special case variant {@link #getFirstByte()}.
|
||||
*
|
||||
* @param index
|
||||
* index of the byte to obtain from the raw form of the ObjectId.
|
||||
* Must be in range [0, {@link Constants#OBJECT_ID_LENGTH}).
|
||||
* @return the value of the requested byte at {@code index}. Returned values
|
||||
* are unsigned and thus are in the range [0,255] rather than the
|
||||
* signed byte range of [-128, 127].
|
||||
* @throws ArrayIndexOutOfBoundsException
|
||||
* {@code index} is less than 0, equal to
|
||||
* {@link Constants#OBJECT_ID_LENGTH}, or greater than
|
||||
* {@link Constants#OBJECT_ID_LENGTH}.
|
||||
*/
|
||||
public final int getByte(int index) {
|
||||
int w;
|
||||
switch (index >> 2) {
|
||||
case 0:
|
||||
w = w1;
|
||||
break;
|
||||
case 1:
|
||||
w = w2;
|
||||
break;
|
||||
case 2:
|
||||
w = w3;
|
||||
break;
|
||||
case 3:
|
||||
w = w4;
|
||||
break;
|
||||
case 4:
|
||||
w = w5;
|
||||
break;
|
||||
default:
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
}
|
||||
|
||||
return (w >>> (8 * (3 - (index & 3)))) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this ObjectId to another and obtain a sort ordering.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue