static void writeCell(PositionedByteRange pbr, KeyValue kv) throws Exception { pbr.putInt(kv.getKeyLength()); pbr.putInt(kv.getValueLength()); pbr.put(kv.getBuffer(), kv.getKeyOffset(), kv.getKeyLength()); pbr.put(kv.getBuffer(), kv.getValueOffset(), kv.getValueLength()); int tagsLen = kv.getTagsLength(); pbr.put((byte) (tagsLen >> 8 & 0xff)); pbr.put((byte) (tagsLen & 0xff)); pbr.put(kv.getTagsArray(), kv.getTagsOffset(), tagsLen); pbr.putVLong(kv.getSequenceId()); }
/** * Encode a null value. * @param dst The destination to which encoded digits are written. * @param ord The {@link Order} to respect while encoding {@code val}. * @return the number of bytes written. */ public static int encodeNull(PositionedByteRange dst, Order ord) { dst.put(ord.apply(NULL)); return 1; }
@Override public int encode(PositionedByteRange dst, String val) { byte[] s = Bytes.toBytes(val); order.apply(s); dst.put(s); return s.length; } }
/** * Encode an {@code int32} value using the fixed-length encoding. * @return the number of bytes written. * @see #encodeInt64(PositionedByteRange, long, Order) * @see #decodeInt32(PositionedByteRange) */ public static int encodeInt32(PositionedByteRange dst, int val, Order ord) { final int offset = dst.getOffset(), start = dst.getPosition(); dst.put(FIXED_INT32) .put((byte) ((val >> 24) ^ 0x80)) .put((byte) (val >> 16)) .put((byte) (val >> 8)) .put((byte) val); ord.apply(dst.getBytes(), offset + start, 5); return 5; }
/** * Encode a 32-bit floating point value using the fixed-length encoding. * Encoding format is described at length in * {@link #encodeFloat64(PositionedByteRange, double, Order)}. * @return the number of bytes written. * @see #decodeFloat32(PositionedByteRange) * @see #encodeFloat64(PositionedByteRange, double, Order) */ public static int encodeFloat32(PositionedByteRange dst, float val, Order ord) { final int offset = dst.getOffset(), start = dst.getPosition(); int i = Float.floatToIntBits(val); i ^= ((i >> (Integer.SIZE - 1)) | Integer.MIN_VALUE); dst.put(FIXED_FLOAT32) .put((byte) (i >> 24)) .put((byte) (i >> 16)) .put((byte) (i >> 8)) .put((byte) i); ord.apply(dst.getBytes(), offset + start, 5); return 5; }
/** * Encode an {@code int16} value using the fixed-length encoding. * @return the number of bytes written. * @see #encodeInt64(PositionedByteRange, long, Order) * @see #decodeInt16(PositionedByteRange) */ public static int encodeInt16(PositionedByteRange dst, short val, Order ord) { final int offset = dst.getOffset(), start = dst.getPosition(); dst.put(FIXED_INT16) .put((byte) ((val >> 8) ^ 0x80)) .put((byte) val); ord.apply(dst.getBytes(), offset + start, 3); return 3; }
/** * Encode a numerical value using the variable-length encoding. * @param dst The destination to which encoded digits are written. * @param val The value to encode. * @param ord The {@link Order} to respect while encoding {@code val}. * @return the number of bytes written. */ public static int encodeNumeric(PositionedByteRange dst, double val, Order ord) { if (val == 0.0) { dst.put(ord.apply(ZERO)); return 1; } if (Double.isNaN(val)) { dst.put(ord.apply(NAN)); return 1; } if (val == Double.NEGATIVE_INFINITY) { dst.put(ord.apply(NEG_INF)); return 1; } if (val == Double.POSITIVE_INFINITY) { dst.put(ord.apply(POS_INF)); return 1; } return encodeNumeric(dst, BigDecimal.valueOf(val), ord); }
/** * Encode an {@code int8} value using the fixed-length encoding. * @return the number of bytes written. * @see #encodeInt64(PositionedByteRange, long, Order) * @see #decodeInt8(PositionedByteRange) */ public static int encodeInt8(PositionedByteRange dst, byte val, Order ord) { final int offset = dst.getOffset(), start = dst.getPosition(); dst.put(FIXED_INT8) .put((byte) (val ^ 0x80)); ord.apply(dst.getBytes(), offset + start, 2); return 2; }
/** * Encode a String value. String encoding is 0x00-terminated and so it does * not support {@code \u0000} codepoints in the value. * @param dst The destination to which the encoded value is written. * @param val The value to encode. * @param ord The {@link Order} to respect while encoding {@code val}. * @return the number of bytes written. * @throws IllegalArgumentException when {@code val} contains a {@code \u0000}. */ public static int encodeString(PositionedByteRange dst, String val, Order ord) { if (null == val) { return encodeNull(dst, ord); } if (val.contains("\u0000")) throw new IllegalArgumentException("Cannot encode String values containing '\\u0000'"); final int offset = dst.getOffset(), start = dst.getPosition(); dst.put(TEXT); // TODO: is there no way to decode into dst directly? dst.put(val.getBytes(UTF8)); dst.put(TERM); ord.apply(dst.getBytes(), offset + start, dst.getPosition() - start); return dst.getPosition() - start; }
@Override public int encode(PositionedByteRange dst, T val) { if (dst.getRemaining() < length) { throw new IllegalArgumentException("Not enough buffer remaining. dst.offset: " + dst.getOffset() + " dst.length: " + dst.getLength() + " dst.position: " + dst.getPosition() + " max length: " + length); } int written = base.encode(dst, val); if (written > length) { throw new IllegalArgumentException("Length of encoded value (" + written + ") exceeds max length (" + length + ")."); } // TODO: is the zero-padding appropriate? for (; written < length; written++) { dst.put((byte) 0x00); } return written; } }
@Override public int encode(PositionedByteRange dst, Object val) { Integer i = null; String s = null; try { i = (Integer) val; } catch (ClassCastException e) {} try { s = (String) val; } catch (ClassCastException e) {} if (null != i) { dst.put(IS_INTEGER); return 1 + typeA.encode(dst, i); } else if (null != s) { dst.put(IS_STRING); return 1 + typeB.encode(dst, s); } else throw new IllegalArgumentException("val is not of a supported type."); } }
dst.put(BLOB_VAR); if (0 == vlen) { dst.put(TERM); } else { byte s = 1, t = 0; for (int i = voff; i < vlen; i++) { dst.put((byte) (0x80 | t | ((val[i] & 0xff) >>> s))); if (s < 7) { t = (byte) (val[i] << (7 - s)); s++; } else { dst.put((byte) (0x80 | val[i])); s = 1; t = 0; dst.put((byte) (0x7f & t)); } else { dst.getBytes()[offset + dst.getPosition() - 1] =
/** * Encode a numerical value using the variable-length encoding. * @param dst The destination to which encoded digits are written. * @param val The value to encode. * @param ord The {@link Order} to respect while encoding {@code val}. * @return the number of bytes written. */ public static int encodeNumeric(PositionedByteRange dst, BigDecimal val, Order ord) { final int len, offset = dst.getOffset(), start = dst.getPosition(); if (null == val) { return encodeNull(dst, ord); } else if (BigDecimal.ZERO.compareTo(val) == 0) { dst.put(ord.apply(ZERO)); return 1; } BigDecimal abs = val.abs(); if (BigDecimal.ONE.compareTo(abs) <= 0) { // abs(v) >= 1.0 len = encodeNumericLarge(dst, normalize(val)); } else { // 1.0 > abs(v) >= 0.0 len = encodeNumericSmall(dst, normalize(val)); } ord.apply(dst.getBytes(), offset + start, len); return len; }
/** * 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; } }