Added position as a parameter for reading/writing optimized int/long

This commit is contained in:
nathan 2016-03-09 00:52:46 +01:00
parent 7983454378
commit 1162d0c3f9
2 changed files with 126 additions and 73 deletions

View File

@ -34,12 +34,11 @@
*/ */
package dorkbox.util.bytes; package dorkbox.util.bytes;
@SuppressWarnings({"Duplicates", "NumericCastThatLosesPrecision", "UnusedAssignment", "IntegerMultiplicationImplicitCastToLong", "unused"})
public public
class OptimizeUtilsByteArray { class OptimizeUtilsByteArray {
/** /**
* FROM KRYO
* <p>
* Returns the number of bytes that would be written with {@link #writeInt(byte[], int, boolean)}. * Returns the number of bytes that would be written with {@link #writeInt(byte[], int, boolean)}.
* *
* @param optimizePositive * @param optimizePositive
@ -53,8 +52,6 @@ class OptimizeUtilsByteArray {
// int // int
/** /**
* FROM KRYO
* <p>
* look at buffer, and see if we can read the length of the int off of it. (from the reader index) * look at buffer, and see if we can read the length of the int off of it. (from the reader index)
* *
* @return 0 if we could not read anything, >0 for the number of bytes for the int on the buffer * @return 0 if we could not read anything, >0 for the number of bytes for the int on the buffer
@ -62,34 +59,61 @@ class OptimizeUtilsByteArray {
@SuppressWarnings("SimplifiableIfStatement") @SuppressWarnings("SimplifiableIfStatement")
public static public static
boolean canReadInt(byte[] buffer) { boolean canReadInt(byte[] buffer) {
int position = 0;
return canReadInt(buffer, position);
}
/**
* FROM KRYO
* <p>
* look at buffer, and see if we can read the length of the int off of it. (from the reader index)
*
* @param position where in the buffer to start reading
* @return 0 if we could not read anything, >0 for the number of bytes for the int on the buffer
*/
@SuppressWarnings("SimplifiableIfStatement")
public static
boolean canReadInt(final byte[] buffer, int position) {
int length = buffer.length; int length = buffer.length;
if (length >= 5) { if (length >= 5) {
return true; return true;
} }
int p = 0; if ((buffer[position++] & 0x80) == 0) {
if ((buffer[p++] & 0x80) == 0) {
return true; return true;
} }
if (p == length) { if (position == length) {
return false; return false;
} }
if ((buffer[p++] & 0x80) == 0) { if ((buffer[position++] & 0x80) == 0) {
return true; return true;
} }
if (p == length) { if (position == length) {
return false; return false;
} }
if ((buffer[p++] & 0x80) == 0) { if ((buffer[position++] & 0x80) == 0) {
return true; return true;
} }
if (p == length) { if (position == length) {
return false; return false;
} }
if ((buffer[p++] & 0x80) == 0) { if ((buffer[position++] & 0x80) == 0) {
return true; return true;
} }
return p != length; return position != length;
}
/**
* Reads an int from the buffer that was optimized at position 0
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*/
public static
int readInt(byte[] buffer, boolean optimizePositive) {
int position = 0;
return readInt(buffer, optimizePositive, position);
} }
/** /**
@ -97,14 +121,13 @@ class OptimizeUtilsByteArray {
* <p> * <p>
* Reads an int from the buffer that was optimized. * Reads an int from the buffer that was optimized.
* *
* @param position where in the buffer to start reading
* @param optimizePositive * @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5 * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5
* bytes). This ultimately means that it will use fewer bytes for positive numbers. * bytes). This ultimately means that it will use fewer bytes for positive numbers.
*/ */
@SuppressWarnings("UnusedAssignment")
public static public static
int readInt(byte[] buffer, boolean optimizePositive) { int readInt(final byte[] buffer, final boolean optimizePositive, int position) {
int position = 0;
int b = buffer[position++]; int b = buffer[position++];
int result = b & 0x7F; int result = b & 0x7F;
if ((b & 0x80) != 0) { if ((b & 0x80) != 0) {
@ -127,8 +150,6 @@ class OptimizeUtilsByteArray {
} }
/** /**
* FROM KRYO
* <p>
* Writes the specified int to the buffer using 1 to 5 bytes, depending on the size of the number. * Writes the specified int to the buffer using 1 to 5 bytes, depending on the size of the number.
* *
* @param optimizePositive * @param optimizePositive
@ -137,10 +158,26 @@ class OptimizeUtilsByteArray {
* *
* @return the number of bytes written. * @return the number of bytes written.
*/ */
@SuppressWarnings({"UnusedAssignment", "NumericCastThatLosesPrecision", "Duplicates"})
public static public static
int writeInt(byte[] buffer, int value, boolean optimizePositive) { int writeInt(byte[] buffer, int value, boolean optimizePositive) {
int position = 0; int position = 0;
return writeInt(buffer, value, optimizePositive, position);
}
/**
* FROM KRYO
* <p>
* Writes the specified int to the buffer using 1 to 5 bytes, depending on the size of the number.
*
* @param position where in the buffer to start writing
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*
* @return the number of bytes written.
*/
public static
int writeInt(final byte[] buffer, int value, final boolean optimizePositive, int position) {
if (!optimizePositive) { if (!optimizePositive) {
value = value << 1 ^ value >> 31; value = value << 1 ^ value >> 31;
} }
@ -180,54 +217,37 @@ class OptimizeUtilsByteArray {
* @param optimizePositive * @param optimizePositive
* true if you want to optimize the number of bytes needed to write the length value * true if you want to optimize the number of bytes needed to write the length value
*/ */
@SuppressWarnings("Duplicates")
public static public static
int longLength(long value, boolean optimizePositive) { int longLength(long value, boolean optimizePositive) {
if (!optimizePositive) { return OptimizeUtilsByteBuf.longLength(value, optimizePositive);
value = value << 1 ^ value >> 63;
}
if (value >>> 7 == 0) {
return 1;
}
if (value >>> 14 == 0) {
return 2;
}
if (value >>> 21 == 0) {
return 3;
}
if (value >>> 28 == 0) {
return 4;
}
if (value >>> 35 == 0) {
return 5;
}
if (value >>> 42 == 0) {
return 6;
}
if (value >>> 49 == 0) {
return 7;
}
if (value >>> 56 == 0) {
return 8;
}
return 9;
} }
// long // long
/** /**
* FROM KRYO
* <p>
* Reads a 1-9 byte long. * Reads a 1-9 byte long.
* *
* @param optimizePositive * @param optimizePositive
* true if you want to optimize the number of bytes needed to write the length value * true if you want to optimize the number of bytes needed to write the length value
*/ */
@SuppressWarnings({"IntegerMultiplicationImplicitCastToLong", "UnusedAssignment"})
public static public static
long readLong(byte[] buffer, boolean optimizePositive) { long readLong(byte[] buffer, boolean optimizePositive) {
int position = 0; int position = 0;
return readLong(buffer, optimizePositive, position);
}
/**
* FROM KRYO
* <p>
* Reads a 1-9 byte long.
*
* @param position where in the buffer to start reading
* @param optimizePositive
* true if you want to optimize the number of bytes needed to write the length value
*/
public static
long readLong(final byte[] buffer, final boolean optimizePositive, int position) {
int b = buffer[position++]; int b = buffer[position++];
long result = b & 0x7F; long result = b & 0x7F;
if ((b & 0x80) != 0) { if ((b & 0x80) != 0) {
@ -269,8 +289,6 @@ class OptimizeUtilsByteArray {
} }
/** /**
* FROM KRYO
* <p>
* Writes a 1-9 byte long. * Writes a 1-9 byte long.
* *
* @param optimizePositive * @param optimizePositive
@ -279,13 +297,29 @@ class OptimizeUtilsByteArray {
* *
* @return the number of bytes written. * @return the number of bytes written.
*/ */
@SuppressWarnings({"Duplicates", "UnusedAssignment", "NumericCastThatLosesPrecision"})
public static public static
int writeLong(byte[] buffer, long value, boolean optimizePositive) { int writeLong(byte[] buffer, long value, boolean optimizePositive) {
int position = 0;
return writeLong(buffer, value, optimizePositive, position);
}
/**
* FROM KRYO
* <p>
* Writes a 1-9 byte long.
*
* @param position where in the buffer to start writing
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9
* bytes).
*
* @return the number of bytes written.
*/
public static
int writeLong(final byte[] buffer, long value, final boolean optimizePositive, int position) {
if (!optimizePositive) { if (!optimizePositive) {
value = value << 1 ^ value >> 63; value = value << 1 ^ value >> 63;
} }
int position = 0;
if (value >>> 7 == 0) { if (value >>> 7 == 0) {
buffer[position++] = (byte) value; buffer[position++] = (byte) value;
return 1; return 1;
@ -358,62 +392,80 @@ class OptimizeUtilsByteArray {
return 9; return 9;
} }
/**
* look at buffer, and see if we can read the length of the long off of it (from the reader index).
*
* @return 0 if we could not read anything, >0 for the number of bytes for the long on the buffer
*/
public static public static
boolean canReadLong(byte[] buffer) { boolean canReadLong(byte[] buffer) {
int position = 0;
return canReadLong(buffer, position);
}
/**
* FROM KRYO
* <p>
* look at buffer, and see if we can read the length of the long off of it (from the reader index).
*
* @param position where in the buffer to start reading
* @return 0 if we could not read anything, >0 for the number of bytes for the long on the buffer
*/
private static
boolean canReadLong(final byte[] buffer, int position) {
int limit = buffer.length; int limit = buffer.length;
if (limit >= 9) { if (limit >= 9) {
return true; return true;
} }
int p = 0; if ((buffer[position++] & 0x80) == 0) {
if ((buffer[p++] & 0x80) == 0) {
return true; return true;
} }
if (p == limit) { if (position == limit) {
return false; return false;
} }
if ((buffer[p++] & 0x80) == 0) { if ((buffer[position++] & 0x80) == 0) {
return true; return true;
} }
if (p == limit) { if (position == limit) {
return false; return false;
} }
if ((buffer[p++] & 0x80) == 0) { if ((buffer[position++] & 0x80) == 0) {
return true; return true;
} }
if (p == limit) { if (position == limit) {
return false; return false;
} }
if ((buffer[p++] & 0x80) == 0) { if ((buffer[position++] & 0x80) == 0) {
return true; return true;
} }
if (p == limit) { if (position == limit) {
return false; return false;
} }
if ((buffer[p++] & 0x80) == 0) { if ((buffer[position++] & 0x80) == 0) {
return true; return true;
} }
if (p == limit) { if (position == limit) {
return false; return false;
} }
if ((buffer[p++] & 0x80) == 0) { if ((buffer[position++] & 0x80) == 0) {
return true; return true;
} }
if (p == limit) { if (position == limit) {
return false; return false;
} }
if ((buffer[p++] & 0x80) == 0) { if ((buffer[position++] & 0x80) == 0) {
return true; return true;
} }
if (p == limit) { if (position == limit) {
return false; return false;
} }
//noinspection SimplifiableIfStatement //noinspection SimplifiableIfStatement
if ((buffer[p++] & 0x80) == 0) { if ((buffer[position++] & 0x80) == 0) {
return true; return true;
} }
return p != limit; return position != limit;
} }

View File

@ -36,6 +36,7 @@ package dorkbox.util.bytes;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
@SuppressWarnings({"Duplicates", "NumericCastThatLosesPrecision", "UnusedAssignment", "IntegerMultiplicationImplicitCastToLong", "unused"})
public public
class OptimizeUtilsByteBuf { class OptimizeUtilsByteBuf {
@ -177,7 +178,7 @@ class OptimizeUtilsByteBuf {
// long // long
/** /**
* Returns the number of bytes that would be written with {@link #writeLong(long, boolean)}. * Returns the number of bytes that would be written with {@link #writeLong(ByteBuf, long, boolean)}.
* *
* @param optimizePositive * @param optimizePositive
* true if you want to optimize the number of bytes needed to write the length value * true if you want to optimize the number of bytes needed to write the length value