LUCENE-10113: Use VarHandles to access int/long/short types in byte arrays (e.g. ByteArrayDataInput) (#308)

Co-authored-by: Robert Muir <rmuir@apache.org>
This commit is contained in:
Uwe Schindler 2021-09-20 15:37:33 +02:00 committed by GitHub
parent 4bcd64c5ed
commit c57d6e5f8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 213 additions and 158 deletions

View File

@ -271,6 +271,11 @@ Improvements
The getPath API now throws an IAE instead of returning null if the ordinal is out of bounds. The getPath API now throws an IAE instead of returning null if the ordinal is out of bounds.
(Gautam Worah, Mike McCandless) (Gautam Worah, Mike McCandless)
* LUCENE-10113: Use VarHandles to access int/long/short primitive types in byte arrays.
This improves readability and performance of encoding/decoding of primitives to index
file format in input/output classes like DataInput / DataOutput and codecs.
(Uwe Schindler, Robert Muir)
Bug fixes Bug fixes
* LUCENE-10070 Skip deleted docs when accumulating facet counts for all docs. (Ankur Goel, Greg Miller) * LUCENE-10070 Skip deleted docs when accumulating facet counts for all docs. (Ankur Goel, Greg Miller)

View File

@ -28,6 +28,7 @@ import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute; import org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute; import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
import org.apache.lucene.util.BitUtil;
/** /**
* Generate min hash tokens from an incoming stream of tokens. The incoming tokens would typically * Generate min hash tokens from an incoming stream of tokens. The incoming tokens would typically
@ -97,10 +98,7 @@ public class MinHashFilter extends TokenFilter {
static byte[] getBytes(int i) { static byte[] getBytes(int i) {
byte[] answer = new byte[4]; byte[] answer = new byte[4];
answer[3] = (byte) (i); BitUtil.VH_BE_INT.set(answer, 0, i);
answer[2] = (byte) (i >> 8);
answer[1] = (byte) (i >> 16);
answer[0] = (byte) (i >> 24);
return answer; return answer;
} }

View File

@ -16,6 +16,8 @@
*/ */
package org.apache.lucene.analysis.payloads; package org.apache.lucene.analysis.payloads;
import org.apache.lucene.util.BitUtil;
/** Utility methods for encoding payloads. */ /** Utility methods for encoding payloads. */
public class PayloadHelper { public class PayloadHelper {
@ -24,7 +26,8 @@ public class PayloadHelper {
} }
public static byte[] encodeFloat(float payload, byte[] data, int offset) { public static byte[] encodeFloat(float payload, byte[] data, int offset) {
return encodeInt(Float.floatToIntBits(payload), data, offset); BitUtil.VH_BE_FLOAT.set(data, offset, payload);
return data;
} }
public static byte[] encodeInt(int payload) { public static byte[] encodeInt(int payload) {
@ -32,10 +35,7 @@ public class PayloadHelper {
} }
public static byte[] encodeInt(int payload, byte[] data, int offset) { public static byte[] encodeInt(int payload, byte[] data, int offset) {
data[offset] = (byte) (payload >> 24); BitUtil.VH_BE_INT.set(data, offset, payload);
data[offset + 1] = (byte) (payload >> 16);
data[offset + 2] = (byte) (payload >> 8);
data[offset + 3] = (byte) payload;
return data; return data;
} }
@ -58,14 +58,10 @@ public class PayloadHelper {
* @see #encodeFloat(float) * @see #encodeFloat(float)
*/ */
public static final float decodeFloat(byte[] bytes, int offset) { public static final float decodeFloat(byte[] bytes, int offset) {
return (float) BitUtil.VH_BE_FLOAT.get(bytes, offset);
return Float.intBitsToFloat(decodeInt(bytes, offset));
} }
public static final int decodeInt(byte[] bytes, int offset) { public static final int decodeInt(byte[] bytes, int offset) {
return ((bytes[offset] & 0xFF) << 24) return (int) BitUtil.VH_BE_INT.get(bytes, offset);
| ((bytes[offset + 1] & 0xFF) << 16)
| ((bytes[offset + 2] & 0xFF) << 8)
| (bytes[offset + 3] & 0xFF);
} }
} }

View File

@ -19,6 +19,7 @@ package org.apache.lucene.index;
import java.io.IOException; import java.io.IOException;
import org.apache.lucene.store.DataInput; import org.apache.lucene.store.DataInput;
import org.apache.lucene.store.DataOutput; import org.apache.lucene.store.DataOutput;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.ByteBlockPool; import org.apache.lucene.util.ByteBlockPool;
/* IndexInput that knows how to read the byte slices written /* IndexInput that knows how to read the byte slices written
@ -94,11 +95,7 @@ final class ByteSliceReader extends DataInput {
public void nextSlice() { public void nextSlice() {
// Skip to our next slice // Skip to our next slice
final int nextIndex = final int nextIndex = (int) BitUtil.VH_BE_INT.get(buffer, limit);
((buffer[limit] & 0xff) << 24)
+ ((buffer[1 + limit] & 0xff) << 16)
+ ((buffer[2 + limit] & 0xff) << 8)
+ (buffer[3 + limit] & 0xff);
level = ByteBlockPool.NEXT_LEVEL_ARRAY[level]; level = ByteBlockPool.NEXT_LEVEL_ARRAY[level];
final int newSize = ByteBlockPool.LEVEL_SIZE_ARRAY[level]; final int newSize = ByteBlockPool.LEVEL_SIZE_ARRAY[level];

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.lucene.store; package org.apache.lucene.store;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
/** /**
@ -81,38 +82,29 @@ public final class ByteArrayDataInput extends DataInput {
@Override @Override
public short readShort() { public short readShort() {
final byte b1 = bytes[pos++]; try {
final byte b2 = bytes[pos++]; return (short) BitUtil.VH_LE_SHORT.get(bytes, pos);
return (short) ((b2 & 0xFF) << 8 | (b1 & 0xFF)); } finally {
pos += Short.BYTES;
}
} }
@Override @Override
public int readInt() { public int readInt() {
final byte b1 = bytes[pos++]; try {
final byte b2 = bytes[pos++]; return (int) BitUtil.VH_LE_INT.get(bytes, pos);
final byte b3 = bytes[pos++]; } finally {
final byte b4 = bytes[pos++]; pos += Integer.BYTES;
return (b4 & 0xFF) << 24 | (b3 & 0xFF) << 16 | (b2 & 0xFF) << 8 | (b1 & 0xFF); }
} }
@Override @Override
public long readLong() { public long readLong() {
final byte b1 = bytes[pos++]; try {
final byte b2 = bytes[pos++]; return (long) BitUtil.VH_LE_LONG.get(bytes, pos);
final byte b3 = bytes[pos++]; } finally {
final byte b4 = bytes[pos++]; pos += Long.BYTES;
final byte b5 = bytes[pos++]; }
final byte b6 = bytes[pos++];
final byte b7 = bytes[pos++];
final byte b8 = bytes[pos++];
return (b8 & 0xFFL) << 56
| (b7 & 0xFFL) << 48
| (b6 & 0xFFL) << 40
| (b5 & 0xFFL) << 32
| (b4 & 0xFFL) << 24
| (b3 & 0xFFL) << 16
| (b2 & 0xFFL) << 8
| (b1 & 0xFFL);
} }
@Override @Override

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.lucene.store; package org.apache.lucene.store;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
/** /**
@ -68,4 +69,25 @@ public class ByteArrayDataOutput extends DataOutput {
System.arraycopy(b, offset, bytes, pos, length); System.arraycopy(b, offset, bytes, pos, length);
pos += length; pos += length;
} }
@Override
public void writeShort(short i) {
assert pos + Short.BYTES <= limit;
BitUtil.VH_LE_SHORT.set(bytes, pos, i);
pos += Short.BYTES;
}
@Override
public void writeInt(int i) {
assert pos + Integer.BYTES <= limit;
BitUtil.VH_LE_INT.set(bytes, pos, i);
pos += Integer.BYTES;
}
@Override
public void writeLong(long i) {
assert pos + Long.BYTES <= limit;
BitUtil.VH_LE_LONG.set(bytes, pos, i);
pos += Long.BYTES;
}
} }

View File

@ -16,8 +16,12 @@
*/ */
package org.apache.lucene.util; // from org.apache.solr.util rev 555343 package org.apache.lucene.util; // from org.apache.solr.util rev 555343
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;
/** /**
* A variety of high efficiency bit twiddling routines. * A variety of high efficiency bit twiddling routines and encoders for primitives.
* *
* @lucene.internal * @lucene.internal
*/ */
@ -25,6 +29,92 @@ public final class BitUtil {
private BitUtil() {} // no instance private BitUtil() {} // no instance
/**
* A {@link VarHandle} to read/write little endian {@code short} from/to a byte array. Shape:
* {@code short vh.get(byte[] arr, int ofs)} and {@code void vh.set(byte[] arr, int ofs, short
* val)}
*/
public static final VarHandle VH_LE_SHORT =
MethodHandles.byteArrayViewVarHandle(short[].class, ByteOrder.LITTLE_ENDIAN);
/**
* A {@link VarHandle} to read/write little endian {@code int} from a byte array. Shape: {@code
* int vh.get(byte[] arr, int ofs)} and {@code void vh.set(byte[] arr, int ofs, int val)}
*/
public static final VarHandle VH_LE_INT =
MethodHandles.byteArrayViewVarHandle(int[].class, ByteOrder.LITTLE_ENDIAN);
/**
* A {@link VarHandle} to read/write little endian {@code long} from a byte array. Shape: {@code
* long vh.get(byte[] arr, int ofs)} and {@code void vh.set(byte[] arr, int ofs, long val)}
*/
public static final VarHandle VH_LE_LONG =
MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN);
/**
* A {@link VarHandle} to read/write little endian {@code float} from a byte array. Shape: {@code
* float vh.get(byte[] arr, int ofs)} and {@code void vh.set(byte[] arr, int ofs, float val)}
*/
public static final VarHandle VH_LE_FLOAT =
MethodHandles.byteArrayViewVarHandle(float[].class, ByteOrder.LITTLE_ENDIAN);
/**
* A {@link VarHandle} to read/write little endian {@code double} from a byte array. Shape: {@code
* double vh.get(byte[] arr, int ofs)} and {@code void vh.set(byte[] arr, int ofs, double val)}
*/
public static final VarHandle VH_LE_DOUBLE =
MethodHandles.byteArrayViewVarHandle(double[].class, ByteOrder.LITTLE_ENDIAN);
/**
* A {@link VarHandle} to read/write big endian {@code short} from a byte array. Shape: {@code
* short vh.get(byte[] arr, int ofs)} and {@code void vh.set(byte[] arr, int ofs, short val)}
*
* @deprecated Better use little endian unless it is needed for backwards compatibility.
*/
@Deprecated
public static final VarHandle VH_BE_SHORT =
MethodHandles.byteArrayViewVarHandle(short[].class, ByteOrder.BIG_ENDIAN);
/**
* A {@link VarHandle} to read/write big endian {@code int} from a byte array. Shape: {@code int
* vh.get(byte[] arr, int ofs)} and {@code void vh.set(byte[] arr, int ofs, int val)}
*
* @deprecated Better use little endian unless it is needed for backwards compatibility.
*/
@Deprecated
public static final VarHandle VH_BE_INT =
MethodHandles.byteArrayViewVarHandle(int[].class, ByteOrder.BIG_ENDIAN);
/**
* A {@link VarHandle} to read/write big endian {@code long} from a byte array. Shape: {@code long
* vh.get(byte[] arr, int ofs)} and {@code void vh.set(byte[] arr, int ofs, long val)}
*
* @deprecated Better use little endian unless it is needed for backwards compatibility.
*/
@Deprecated
public static final VarHandle VH_BE_LONG =
MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN);
/**
* A {@link VarHandle} to read/write big endian {@code float} from a byte array. Shape: {@code
* float vh.get(byte[] arr, int ofs)} and {@code void vh.set(byte[] arr, int ofs, float val)}
*
* @deprecated Better use little endian unless it is needed for backwards compatibility.
*/
@Deprecated
public static final VarHandle VH_BE_FLOAT =
MethodHandles.byteArrayViewVarHandle(float[].class, ByteOrder.BIG_ENDIAN);
/**
* A {@link VarHandle} to read/write big endian {@code double} from a byte array. Shape: {@code
* double vh.get(byte[] arr, int ofs)} and {@code void vh.set(byte[] arr, int ofs, double val)}
*
* @deprecated Better use little endian unless it is needed for backwards compatibility.
*/
@Deprecated
public static final VarHandle VH_BE_DOUBLE =
MethodHandles.byteArrayViewVarHandle(double[].class, ByteOrder.BIG_ENDIAN);
// The pop methods used to rely on bit-manipulation tricks for speed but it // The pop methods used to rely on bit-manipulation tricks for speed but it
// turns out that it is faster to use the Long.bitCount method (which is an // turns out that it is faster to use the Long.bitCount method (which is an
// intrinsic since Java 6u18) in a naive loop, see LUCENE-2221 // intrinsic since Java 6u18) in a naive loop, see LUCENE-2221

View File

@ -141,10 +141,7 @@ public final class NumericUtils {
public static void intToSortableBytes(int value, byte[] result, int offset) { public static void intToSortableBytes(int value, byte[] result, int offset) {
// Flip the sign bit, so negative ints sort before positive ints correctly: // Flip the sign bit, so negative ints sort before positive ints correctly:
value ^= 0x80000000; value ^= 0x80000000;
result[offset] = (byte) (value >> 24); BitUtil.VH_BE_INT.set(result, offset, value);
result[offset + 1] = (byte) (value >> 16);
result[offset + 2] = (byte) (value >> 8);
result[offset + 3] = (byte) value;
} }
/** /**
@ -153,11 +150,7 @@ public final class NumericUtils {
* @see #intToSortableBytes(int, byte[], int) * @see #intToSortableBytes(int, byte[], int)
*/ */
public static int sortableBytesToInt(byte[] encoded, int offset) { public static int sortableBytesToInt(byte[] encoded, int offset) {
int x = int x = (int) BitUtil.VH_BE_INT.get(encoded, offset);
((encoded[offset] & 0xFF) << 24)
| ((encoded[offset + 1] & 0xFF) << 16)
| ((encoded[offset + 2] & 0xFF) << 8)
| (encoded[offset + 3] & 0xFF);
// Re-flip the sign bit to restore the original value: // Re-flip the sign bit to restore the original value:
return x ^ 0x80000000; return x ^ 0x80000000;
} }
@ -171,14 +164,7 @@ public final class NumericUtils {
public static void longToSortableBytes(long value, byte[] result, int offset) { public static void longToSortableBytes(long value, byte[] result, int offset) {
// Flip the sign bit so negative longs sort before positive longs: // Flip the sign bit so negative longs sort before positive longs:
value ^= 0x8000000000000000L; value ^= 0x8000000000000000L;
result[offset] = (byte) (value >> 56); BitUtil.VH_BE_LONG.set(result, offset, value);
result[offset + 1] = (byte) (value >> 48);
result[offset + 2] = (byte) (value >> 40);
result[offset + 3] = (byte) (value >> 32);
result[offset + 4] = (byte) (value >> 24);
result[offset + 5] = (byte) (value >> 16);
result[offset + 6] = (byte) (value >> 8);
result[offset + 7] = (byte) value;
} }
/** /**
@ -187,15 +173,7 @@ public final class NumericUtils {
* @see #longToSortableBytes(long, byte[], int) * @see #longToSortableBytes(long, byte[], int)
*/ */
public static long sortableBytesToLong(byte[] encoded, int offset) { public static long sortableBytesToLong(byte[] encoded, int offset) {
long v = long v = (long) BitUtil.VH_BE_LONG.get(encoded, offset);
((encoded[offset] & 0xFFL) << 56)
| ((encoded[offset + 1] & 0xFFL) << 48)
| ((encoded[offset + 2] & 0xFFL) << 40)
| ((encoded[offset + 3] & 0xFFL) << 32)
| ((encoded[offset + 4] & 0xFFL) << 24)
| ((encoded[offset + 5] & 0xFFL) << 16)
| ((encoded[offset + 6] & 0xFFL) << 8)
| (encoded[offset + 7] & 0xFFL);
// Flip the sign bit back // Flip the sign bit back
v ^= 0x8000000000000000L; v ^= 0x8000000000000000L;
return v; return v;

View File

@ -164,11 +164,7 @@ public abstract class StringHelper {
for (int i = offset; i < roundedEnd; i += 4) { for (int i = offset; i < roundedEnd; i += 4) {
// little endian load order // little endian load order
int k1 = int k1 = (int) BitUtil.VH_LE_INT.get(data, i);
(data[i] & 0xff)
| ((data[i + 1] & 0xff) << 8)
| ((data[i + 2] & 0xff) << 16)
| (data[i + 3] << 24);
k1 *= c1; k1 *= c1;
k1 = Integer.rotateLeft(k1, 15); k1 = Integer.rotateLeft(k1, 15);
k1 *= c2; k1 *= c2;

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.lucene.util.bkd; package org.apache.lucene.util.bkd;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
/** /**
@ -85,10 +86,7 @@ public final class HeapPointReader implements PointReader {
@Override @Override
public int docID() { public int docID() {
int position = packedValueDocID.offset + packedValueLength; int position = packedValueDocID.offset + packedValueLength;
return ((packedValueDocID.bytes[position] & 0xFF) << 24) return (int) BitUtil.VH_BE_INT.get(packedValueDocID.bytes, position);
| ((packedValueDocID.bytes[++position] & 0xFF) << 16)
| ((packedValueDocID.bytes[++position] & 0xFF) << 8)
| (packedValueDocID.bytes[++position] & 0xFF);
} }
@Override @Override

View File

@ -17,6 +17,7 @@
package org.apache.lucene.util.bkd; package org.apache.lucene.util.bkd;
import java.util.Arrays; import java.util.Arrays;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
/** /**
@ -67,10 +68,7 @@ public final class HeapPointWriter implements PointWriter {
System.arraycopy( System.arraycopy(
packedValue, 0, block, nextWrite * config.bytesPerDoc, config.packedBytesLength); packedValue, 0, block, nextWrite * config.bytesPerDoc, config.packedBytesLength);
int position = nextWrite * config.bytesPerDoc + config.packedBytesLength; int position = nextWrite * config.bytesPerDoc + config.packedBytesLength;
block[position] = (byte) (docID >> 24); BitUtil.VH_BE_INT.set(block, position, docID);
block[++position] = (byte) (docID >> 16);
block[++position] = (byte) (docID >> 8);
block[++position] = (byte) (docID >> 0);
nextWrite++; nextWrite++;
} }

View File

@ -23,6 +23,7 @@ import org.apache.lucene.store.ChecksumIndexInput;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IOContext;
import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.IndexInput;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
/** /**
@ -180,10 +181,7 @@ public final class OfflinePointReader implements PointReader {
@Override @Override
public int docID() { public int docID() {
int position = packedValueDocID.offset + packedValueLength; int position = packedValueDocID.offset + packedValueLength;
return ((packedValueDocID.bytes[position] & 0xFF) << 24) return (int) BitUtil.VH_BE_INT.get(packedValueDocID.bytes, position);
| ((packedValueDocID.bytes[++position] & 0xFF) << 16)
| ((packedValueDocID.bytes[++position] & 0xFF) << 8)
| (packedValueDocID.bytes[++position] & 0xFF);
} }
@Override @Override

View File

@ -16,6 +16,8 @@
*/ */
package org.apache.lucene.store; package org.apache.lucene.store;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.LuceneTestCase;
public class TestByteArrayDataInput extends LuceneTestCase { public class TestByteArrayDataInput extends LuceneTestCase {
@ -24,9 +26,39 @@ public class TestByteArrayDataInput extends LuceneTestCase {
byte[] bytes = new byte[] {1, 65}; byte[] bytes = new byte[] {1, 65};
ByteArrayDataInput in = new ByteArrayDataInput(bytes); ByteArrayDataInput in = new ByteArrayDataInput(bytes);
assertEquals("A", in.readString()); assertEquals("A", in.readString());
assertTrue(in.eof());
bytes = new byte[] {1, 1, 65}; bytes = new byte[] {1, 1, 65};
in.reset(bytes, 1, 2); in.reset(bytes, 1, 2);
assertEquals("A", in.readString()); assertEquals("A", in.readString());
assertTrue(in.eof());
}
public void testDatatypes() throws Exception {
// write some primitives using ByteArrayDataOutput:
final byte[] bytes = new byte[32];
final ByteArrayDataOutput out = new ByteArrayDataOutput(bytes);
out.writeByte((byte) 43);
out.writeShort((short) 12345);
out.writeInt(1234567890);
out.writeLong(1234567890123456789L);
final int size = out.getPosition();
assertEquals(15, size);
// read the primitives using ByteBuffer to ensure encoding in byte array is LE:
final ByteBuffer buf = ByteBuffer.wrap(bytes, 0, size).order(ByteOrder.LITTLE_ENDIAN);
assertEquals(43, buf.get());
assertEquals(12345, buf.getShort());
assertEquals(1234567890, buf.getInt());
assertEquals(1234567890123456789L, buf.getLong());
assertEquals(0, buf.remaining());
// read the primitives using ByteArrayDataInput:
final ByteArrayDataInput in = new ByteArrayDataInput(bytes, 0, size);
assertEquals(43, in.readByte());
assertEquals(12345, in.readShort());
assertEquals(1234567890, in.readInt());
assertEquals(1234567890123456789L, in.readLong());
assertTrue(in.eof());
} }
} }

View File

@ -39,6 +39,7 @@ import org.apache.lucene.facet.taxonomy.TaxonomyWriter;
import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.IndexableFieldType; import org.apache.lucene.index.IndexableFieldType;
import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.IntsRef; import org.apache.lucene.util.IntsRef;
import org.apache.lucene.util.IntsRefBuilder; import org.apache.lucene.util.IntsRefBuilder;
@ -492,10 +493,8 @@ public class FacetsConfig {
bytes = ArrayUtil.grow(bytes, upto + 4); bytes = ArrayUtil.grow(bytes, upto + 4);
} }
// big-endian: // big-endian:
bytes[upto++] = (byte) (ordinal >> 24); BitUtil.VH_BE_INT.set(bytes, upto, ordinal);
bytes[upto++] = (byte) (ordinal >> 16); upto += 4;
bytes[upto++] = (byte) (ordinal >> 8);
bytes[upto++] = (byte) ordinal;
if (upto + field.assoc.length > bytes.length) { if (upto + field.assoc.length > bytes.length) {
bytes = ArrayUtil.grow(bytes, upto + field.assoc.length); bytes = ArrayUtil.grow(bytes, upto + field.assoc.length);
} }

View File

@ -18,6 +18,7 @@ package org.apache.lucene.facet.taxonomy;
import java.util.Arrays; import java.util.Arrays;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
/** /**
@ -37,19 +38,13 @@ public class IntAssociationFacetField extends AssociationFacetField {
public static BytesRef intToBytesRef(int v) { public static BytesRef intToBytesRef(int v) {
byte[] bytes = new byte[4]; byte[] bytes = new byte[4];
// big-endian: // big-endian:
bytes[0] = (byte) (v >> 24); BitUtil.VH_BE_INT.set(bytes, 0, v);
bytes[1] = (byte) (v >> 16);
bytes[2] = (byte) (v >> 8);
bytes[3] = (byte) v;
return new BytesRef(bytes); return new BytesRef(bytes);
} }
/** Decodes a previously encoded {@code int}. */ /** Decodes a previously encoded {@code int}. */
public static int bytesRefToInt(BytesRef b) { public static int bytesRefToInt(BytesRef b) {
return ((b.bytes[b.offset] & 0xFF) << 24) return (int) BitUtil.VH_BE_INT.get(b.bytes, b.offset);
| ((b.bytes[b.offset + 1] & 0xFF) << 16)
| ((b.bytes[b.offset + 2] & 0xFF) << 8)
| (b.bytes[b.offset + 3] & 0xFF);
} }
@Override @Override

View File

@ -23,6 +23,7 @@ import org.apache.lucene.facet.FacetsCollector.MatchingDocs;
import org.apache.lucene.facet.FacetsConfig; import org.apache.lucene.facet.FacetsConfig;
import org.apache.lucene.index.BinaryDocValues; import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
/** /**
@ -71,19 +72,11 @@ public class TaxonomyFacetSumFloatAssociations extends FloatTaxonomyFacets {
int end = bytesRef.offset + bytesRef.length; int end = bytesRef.offset + bytesRef.length;
int offset = bytesRef.offset; int offset = bytesRef.offset;
while (offset < end) { while (offset < end) {
int ord = int ord = (int) BitUtil.VH_BE_INT.get(bytes, offset);
((bytes[offset] & 0xFF) << 24)
| ((bytes[offset + 1] & 0xFF) << 16)
| ((bytes[offset + 2] & 0xFF) << 8)
| (bytes[offset + 3] & 0xFF);
offset += 4; offset += 4;
int value = float value = (float) BitUtil.VH_BE_FLOAT.get(bytes, offset);
((bytes[offset] & 0xFF) << 24)
| ((bytes[offset + 1] & 0xFF) << 16)
| ((bytes[offset + 2] & 0xFF) << 8)
| (bytes[offset + 3] & 0xFF);
offset += 4; offset += 4;
values[ord] += Float.intBitsToFloat(value); values[ord] += value;
} }
} }
} }

View File

@ -23,6 +23,7 @@ import org.apache.lucene.facet.FacetsCollector.MatchingDocs;
import org.apache.lucene.facet.FacetsConfig; import org.apache.lucene.facet.FacetsConfig;
import org.apache.lucene.index.BinaryDocValues; import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
/** /**
@ -71,17 +72,9 @@ public class TaxonomyFacetSumIntAssociations extends IntTaxonomyFacets {
int end = bytesRef.offset + bytesRef.length; int end = bytesRef.offset + bytesRef.length;
int offset = bytesRef.offset; int offset = bytesRef.offset;
while (offset < end) { while (offset < end) {
int ord = int ord = (int) BitUtil.VH_BE_INT.get(bytes, offset);
((bytes[offset] & 0xFF) << 24)
| ((bytes[offset + 1] & 0xFF) << 16)
| ((bytes[offset + 2] & 0xFF) << 8)
| (bytes[offset + 3] & 0xFF);
offset += 4; offset += 4;
int value = int value = (int) BitUtil.VH_BE_INT.get(bytes, offset);
((bytes[offset] & 0xFF) << 24)
| ((bytes[offset + 1] & 0xFF) << 16)
| ((bytes[offset + 2] & 0xFF) << 8)
| (bytes[offset + 3] & 0xFF);
offset += 4; offset += 4;
increment(ord, value); increment(ord, value);
} }

View File

@ -21,6 +21,7 @@ import java.util.EnumMap;
import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery.MatchOperation; import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery.MatchOperation;
import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery.PayloadType; import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery.PayloadType;
import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
/** /**
@ -153,10 +154,7 @@ public class PayloadMatcherFactory {
} }
private int decodeInt(byte[] bytes, int offset) { private int decodeInt(byte[] bytes, int offset) {
return ((bytes[offset] & 0xFF) << 24) return (int) BitUtil.VH_BE_INT.get(bytes, offset);
| ((bytes[offset + 1] & 0xFF) << 16)
| ((bytes[offset + 2] & 0xFF) << 8)
| (bytes[offset + 3] & 0xFF);
} }
protected abstract boolean intCompare(int val, int threshold); protected abstract boolean intCompare(int val, int threshold);
@ -203,11 +201,7 @@ public class PayloadMatcherFactory {
} }
private float decodeFloat(byte[] bytes, int offset) { private float decodeFloat(byte[] bytes, int offset) {
return Float.intBitsToFloat( return (float) BitUtil.VH_BE_FLOAT.get(bytes, offset);
((bytes[offset] & 0xFF) << 24)
| ((bytes[offset + 1] & 0xFF) << 16)
| ((bytes[offset + 2] & 0xFF) << 8)
| (bytes[offset + 3] & 0xFF));
} }
protected abstract boolean floatCompare(float val, float threshold); protected abstract boolean floatCompare(float val, float threshold);

View File

@ -32,6 +32,7 @@ import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.store.ByteArrayDataInput; import org.apache.lucene.store.ByteArrayDataInput;
import org.apache.lucene.store.ByteBuffersDataOutput; import org.apache.lucene.store.ByteBuffersDataOutput;
import org.apache.lucene.store.DataInput; import org.apache.lucene.store.DataInput;
import org.apache.lucene.util.BitUtil;
/** /**
* This is a stupid yet functional transaction log: it never fsync's, never prunes, it's * This is a stupid yet functional transaction log: it never fsync's, never prunes, it's
@ -91,10 +92,7 @@ class SimpleTransLog implements Closeable {
byte[] bytes = buffer.toArrayCopy(); byte[] bytes = buffer.toArrayCopy();
buffer.reset(); buffer.reset();
intBuffer[0] = (byte) (len >> 24); BitUtil.VH_BE_INT.set(intBuffer, 0, len);
intBuffer[1] = (byte) (len >> 16);
intBuffer[2] = (byte) (len >> 8);
intBuffer[3] = (byte) len;
intByteBuffer.limit(4); intByteBuffer.limit(4);
intByteBuffer.position(0); intByteBuffer.position(0);
@ -140,11 +138,7 @@ class SimpleTransLog implements Closeable {
intByteBuffer.limit(4); intByteBuffer.limit(4);
readBytesFromChannel(pos, intByteBuffer); readBytesFromChannel(pos, intByteBuffer);
pos += 4; pos += 4;
int len = int len = (int) BitUtil.VH_BE_INT.get(intBuffer, 0);
((intBuffer[0] & 0xff) << 24)
| (intBuffer[1] & 0xff) << 16
| (intBuffer[2] & 0xff) << 8
| (intBuffer[3] & 0xff);
byte[] bytes = new byte[len]; byte[] bytes = new byte[len];
readBytesFromChannel(pos, ByteBuffer.wrap(bytes)); readBytesFromChannel(pos, ByteBuffer.wrap(bytes));

View File

@ -26,6 +26,7 @@ import org.apache.lucene.codecs.lucene90.blocktree.Lucene90BlockTreeTermsWriter;
import org.apache.lucene.index.SegmentReadState; import org.apache.lucene.index.SegmentReadState;
import org.apache.lucene.index.SegmentWriteState; import org.apache.lucene.index.SegmentWriteState;
import org.apache.lucene.search.LiveFieldValues; import org.apache.lucene.search.LiveFieldValues;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.IOUtils;
@ -108,14 +109,7 @@ public class IDVersionPostingsFormat extends PostingsFormat {
} }
public static long bytesToLong(BytesRef bytes) { public static long bytesToLong(BytesRef bytes) {
return ((bytes.bytes[bytes.offset] & 0xFFL) << 56) return (long) BitUtil.VH_BE_LONG.get(bytes.bytes, bytes.offset);
| ((bytes.bytes[bytes.offset + 1] & 0xFFL) << 48)
| ((bytes.bytes[bytes.offset + 2] & 0xFFL) << 40)
| ((bytes.bytes[bytes.offset + 3] & 0xFFL) << 32)
| ((bytes.bytes[bytes.offset + 4] & 0xFFL) << 24)
| ((bytes.bytes[bytes.offset + 5] & 0xFFL) << 16)
| ((bytes.bytes[bytes.offset + 6] & 0xFFL) << 8)
| (bytes.bytes[bytes.offset + 7] & 0xFFL);
} }
public static void longToBytes(long v, BytesRef bytes) { public static void longToBytes(long v, BytesRef bytes) {
@ -131,14 +125,7 @@ public class IDVersionPostingsFormat extends PostingsFormat {
} }
bytes.offset = 0; bytes.offset = 0;
bytes.length = 8; bytes.length = 8;
bytes.bytes[0] = (byte) (v >> 56); BitUtil.VH_BE_LONG.set(bytes.bytes, 0, v);
bytes.bytes[1] = (byte) (v >> 48);
bytes.bytes[2] = (byte) (v >> 40);
bytes.bytes[3] = (byte) (v >> 32);
bytes.bytes[4] = (byte) (v >> 24);
bytes.bytes[5] = (byte) (v >> 16);
bytes.bytes[6] = (byte) (v >> 8);
bytes.bytes[7] = (byte) v;
assert bytesToLong(bytes) == v : bytesToLong(bytes) + " vs " + v + " bytes=" + bytes; assert bytesToLong(bytes) == v : bytesToLong(bytes) + " vs " + v + " bytes=" + bytes;
} }
} }

View File

@ -26,6 +26,7 @@ import org.apache.lucene.index.PointValues;
import org.apache.lucene.search.PointInSetQuery; import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.PointRangeQuery; import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
/** /**
@ -190,12 +191,11 @@ public final class HalfFloatPoint extends Field {
static void shortToSortableBytes(short value, byte[] result, int offset) { static void shortToSortableBytes(short value, byte[] result, int offset) {
// Flip the sign bit, so negative shorts sort before positive shorts correctly: // Flip the sign bit, so negative shorts sort before positive shorts correctly:
value ^= 0x8000; value ^= 0x8000;
result[offset] = (byte) (value >> 8); BitUtil.VH_BE_SHORT.set(result, offset, value);
result[offset + 1] = (byte) value;
} }
static short sortableBytesToShort(byte[] encoded, int offset) { static short sortableBytesToShort(byte[] encoded, int offset) {
short x = (short) (((encoded[offset] & 0xFF) << 8) | (encoded[offset + 1] & 0xFF)); short x = (short) BitUtil.VH_BE_SHORT.get(encoded, offset);
// Re-flip the sign bit to restore the original value: // Re-flip the sign bit to restore the original value:
return (short) (x ^ 0x8000); return (short) (x ^ 0x8000);
} }