|
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