@Test public void testReadWrite() { for (int limit : limits) { PositionedByteRange buff = new SimplePositionedMutableByteRange(limit); for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) { for (byte[] val : VALUES) { buff.setPosition(0); DataType<byte[]> type = new FixedLengthWrapper<byte[]>(new RawBytes(ord), limit); assertEquals(limit, type.encode(buff, val)); buff.setPosition(0); byte[] actual = type.decode(buff); assertTrue("Decoding output differs from expected", Bytes.equals(val, 0, val.length, actual, 0, val.length)); buff.setPosition(0); assertEquals(limit, type.skip(buff)); } } } }
@Test public void testReadWriteSkippable() { PositionedByteRange buff = new SimplePositionedMutableByteRange(14); for (OrderedString t : new OrderedString[] { OrderedString.ASCENDING, OrderedString.DESCENDING }) { for (byte[] term : TERMINATORS) { for (String val : VALUES_STRINGS) { buff.setPosition(0); DataType<String> type = new TerminatedWrapper<String>(t, term); assertEquals(val.length() + 2 + term.length, type.encode(buff, val)); buff.setPosition(0); assertEquals(val, type.decode(buff)); assertEquals(val.length() + 2 + term.length, buff.getPosition()); } } } }
@Test public void testSkipSkippable() { PositionedByteRange buff = new SimplePositionedMutableByteRange(14); for (OrderedString t : new OrderedString[] { OrderedString.ASCENDING, OrderedString.DESCENDING }) { for (byte[] term : TERMINATORS) { for (String val : VALUES_STRINGS) { buff.setPosition(0); DataType<String> type = new TerminatedWrapper<String>(t, term); int expected = val.length() + 2 + term.length; assertEquals(expected, type.encode(buff, val)); buff.setPosition(0); assertEquals(expected, type.skip(buff)); assertEquals(expected, buff.getPosition()); } } } }
@Test public void testReadWriteNonSkippable() { PositionedByteRange buff = new SimplePositionedMutableByteRange(12); for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) { for (byte[] term : TERMINATORS) { for (byte[] val : VALUES_BYTES) { buff.setPosition(0); DataType<byte[]> type = new TerminatedWrapper<byte[]>(new RawBytes(ord), term); assertEquals(val.length + term.length, type.encode(buff, val)); buff.setPosition(0); assertArrayEquals(val, type.decode(buff)); assertEquals(val.length + term.length, buff.getPosition()); } } } }
/** * Skip {@code src}'s position forward over one encoded value. * @param src the buffer containing the encoded value. * @return number of bytes skipped. * @throws IllegalArgumentException when the terminator sequence is not found. */ @Override public int skip(PositionedByteRange src) { if (wrapped.isSkippable()) { int ret = wrapped.skip(src); src.setPosition(src.getPosition() + term.length); return ret + term.length; } else { // find the terminator position final int start = src.getPosition(); int skipped = terminatorPosition(src); if (-1 == skipped) throw new IllegalArgumentException("Terminator sequence not found."); skipped += term.length; src.setPosition(skipped); return skipped - start; } }
public static void generateHBaseDatasetDoubleOB(Connection conn, Admin admin, TableName tableName, int numberRegions) throws Exception { if (admin.tableExists(tableName)) { admin.disableTable(tableName); admin.deleteTable(tableName); } HTableDescriptor desc = new HTableDescriptor(tableName); desc.addFamily(new HColumnDescriptor(FAMILY_F)); if (numberRegions > 1) { admin.createTable(desc, Arrays.copyOfRange(SPLIT_KEYS, 0, numberRegions-1)); } else { admin.createTable(desc); } BufferedMutator table = conn.getBufferedMutator(tableName); for (double i = 0.5; i <= 100.00; i += 0.75) { byte[] bytes = new byte[9]; PositionedByteRange br = new SimplePositionedMutableByteRange(bytes, 0, 9); OrderedBytes.encodeFloat64(br, i, Order.ASCENDING); Put p = new Put(bytes); p.addColumn(FAMILY_F, COLUMN_C, String.format("value %03f", i).getBytes()); table.mutate(p); } table.close(); admin.flush(tableName); }
public static void generateHBaseDatasetFloatOB(Connection conn, Admin admin, TableName tableName, int numberRegions) throws Exception { if (admin.tableExists(tableName)) { admin.disableTable(tableName); admin.deleteTable(tableName); } HTableDescriptor desc = new HTableDescriptor(tableName); desc.addFamily(new HColumnDescriptor(FAMILY_F)); if (numberRegions > 1) { admin.createTable(desc, Arrays.copyOfRange(SPLIT_KEYS, 0, numberRegions-1)); } else { admin.createTable(desc); } BufferedMutator table = conn.getBufferedMutator(tableName); for (float i = (float)0.5; i <= 100.00; i += 0.75) { byte[] bytes = new byte[5]; PositionedByteRange br = new SimplePositionedMutableByteRange(bytes, 0, 5); OrderedBytes.encodeFloat32(br, i,Order.ASCENDING); Put p = new Put(bytes); p.addColumn(FAMILY_F, COLUMN_C, String.format("value %03f", i).getBytes()); table.mutate(p); } table.close(); admin.flush(tableName); }
@Override public Pojo1 decode(PositionedByteRange src) { Object[] ret = new Object[3]; ret[0] = stringField.decode(src); ret[1] = intField.decode(src); ret[2] = doubleField.decode(src); return new Pojo1(ret); }
public static void generateHBaseDatasetIntOB(Connection conn, Admin admin, TableName tableName, int numberRegions) throws Exception { if (admin.tableExists(tableName)) { admin.disableTable(tableName); admin.deleteTable(tableName); } HTableDescriptor desc = new HTableDescriptor(tableName); desc.addFamily(new HColumnDescriptor(FAMILY_F)); if (numberRegions > 1) { admin.createTable(desc, Arrays.copyOfRange(SPLIT_KEYS, 0, numberRegions-1)); } else { admin.createTable(desc); } BufferedMutator table = conn.getBufferedMutator(tableName); for (int i = -49; i <= 100; i ++) { byte[] bytes = new byte[5]; PositionedByteRange br = new SimplePositionedMutableByteRange(bytes, 0, 5); OrderedBytes.encodeInt32(br, i, Order.ASCENDING); Put p = new Put(bytes); p.addColumn(FAMILY_F, COLUMN_C, String.format("value %d", i).getBytes()); table.mutate(p); } table.close(); admin.flush(tableName); }
@Override public int skip(PositionedByteRange src) { CellProtos.Cell.Builder builder = CellProtos.Cell.newBuilder(); CodedInputStream is = inputStreamFromByteRange(src); is.setSizeLimit(src.getLength()); try { builder.mergeFrom(is); int consumed = is.getTotalBytesRead(); src.setPosition(src.getPosition() + consumed); return consumed; } catch (IOException e) { throw new RuntimeException("Error while skipping type.", e); } }
public static void generateHBaseDatasetFloatOBDesc(Connection conn, Admin admin, TableName tableName, int numberRegions) throws Exception { if (admin.tableExists(tableName)) { admin.disableTable(tableName); admin.deleteTable(tableName); } HTableDescriptor desc = new HTableDescriptor(tableName); desc.addFamily(new HColumnDescriptor(FAMILY_F)); if (numberRegions > 1) { admin.createTable(desc, Arrays.copyOfRange(SPLIT_KEYS, 0, numberRegions-1)); } else { admin.createTable(desc); } BufferedMutator table = conn.getBufferedMutator(tableName); for (float i = (float)0.5; i <= 100.00; i += 0.75) { byte[] bytes = new byte[5]; PositionedByteRange br = new SimplePositionedMutableByteRange(bytes, 0, 5); OrderedBytes.encodeFloat32(br, i, Order.DESCENDING); Put p = new Put(bytes); p.addColumn(FAMILY_F, COLUMN_C, String.format("value %03f", i).getBytes()); table.mutate(p); } table.close(); admin.flush(tableName); }
public static void generateHBaseDatasetBigIntOBDesc(Connection conn, Admin admin, TableName tableName, int numberRegions) throws Exception { if (admin.tableExists(tableName)) { admin.disableTable(tableName); admin.deleteTable(tableName); } HTableDescriptor desc = new HTableDescriptor(tableName); desc.addFamily(new HColumnDescriptor(FAMILY_F)); if (numberRegions > 1) { admin.createTable(desc, Arrays.copyOfRange(SPLIT_KEYS, 0, numberRegions-1)); } else { admin.createTable(desc); } BufferedMutator table = conn.getBufferedMutator(tableName); long startTime = (long)1438034423 * 1000; for (long i = startTime; i <= startTime + 100; i ++) { byte[] bytes = new byte[9]; PositionedByteRange br = new SimplePositionedMutableByteRange(bytes, 0, 9); OrderedBytes.encodeInt64(br, i, Order.DESCENDING); Put p = new Put(bytes); p.addColumn(FAMILY_F, COLUMN_C, String.format("value %d", i).getBytes()); table.mutate(p); } table.close(); admin.flush(tableName); }
public static void generateHBaseDatasetIntOBDesc(Connection conn, Admin admin, TableName tableName, int numberRegions) throws Exception { if (admin.tableExists(tableName)) { admin.disableTable(tableName); admin.deleteTable(tableName); } HTableDescriptor desc = new HTableDescriptor(tableName); desc.addFamily(new HColumnDescriptor(FAMILY_F)); if (numberRegions > 1) { admin.createTable(desc, Arrays.copyOfRange(SPLIT_KEYS, 0, numberRegions-1)); } else { admin.createTable(desc); } BufferedMutator table = conn.getBufferedMutator(tableName); for (int i = -49; i <= 100; i ++) { byte[] bytes = new byte[5]; PositionedByteRange br = new SimplePositionedMutableByteRange(bytes, 0, 5); OrderedBytes.encodeInt32(br, i, Order.DESCENDING); Put p = new Put(bytes); p.addColumn(FAMILY_F, COLUMN_C, String.format("value %d", i).getBytes()); table.mutate(p); } table.close(); admin.flush(tableName); }
@Override public int encode(PositionedByteRange dst, Pojo2 val) { int written = byteField1.encode(dst, val.byteField1Asc); written += byteField2.encode(dst, val.byteField2Dsc); written += stringField.encode(dst, val.stringFieldDsc); written += byteField3.encode(dst, val.byteField3Dsc); return written; }
@Override public Pojo2 decode(PositionedByteRange src) { Object[] ret = new Object[4]; ret[0] = byteField1.decode(src); ret[1] = byteField2.decode(src); ret[2] = stringField.decode(src); ret[3] = byteField3.decode(src); return new Pojo2(ret); }
@Test public void testSkip() { Integer intVal = Integer.valueOf(10); String strVal = "hello"; PositionedByteRange buff = new SimplePositionedMutableByteRange(10); SampleUnion1 type = new SampleUnion1(); int len = type.encode(buff, intVal); buff.setPosition(0); assertEquals(len, type.skip(buff)); buff.setPosition(0); len = type.encode(buff, strVal); buff.setPosition(0); assertEquals(len, type.skip(buff)); }
@Override public String decode(PositionedByteRange src) { if (Order.ASCENDING == this.order) { // avoid unnecessary array copy for ASC case. String val = Bytes.toString(src.getBytes(), src.getOffset() + src.getPosition(), src.getRemaining()); src.setPosition(src.getLength()); return val; } else { byte[] b = new byte[src.getRemaining()]; src.get(b); order.apply(b, 0, b.length); return Bytes.toString(b); } }
@Override public int encode(PositionedByteRange dst, String val) { byte[] s = Bytes.toBytes(val); order.apply(s); dst.put(s); return s.length; }
@Override public int skip(PositionedByteRange src) { StructIterator it = iterator(src); int skipped = 0; while (it.hasNext()) skipped += it.skip(); return skipped; }
@Test public void testEncodedLength() { PositionedByteRange buff = new SimplePositionedMutableByteRange(20); for (DataType<String> type : new OrderedString[] { OrderedString.ASCENDING, OrderedString.DESCENDING }) { for (String val : VALUES) { buff.setPosition(0); type.encode(buff, val); assertEquals( "encodedLength does not match actual, " + val, buff.getPosition(), type.encodedLength(val)); } } }
/** * Read the field at {@code index}. {@code src}'s position is not affected. */ public Object decode(PositionedByteRange src, int index) { assert index >= 0; StructIterator it = iterator(src.shallowCopy()); for (; index > 0; index--) it.skip(); return it.next(); }
@SuppressWarnings("unchecked") @Override public int encode(PositionedByteRange dst, Object[] val) { if (val.length == 0) return 0; assert fields.length >= val.length; int end, written = 0; // find the last occurrence of a non-null or null and non-nullable value for (end = val.length - 1; end > -1; end--) { if (null != val[end] || (null == val[end] && !fields[end].isNullable())) break; } for (int i = 0; i <= end; i++) { written += fields[i].encode(dst, val[i]); } return written; }
@Override public int skip(PositionedByteRange src) { int skipped = stringField.skip(src); skipped += intField.skip(src); skipped += doubleField.skip(src); return skipped; }
@Override public Number decode(PositionedByteRange src) { if (OrderedBytes.isNumericInfinite(src) || OrderedBytes.isNumericNaN(src)) { return OrderedBytes.decodeNumericAsDouble(src); } return OrderedBytes.decodeNumericAsBigDecimal(src); }
@Override public int encode(PositionedByteRange dst, Number val) { if (null == val) { return OrderedBytes.encodeNull(dst, order); } else if (val instanceof BigDecimal) { return OrderedBytes.encodeNumeric(dst, (BigDecimal) val, order); } else if (val instanceof BigInteger) { return OrderedBytes.encodeNumeric(dst, new BigDecimal((BigInteger) val), order); } else if (val instanceof Double || val instanceof Float) { return OrderedBytes.encodeNumeric(dst, val.doubleValue(), order); } else { // TODO: other instances of Numeric to consider? return OrderedBytes.encodeNumeric(dst, val.longValue(), order); } }
/** * Basic test to verify utility methods in {@link PBType} and delegation to protobuf works. */ @Test public void testRoundTrip() { final Cell cell = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("fam"), Bytes.toBytes("qual"), Bytes.toBytes("val")); CellProtos.Cell c = ProtobufUtil.toCell(cell), decoded; PositionedByteRange pbr = new SimplePositionedByteRange(c.getSerializedSize()); pbr.setPosition(0); int encodedLength = CODEC.encode(pbr, c); pbr.setPosition(0); decoded = CODEC.decode(pbr); assertEquals(encodedLength, pbr.getPosition()); assertTrue(CellComparator.equals(cell, ProtobufUtil.toCell(decoded))); }
@Override public int encode(PositionedByteRange dst, CellProtos.Cell val) { CodedOutputStream os = outputStreamFromByteRange(dst); try { int before = os.spaceLeft(), after, written; val.writeTo(os); after = os.spaceLeft(); written = before - after; dst.setPosition(dst.getPosition() + written); return written; } catch (IOException e) { throw new RuntimeException("Error while encoding type.", e); } }
@Test public void testEncodeDecode() { Integer intVal = Integer.valueOf(10); String strVal = "hello"; PositionedByteRange buff = new SimplePositionedMutableByteRange(10); SampleUnion1 type = new SampleUnion1(); type.encode(buff, intVal); buff.setPosition(0); assertTrue(0 == intVal.compareTo(type.decodeA(buff))); buff.setPosition(0); type.encode(buff, strVal); buff.setPosition(0); assertTrue(0 == strVal.compareTo(type.decodeB(buff))); }
@Override public Object decode(PositionedByteRange src) { switch (src.get()) { case IS_INTEGER: return typeA.decode(src); case IS_STRING: return typeB.decode(src); default: throw new IllegalArgumentException("Unrecognized encoding format."); } }
@Override public int skip(PositionedByteRange src) { int skipped = byteField1.skip(src); skipped += byteField2.skip(src); skipped += stringField.skip(src); skipped += byteField3.skip(src); return skipped; }
@Test public void testEncodedLength() { PositionedByteRange buff = new SimplePositionedMutableByteRange(20); for (DataType<byte[]> type : new OrderedBlob[] { OrderedBlob.ASCENDING, OrderedBlob.DESCENDING }) { for (byte[] val : VALUES) { buff.setPosition(0); type.encode(buff, val); assertEquals( "encodedLength does not match actual, " + Bytes.toStringBinary(val), buff.getPosition(), type.encodedLength(val)); } } }
@Test @SuppressWarnings("unchecked") public void testOrderPreservation() throws Exception { Object[] vals = new Object[constructorArgs.length]; PositionedByteRange[] encodedGeneric = new PositionedByteRange[constructorArgs.length]; PositionedByteRange[] encodedSpecialized = new PositionedByteRange[constructorArgs.length]; Constructor<?> ctor = specialized.encodedClass().getConstructor(Object[].class); for (int i = 0; i < vals.length; i++) { vals[i] = ctor.newInstance(new Object[] { constructorArgs[i] }); encodedGeneric[i] = new SimplePositionedMutableByteRange( generic.encodedLength(constructorArgs[i])); encodedSpecialized[i] = new SimplePositionedMutableByteRange( specialized.encodedLength(vals[i])); } // populate our arrays for (int i = 0; i < vals.length; i++) { generic.encode(encodedGeneric[i], constructorArgs[i]); encodedGeneric[i].setPosition(0); specialized.encode(encodedSpecialized[i], vals[i]); encodedSpecialized[i].setPosition(0); assertArrayEquals(encodedGeneric[i].getBytes(), encodedSpecialized[i].getBytes()); } Arrays.sort(vals); Arrays.sort(encodedGeneric); Arrays.sort(encodedSpecialized); for (int i = 0; i < vals.length; i++) { assertEquals( "Struct encoder does not preserve sort order at position " + i, vals[i], ctor.newInstance(new Object[] { generic.decode(encodedGeneric[i]) })); assertEquals( "Specialized encoder does not preserve sort order at position " + i, vals[i], specialized.decode(encodedSpecialized[i])); } }
/** * Return the position at which {@code term} begins within {@code src}, * or {@code -1} if {@code term} is not found. */ protected int terminatorPosition(PositionedByteRange src) { byte[] a = src.getBytes(); final int offset = src.getOffset(); int i; SKIP: for (i = src.getPosition(); i < src.getLength(); i++) { if (a[offset + i] != term[0]) continue; int j; for (j = 1; j < term.length && offset + j < src.getLength(); j++) { if (a[offset + i + j] != term[j]) continue SKIP; } if (j == term.length) return i; // success } return -1; }
/** * Write instance {@code val} into buffer {@code dst}. * @throws IllegalArgumentException when the encoded representation of * {@code val} contains the {@code term} sequence. */ @Override public int encode(PositionedByteRange dst, T val) { final int start = dst.getPosition(); int written = wrapped.encode(dst, val); PositionedByteRange b = dst.shallowCopy(); b.setLength(dst.getPosition()); b.setPosition(start); if (-1 != terminatorPosition(b)) { dst.setPosition(start); throw new IllegalArgumentException("Encoded value contains terminator sequence."); } dst.put(term); return written + term.length; }
/** * Verify null extension respects the type's isNullable field. */ @Test(expected = NullPointerException.class) public void testNonNullableNullExtension() { Struct s = new StructBuilder() .add(new RawStringTerminated("|")) // not nullable .toStruct(); PositionedByteRange buf = new SimplePositionedMutableByteRange(4); s.encode(buf, new Object[1]); }
@Override public int skip(PositionedByteRange src) { src.setPosition(src.getPosition() + Bytes.SIZEOF_INT); return Bytes.SIZEOF_INT; }
@Override public Integer decode(PositionedByteRange src) { int val = Bytes.toInt(src.getBytes(), src.getOffset() + src.getPosition()); skip(src); return val; }
@Override public int encode(PositionedByteRange dst, Integer val) { Bytes.putInt(dst.getBytes(), dst.getOffset() + dst.getPosition(), val); return skip(dst); }
@Override public Double decode(PositionedByteRange src) { double val = Bytes.toDouble(src.getBytes(), src.getOffset() + src.getPosition()); skip(src); return val; }
@Test(expected = IllegalArgumentException.class) public void testEncodedValueContainsTerm() { DataType<byte[]> type = new TerminatedWrapper<byte[]>(new RawBytes(), "foo"); PositionedByteRange buff = new SimplePositionedMutableByteRange(16); type.encode(buff, Bytes.toBytes("hello foobar!")); }