Skip to content

Instantly share code, notes, and snippets.

@heuermh
Created September 12, 2011 14:27
Show Gist options
  • Save heuermh/1211388 to your computer and use it in GitHub Desktop.
Save heuermh/1211388 to your computer and use it in GitHub Desktop.
Adapt lower two bytes of int[] as byte[] for bitwise comparisons
/**
* Foo key analyzer, treats int[] as a byte[] for bitwise comparisons.
*/
private static class FooKeyAnalyzer implements KeyAnalyzer<AbstractFooKey> {
private static final int MSB = 1 << Byte.SIZE - 1;
private static int mask(final int bit) {
return MSB >>> bit;
}
private static byte valueAt(final int[] values, final int index) {
if (index >= 0 && index < (values.length * 2)) {
if ((index % 2) == 0) {
return (byte) ((values[index / 2] >> 8) & 0xFF);
}
else {
return (byte) (values[index / 2] & 0xFF);
}
}
return 0;
}
@Override
public int compare(final AbstractFooKey key0, final AbstractFooKey key1) {
if (key0 == null) {
return (key1 == null) ? 0 : -1;
} else if (key1 == null) {
return (key0 == null) ? 0 : 1;
}
if (key0.getValues().length != key1.getValues().length) {
return key0.getValues().length - key1.getValues().length;
}
for (int i = 0; i < key0.getValues().length; i++) {
int diff = key0.getValues()[i] - key1.getValues()[i];
if (diff != 0) {
return diff;
}
}
return 0;
}
@Override
public int bitIndex(final AbstractFooKey key0, final AbstractFooKey key1) {
int length = Math.max(key0.getValues().length * 2, key1.getValues().length * 2);
boolean allNull = true;
for (int i = 0; i < length; i++) {
byte b1 = valueAt(key0.getAlleles(), i);
byte b2 = valueAt(key1.getAlleles(), i);
if (b1 != b2) {
int xor = b1 ^ b2;
for (int j = 0; j < Byte.SIZE; j++) {
if ((xor & mask(j)) != 0) {
return (i * Byte.SIZE) + j;
}
}
}
if (b1 != 0) {
allNull = false;
}
}
if (allNull) {
return KeyAnalyzer.NULL_BIT_KEY;
}
return KeyAnalyzer.EQUAL_BIT_KEY;
}
@Override
public boolean isBitSet(final AbstractFooKey key, final int bitIndex) {
if (bitIndex > lengthInBits(key)) {
return false;
}
int index = (int) (bitIndex / Byte.SIZE);
int bit = (int) (bitIndex % Byte.SIZE);
return (valueAt(key.getValues(), index) & mask(bit)) != 0;
}
@Override
public boolean isPrefix(final AbstractFooKey key, final AbstractFooKey prefix) {
if (key.getValues().length < prefix.getValues().length) {
return false;
}
for (int i = 0; i < prefix.getValues().length; i++) {
if (key.getValues()[i] != prefix.getValues()[i]) {
return false;
}
}
return true;
}
@Override
public int lengthInBits(final AbstractFooKey key) {
return key.getValues().length * 2 * Byte.SIZE;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment