/** Similar to {@link WritableUtils#readVLong(DataInput)} but reads from a {@link ByteBuff}. */ public static long readVLong(ByteBuff in) { byte firstByte = in.get(); int len = WritableUtils.decodeVIntSize(firstByte); if (len == 1) { return firstByte; } long i = 0; for (int idx = 0; idx < len - 1; idx++) { byte b = in.get(); i = i << 8; i = i | (b & 0xFF); } return (WritableUtils.isNegativeVInt(firstByte) ? (i ^ -1L) : i); }
/** * Read long which was written to fitInBytes bytes and increment position. * * @param fitInBytes In how many bytes given long is stored. * @return The value of parsed long. */ public static long readLong(ByteBuff in, final int fitInBytes) { long tmpLength = 0; for (int i = 0; i < fitInBytes; ++i) { tmpLength |= (in.get() & 0xffl) << (8l * i); } return tmpLength; }
/** * Compares two ByteBuffs * * @param buf1 the first ByteBuff * @param o1 the offset in the first ByteBuff from where the compare has to happen * @param len1 the length in the first ByteBuff upto which the compare has to happen * @param buf2 the second ByteBuff * @param o2 the offset in the second ByteBuff from where the compare has to happen * @param len2 the length in the second ByteBuff upto which the compare has to happen * @return Positive if buf1 is bigger than buf2, 0 if they are equal, and negative if buf1 is * smaller than buf2. */ public static int compareTo(ByteBuff buf1, int o1, int len1, ByteBuff buf2, int o2, int len2) { if (buf1.hasArray() && buf2.hasArray()) { return Bytes.compareTo( buf1.array(), buf1.arrayOffset() + o1, len1, buf2.array(), buf2.arrayOffset() + o2, len2); } int end1 = o1 + len1; int end2 = o2 + len2; for (int i = o1, j = o2; i < end1 && j < end2; i++, j++) { int a = buf1.get(i) & 0xFF; int b = buf2.get(j) & 0xFF; if (a != b) { return a - b; } } return len1 - len2; }
/** * Read integer from ByteBuff coded in 7 bits and increment position. * * @return Read integer. */ public static int readCompressedInt(ByteBuff buf) { byte b = buf.get(); if ((b & ByteBufferUtils.NEXT_BIT_MASK) != 0) { return (b & ByteBufferUtils.VALUE_MASK) + (readCompressedInt(buf) << ByteBufferUtils.NEXT_BIT_SHIFT); } return b & ByteBufferUtils.VALUE_MASK; }
@Override public ByteBuffer getKeyValueBuffer() { ByteBuffer kvBuffer = createKVBuffer(); kvBuffer.putInt(current.keyLength); kvBuffer.putInt(current.valueLength); kvBuffer.put(current.keyBuffer, 0, current.keyLength); currentBuffer.get(kvBuffer, current.valueOffset, current.valueLength); if (current.tagsLength > 0) { // Put short as unsigned kvBuffer.put((byte) (current.tagsLength >> 8 & 0xff)); kvBuffer.put((byte) (current.tagsLength & 0xff)); if (current.tagsOffset != -1) { // the offset of the tags bytes in the underlying buffer is marked. So the temp // buffer,tagsBuffer was not been used. currentBuffer.get(kvBuffer, current.tagsOffset, current.tagsLength); } else { // When tagsOffset is marked as -1, tag compression was present and so the tags were // uncompressed into temp buffer, tagsBuffer. Let us copy it from there kvBuffer.put(current.tagsBuffer, 0, current.tagsLength); } } kvBuffer.rewind(); return kvBuffer; }
public static String toStringBinary(final ByteBuff b, int off, int len) { StringBuilder result = new StringBuilder(); // Just in case we are passed a 'len' that is > buffer length... if (off >= b.capacity()) return result.toString(); if (off + len > b.capacity()) len = b.capacity() - off; for (int i = off; i < off + len; ++i) { int ch = b.get(i) & 0xFF; if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || " `~!@#$%^&*()-_=+[]{}|;:'\",.<>/?".indexOf(ch) >= 0) { result.append((char) ch); } else { result.append(String.format("\\x%02X", ch)); } } return result.toString(); }
/** * Search sorted array "a" for byte "key". * * @param a Array to search. Entries must be sorted and unique. * @param fromIndex First index inclusive of "a" to include in the search. * @param toIndex Last index exclusive of "a" to include in the search. * @param key The byte to search for. * @return The index of key if found. If not found, return -(index + 1), where negative indicates * "not found" and the "index + 1" handles the "-0" case. */ public static int unsignedBinarySearch(ByteBuff a, int fromIndex, int toIndex, byte key) { int unsignedKey = key & 0xff; int low = fromIndex; int high = toIndex - 1; while (low <= high) { int mid = (low + high) >>> 1; int midVal = a.get(mid) & 0xff; if (midVal < unsignedKey) { low = mid + 1; } else if (midVal > unsignedKey) { high = mid - 1; } else { return mid; // key found } } return -(low + 1); // key not found. }