|
11 | 11 | package org.eclipse.rdf4j.sail.lmdb;
|
12 | 12 |
|
13 | 13 | import java.nio.ByteBuffer;
|
| 14 | +import java.nio.ByteOrder; |
14 | 15 |
|
15 | 16 | /**
|
16 | 17 | * Encodes and decodes unsigned values using variable-length encoding.
|
@@ -89,26 +90,26 @@ private Varint() {
|
89 | 90 | * @param value value to encode
|
90 | 91 | */
|
91 | 92 | public static void writeUnsigned(final ByteBuffer bb, final long value) {
|
| 93 | + bb.order(ByteOrder.BIG_ENDIAN); |
92 | 94 | if (value <= 240) {
|
93 | 95 | bb.put((byte) value);
|
94 | 96 | } 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))); |
97 | 99 | } else if (value <= 67823) {
|
| 100 | + int v = (int) (value - 2288); |
98 | 101 | 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))); |
101 | 103 | } else {
|
102 | 104 | int bytes = descriptor(value) + 1;
|
103 |
| - bb.put((byte) (250 + (bytes - 3))); |
104 | 105 | writeSignificantBits(bb, value, bytes);
|
105 | 106 | }
|
106 | 107 | }
|
107 | 108 |
|
108 | 109 | /**
|
109 | 110 | * Calculates required length in bytes to encode the given long value using variable-length encoding.
|
110 | 111 | *
|
111 |
| - * @param value the value value |
| 112 | + * @param value the value |
112 | 113 | * @return length in bytes
|
113 | 114 | */
|
114 | 115 | public static int calcLengthUnsigned(long value) {
|
@@ -245,20 +246,19 @@ public static long readListElementUnsigned(ByteBuffer bb, int index) {
|
245 | 246 | * @param values array with values to write
|
246 | 247 | */
|
247 | 248 | 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) { |
250 | 251 | if (value <= 240) {
|
251 | 252 | bb.put((byte) value);
|
252 | 253 | } 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))); |
255 | 256 | } else if (value <= 67823) {
|
| 257 | + int v = (int) (value - 2288); |
256 | 258 | 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))); |
259 | 260 | } else {
|
260 | 261 | int bytes = descriptor(value) + 1;
|
261 |
| - bb.put((byte) (250 + (bytes - 3))); |
262 | 262 | writeSignificantBits(bb, value, bytes);
|
263 | 263 | }
|
264 | 264 | }
|
@@ -297,8 +297,34 @@ public static void readListUnsigned(ByteBuffer bb, int[] indexMap, long[] values
|
297 | 297 | * @param bytes number of significant bytes
|
298 | 298 | */
|
299 | 299 | 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)"); |
302 | 328 | }
|
303 | 329 | }
|
304 | 330 |
|
|
0 commit comments