public static void encodeLittleEndianFixedWidthLong(long l, byte[] array) { encodeLittleEndianFixedWidthLong(l, array, 0, array.length); }
private static ByteBuffer key(long key, int keySize) { byte[] keyBytes = new byte[keySize]; EncodingHelper.encodeLittleEndianFixedWidthLong(key, keyBytes); return ByteBuffer.wrap(keyBytes); }
@Override public void close() throws IOException { // clear the last block, if there is one if (uncompressedOffset > 0) { clearUncompressed(); } // serialize the footer byte[] footer = new byte[8 * hashIndex.length + 4 + 4]; for (int i = 0; i < hashIndex.length; i++) { EncodingHelper.encodeLittleEndianFixedWidthLong(hashIndex[i], footer, i * 8, 8); } // write the buffer size hints EncodingHelper.encodeLittleEndianFixedWidthLong(maxUncompressedBlockSize, footer, footer.length - 8, 4); EncodingHelper.encodeLittleEndianFixedWidthLong(maxCompressedBlockSize, footer, footer.length - 4, 4); stream.write(footer); numBytesWritten += footer.length; // flush everything and close stream.flush(); stream.close(); }
@Override public void transform(byte[] buf, int valueOff, int relIndex) { long adjustment = offsetAdjustments[relIndex]; if (adjustment != 0) { long offset = EncodingHelper.decodeLittleEndianFixedWidthLong(buf, valueOff, offsetNumBytes); offset += adjustment; EncodingHelper.encodeLittleEndianFixedWidthLong(offset, buf, valueOff, offsetNumBytes); } } }
@Override public void hash(ByteBuffer keyBytes, int keySize, byte[] hashBytes) { long key = EncodingHelper.decodeLittleEndianFixedWidthLong(keyBytes); if (hashIndexBits % 8 != 0) { throw new RuntimeException("hashIndexBits must be a multiple of 8"); } long keyBlock = key / NUM_RECORDS_PER_BLOCK; long keyIndex = key % NUM_RECORDS_PER_BLOCK; byte[] keyHashBytes = new byte[keySize]; // Note: this is valid because hashIndexBits must be a multiple of 8 int hashIndexBytes = hashIndexBits / 8; // Encode bytes for key block EncodingHelper.encodeLittleEndianFixedWidthLong(keyBlock, keyHashBytes, keyHashBytes.length - hashIndexBytes, hashIndexBytes); // Encode bytes for key index in block EncodingHelper.encodeLittleEndianFixedWidthLong(keyIndex, keyHashBytes, 0, keyHashBytes.length - hashIndexBytes); for (int i = 0; i < keyHashBytes.length; ++i) { hashBytes[i] = (byte)(0xff & keyHashBytes[keyHashBytes.length - 1 - i]); } } }
@Test public void testEncodeLittleEndianFixedWidthLong() throws Exception { byte[] arr = new byte[3]; EncodingHelper.encodeLittleEndianFixedWidthLong(1, arr); assertEquals(ByteBuffer.wrap(new byte[]{1, 0, 0}), ByteBuffer.wrap(arr)); EncodingHelper.encodeLittleEndianFixedWidthLong(-1, arr); assertEquals(ByteBuffer.wrap(new byte[]{-1, -1, -1}), ByteBuffer.wrap(arr)); EncodingHelper.encodeLittleEndianFixedWidthLong(0x001ff, arr); assertEquals(ByteBuffer.wrap(new byte[]{-1, 1, 0}), ByteBuffer.wrap(arr)); }
EncodingHelper.encodeLittleEndianFixedWidthLong(currentRecordOffset, valueOffsetBuffer.array()); EncodingHelper.encodeLittleEndianFixedWidthLong(currentRecordOffset, valueOffsetBuffer.array(), 0, offsetNumBytes); EncodingHelper.encodeLittleEndianFixedWidthLong(offsetInDecompressedBlock, valueOffsetBuffer.array(), offsetNumBytes, offsetInBlockNumBytes);