Skip to content

Commit 3f0a6e6

Browse files
committed
GH-5442 Optimize Varint by replacing multiple put calls with putShort/putInt
1 parent c04a0ae commit 3f0a6e6

File tree

1 file changed

+41
-15
lines changed
  • core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb

1 file changed

+41
-15
lines changed

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/Varint.java

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
package org.eclipse.rdf4j.sail.lmdb;
1212

1313
import java.nio.ByteBuffer;
14+
import java.nio.ByteOrder;
1415

1516
/**
1617
* Encodes and decodes unsigned values using variable-length encoding.
@@ -89,26 +90,26 @@ private Varint() {
8990
* @param value value to encode
9091
*/
9192
public static void writeUnsigned(final ByteBuffer bb, final long value) {
93+
bb.order(ByteOrder.BIG_ENDIAN);
9294
if (value <= 240) {
9395
bb.put((byte) value);
9496
} else if (value <= 2287) {
95-
bb.put((byte) ((value - 240) / 256 + 241));
96-
bb.put((byte) ((value - 240) % 256));
97+
int v = (int) (value - 240);
98+
bb.putShort((short) (((v >>> 8) + 241) << 8 | (v & 0xFF)));
9799
} else if (value <= 67823) {
100+
int v = (int) (value - 2288);
98101
bb.put((byte) 249);
99-
bb.put((byte) ((value - 2288) / 256));
100-
bb.put((byte) ((value - 2288) % 256));
102+
bb.putShort((short) ((v >>> 8) << 8 | (v & 0xFF)));
101103
} else {
102104
int bytes = descriptor(value) + 1;
103-
bb.put((byte) (250 + (bytes - 3)));
104105
writeSignificantBits(bb, value, bytes);
105106
}
106107
}
107108

108109
/**
109110
* Calculates required length in bytes to encode the given long value using variable-length encoding.
110111
*
111-
* @param value the value value
112+
* @param value the value
112113
* @return length in bytes
113114
*/
114115
public static int calcLengthUnsigned(long value) {
@@ -245,20 +246,19 @@ public static long readListElementUnsigned(ByteBuffer bb, int index) {
245246
* @param values array with values to write
246247
*/
247248
public static void writeListUnsigned(final ByteBuffer bb, final long[] values) {
248-
for (int i = 0; i < values.length; i++) {
249-
final long value = values[i];
249+
bb.order(ByteOrder.BIG_ENDIAN);
250+
for (final long value : values) {
250251
if (value <= 240) {
251252
bb.put((byte) value);
252253
} else if (value <= 2287) {
253-
bb.put((byte) ((value - 240) / 256 + 241));
254-
bb.put((byte) ((value - 240) % 256));
254+
int v = (int) (value - 240);
255+
bb.putShort((short) (((v >>> 8) + 241) << 8 | (v & 0xFF)));
255256
} else if (value <= 67823) {
257+
int v = (int) (value - 2288);
256258
bb.put((byte) 249);
257-
bb.put((byte) ((value - 2288) / 256));
258-
bb.put((byte) ((value - 2288) % 256));
259+
bb.putShort((short) ((v >>> 8) << 8 | (v & 0xFF)));
259260
} else {
260261
int bytes = descriptor(value) + 1;
261-
bb.put((byte) (250 + (bytes - 3)));
262262
writeSignificantBits(bb, value, bytes);
263263
}
264264
}
@@ -297,8 +297,34 @@ public static void readListUnsigned(ByteBuffer bb, int[] indexMap, long[] values
297297
* @param bytes number of significant bytes
298298
*/
299299
private static void writeSignificantBits(ByteBuffer bb, long value, int bytes) {
300-
while (bytes-- > 0) {
301-
bb.put((byte) (0xFF & (value >>> (bytes * 8))));
300+
switch (bytes) {
301+
case 3:
302+
bb.putInt((int) ((((250 << 8) | ((value >>> 16) & 0xFF)) << 16) | (value & 0xFFFF)));
303+
break;
304+
case 4:
305+
bb.put((byte) 251); // 250 + (4 - 3)
306+
bb.putInt((int) (value & 0xFFFFFFFFL));
307+
break;
308+
case 5:
309+
bb.putShort((short) ((252 << 8) | ((value >>> 32) & 0xFF)));
310+
bb.putInt((int) (value & 0xFFFFFFFFL));
311+
break;
312+
case 6:
313+
bb.put((byte) 253);
314+
bb.putShort((short) ((value >>> 32) & 0xFFFF));
315+
bb.putInt((int) (value & 0xFFFFFFFFL));
316+
break;
317+
case 7:
318+
bb.putLong(((254 << 8 | ((value >>> 48) & 0xFF)) << 48) | (((value >>> 32) & 0xFFFF) << 32)
319+
| (value & 0xFFFFFFFFL));
320+
break;
321+
case 8:
322+
bb.put((byte) 255);
323+
bb.putLong(value);
324+
break;
325+
default:
326+
throw new IllegalArgumentException(
327+
"Invalid number of bytes " + bytes + " for value " + value + " (must be 3..8)");
302328
}
303329
}
304330

0 commit comments

Comments
 (0)