public static int calculateNumberOfBlocksUsed(long firstBlock) { Bits bits = Bits.bitsFromLongs(new long[] {firstBlock}); // bbbb][bbll,llll][yyyy,tttt][kkkk,kkkk][kkkk,kkkk][kkkk,kkkk] bits.getInt(24); // Get rid of key bits.getByte(4); // Get rid of short array type bits.getByte(4); // Get rid of the type int arrayLength = bits.getByte(6); int requiredBits = bits.getByte(6); if (requiredBits == 0) { requiredBits = 64; } return calculateNumberOfBlocksUsed(arrayLength, requiredBits); }
@Test public void writeAndRead() throws Exception { for (int b = 5; b <= 8; b++) { Bits bits = Bits.bits(16); for (byte value = 0; value < 16; value++) { bits.put(value, b); } for (byte expected = 0; bits.available(); expected++) { assertEquals(expected, bits.getByte(b)); } } for (byte value = Byte.MIN_VALUE; value < Byte.MAX_VALUE; value++) { Bits bits = Bits.bits(8); bits.put(value); assertEquals(value, bits.getByte()); } }
@Override Object createArray(int length, Bits bits, int requiredBits) { if (length == 0) { return EMPTY_BOOLEAN_ARRAY; } final boolean[] result = new boolean[length]; for (int i = 0; i < length; i++) { result[i] = bits.getByte(requiredBits) != 0; } return result; }
public static Object decode(PropertyBlock block) { Bits bits = Bits.bitsFromLongs(Arrays.copyOf(block.getValueBlocks(), block.getValueBlocks().length)); // [][][ ,bbbb][bbll,llll][yyyy,tttt][kkkk,kkkk][kkkk,kkkk][kkkk,kkkk] bits.getInt(24); // Get rid of key bits.getByte(4); // Get rid of short array type int typeId = bits.getByte(4); int arrayLength = bits.getByte(6); int requiredBits = bits.getByte(6); /* * So, it can be the case that values require 64 bits to store. However, you cannot encode this * value with 6 bits. calculateRequiredBitsForArray never returns 0, because even for an array of * all 0s one bit is required for every value. So when writing, we let it overflow and write out * 0. When we are reading back, we just have to make sure that reading in 0 means 64. */ if (requiredBits == 0) { requiredBits = 64; } ShortArray type = typeOf((byte) typeId); return type.createArray(arrayLength, bits, requiredBits); }