From 97af1d240516bec5ce8d42eea934bbcd2a8dfa5e Mon Sep 17 00:00:00 2001 From: "guofeng.my" Date: Mon, 27 Jan 2025 21:18:57 +0800 Subject: [PATCH 1/5] bpv24 --- .../apache/lucene/util/bkd/DocIdsWriter.java | 83 +++++++++++++------ 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java b/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java index b9ea0d9aa08e..e910cd043cdf 100644 --- a/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java +++ b/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java @@ -33,12 +33,14 @@ final class DocIdsWriter { private static final byte CONTINUOUS_IDS = (byte) -2; private static final byte BITSET_IDS = (byte) -1; private static final byte DELTA_BPV_16 = (byte) 16; - private static final byte BPV_24 = (byte) 24; + private static final byte BPV_24 = (byte) -24; private static final byte BPV_32 = (byte) 32; // These signs are legacy, should no longer be used in the writing side. private static final byte LEGACY_DELTA_VINT = (byte) 0; + private static final byte LEGACY_BPV_24 = (byte) 24; private final int[] scratch; + private int[] scratch2; private final LongsRef scratchLongs = new LongsRef(); /** @@ -115,30 +117,24 @@ void writeDocIds(int[] docIds, int start, int count, DataOutput out) throws IOEx if (max <= 0xFFFFFF) { out.writeByte(BPV_24); // write them the same way we are reading them. - int i; - for (i = 0; i < count - 7; i += 8) { - int doc1 = docIds[start + i]; - int doc2 = docIds[start + i + 1]; - int doc3 = docIds[start + i + 2]; - int doc4 = docIds[start + i + 3]; - int doc5 = docIds[start + i + 4]; - int doc6 = docIds[start + i + 5]; - int doc7 = docIds[start + i + 6]; - int doc8 = docIds[start + i + 7]; - long l1 = (doc1 & 0xffffffL) << 40 | (doc2 & 0xffffffL) << 16 | ((doc3 >>> 8) & 0xffffL); - long l2 = - (doc3 & 0xffL) << 56 - | (doc4 & 0xffffffL) << 32 - | (doc5 & 0xffffffL) << 8 - | ((doc6 >> 16) & 0xffL); - long l3 = (doc6 & 0xffffL) << 48 | (doc7 & 0xffffffL) << 24 | (doc8 & 0xffffffL); - out.writeLong(l1); - out.writeLong(l2); - out.writeLong(l3); + final int quarterLen = count >>> 2; + final int quarterLen3 = quarterLen * 3; + for (int i = 0; i < quarterLen3; ++i) { + scratch[i] = docIds[start + i] << 8; } - for (; i < count; ++i) { - out.writeShort((short) (docIds[start + i] >>> 8)); - out.writeByte((byte) docIds[start + i]); + for (int i = 0; i < quarterLen; i++) { + final int longIdx = start + i + quarterLen3; + scratch[i] |= docIds[longIdx] >>> 16; + scratch[i + quarterLen] |= (docIds[longIdx] >>> 8) & 0xFF; + scratch[i + quarterLen * 2] |= docIds[longIdx] & 0xFF; + } + for (int i = 0; i < quarterLen3; ++i) { + out.writeInt(scratch[i]); + } + + final int remainder = count & 0x3; + for (int i = 0; i < remainder; i++) { + out.writeInt(docIds[quarterLen * 4 + i]); } } else { out.writeByte(BPV_32); @@ -204,6 +200,9 @@ void readInts(IndexInput in, int count, int[] docIDs) throws IOException { case LEGACY_DELTA_VINT: readLegacyDeltaVInts(in, count, docIDs); break; + case LEGACY_BPV_24: + readLegacyInts24(in, count, docIDs); + break; default: throw new IOException("Unsupported number of bits per value: " + bpv); } @@ -262,7 +261,26 @@ private static void readDelta16(IndexInput in, int count, int[] docIDs) throws I } } - private static void readInts24(IndexInput in, int count, int[] docIDs) throws IOException { + private void readInts24(IndexInput in, int count, int[] docIDs) throws IOException { + final int quarterLen = count >>> 2; + final int quarterLen3 = quarterLen * 3; + in.readInts(scratch, 0, quarterLen3); + for (int i = 0; i < quarterLen3; ++i) { + docIDs[i] = scratch[i] >>> 8; + } + for (int i = 0; i < quarterLen; i++) { + docIDs[i + quarterLen3] = + ((scratch[i] & 0xFF) << 16) + | ((scratch[i + quarterLen] & 0xFF) << 8) + | (scratch[i + quarterLen * 2] & 0xFF); + } + int remainder = count & 0x3; + if (remainder > 0) { + in.readInts(docIDs, quarterLen << 2, remainder); + } + } + + private static void readLegacyInts24(IndexInput in, int count, int[] docIDs) throws IOException { int i; for (i = 0; i < count - 7; i += 8) { long l1 = in.readLong(); @@ -305,6 +323,9 @@ void readInts(IndexInput in, int count, IntersectVisitor visitor) throws IOExcep case BPV_24: readInts24(in, count, visitor); break; + case LEGACY_BPV_24: + readLegacyInts24(in, count, visitor); + break; case BPV_32: readInts32(in, count, visitor); break; @@ -348,7 +369,17 @@ private void readDelta16(IndexInput in, int count, IntersectVisitor visitor) thr visitor.visit(scratchIntsRef); } - private static void readInts24(IndexInput in, int count, IntersectVisitor visitor) + private void readInts24(IndexInput in, int count, IntersectVisitor visitor) throws IOException { + if (scratch2 == null) { + scratch2 = new int[scratch.length]; + } + readInts24(in, count, scratch2); + scratchIntsRef.ints = scratch2; + scratchIntsRef.length = count; + visitor.visit(scratchIntsRef); + } + + private static void readLegacyInts24(IndexInput in, int count, IntersectVisitor visitor) throws IOException { int i; for (i = 0; i < count - 7; i += 8) { From 617cec7ba91b57fccc78a769115dc3bd457b2c66 Mon Sep 17 00:00:00 2001 From: "guofeng.my" Date: Wed, 5 Feb 2025 15:55:51 +0800 Subject: [PATCH 2/5] only reduce virtual call --- .../apache/lucene/util/bkd/DocIdsWriter.java | 57 +------------------ 1 file changed, 3 insertions(+), 54 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java b/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java index e910cd043cdf..f9a9b592207d 100644 --- a/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java +++ b/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java @@ -33,14 +33,12 @@ final class DocIdsWriter { private static final byte CONTINUOUS_IDS = (byte) -2; private static final byte BITSET_IDS = (byte) -1; private static final byte DELTA_BPV_16 = (byte) 16; - private static final byte BPV_24 = (byte) -24; + private static final byte BPV_24 = (byte) 24; private static final byte BPV_32 = (byte) 32; // These signs are legacy, should no longer be used in the writing side. private static final byte LEGACY_DELTA_VINT = (byte) 0; - private static final byte LEGACY_BPV_24 = (byte) 24; private final int[] scratch; - private int[] scratch2; private final LongsRef scratchLongs = new LongsRef(); /** @@ -200,9 +198,6 @@ void readInts(IndexInput in, int count, int[] docIDs) throws IOException { case LEGACY_DELTA_VINT: readLegacyDeltaVInts(in, count, docIDs); break; - case LEGACY_BPV_24: - readLegacyInts24(in, count, docIDs); - break; default: throw new IOException("Unsupported number of bits per value: " + bpv); } @@ -262,25 +257,6 @@ private static void readDelta16(IndexInput in, int count, int[] docIDs) throws I } private void readInts24(IndexInput in, int count, int[] docIDs) throws IOException { - final int quarterLen = count >>> 2; - final int quarterLen3 = quarterLen * 3; - in.readInts(scratch, 0, quarterLen3); - for (int i = 0; i < quarterLen3; ++i) { - docIDs[i] = scratch[i] >>> 8; - } - for (int i = 0; i < quarterLen; i++) { - docIDs[i + quarterLen3] = - ((scratch[i] & 0xFF) << 16) - | ((scratch[i + quarterLen] & 0xFF) << 8) - | (scratch[i + quarterLen * 2] & 0xFF); - } - int remainder = count & 0x3; - if (remainder > 0) { - in.readInts(docIDs, quarterLen << 2, remainder); - } - } - - private static void readLegacyInts24(IndexInput in, int count, int[] docIDs) throws IOException { int i; for (i = 0; i < count - 7; i += 8) { long l1 = in.readLong(); @@ -323,9 +299,6 @@ void readInts(IndexInput in, int count, IntersectVisitor visitor) throws IOExcep case BPV_24: readInts24(in, count, visitor); break; - case LEGACY_BPV_24: - readLegacyInts24(in, count, visitor); - break; case BPV_32: readInts32(in, count, visitor); break; @@ -370,36 +343,12 @@ private void readDelta16(IndexInput in, int count, IntersectVisitor visitor) thr } private void readInts24(IndexInput in, int count, IntersectVisitor visitor) throws IOException { - if (scratch2 == null) { - scratch2 = new int[scratch.length]; - } - readInts24(in, count, scratch2); - scratchIntsRef.ints = scratch2; + readInts24(in, count, scratch); + scratchIntsRef.ints = scratch; scratchIntsRef.length = count; visitor.visit(scratchIntsRef); } - private static void readLegacyInts24(IndexInput in, int count, IntersectVisitor visitor) - throws IOException { - int i; - for (i = 0; i < count - 7; i += 8) { - long l1 = in.readLong(); - long l2 = in.readLong(); - long l3 = in.readLong(); - visitor.visit((int) (l1 >>> 40)); - visitor.visit((int) (l1 >>> 16) & 0xffffff); - visitor.visit((int) (((l1 & 0xffff) << 8) | (l2 >>> 56))); - visitor.visit((int) (l2 >>> 32) & 0xffffff); - visitor.visit((int) (l2 >>> 8) & 0xffffff); - visitor.visit((int) (((l2 & 0xff) << 16) | (l3 >>> 48))); - visitor.visit((int) (l3 >>> 24) & 0xffffff); - visitor.visit((int) l3 & 0xffffff); - } - for (; i < count; ++i) { - visitor.visit((Short.toUnsignedInt(in.readShort()) << 8) | Byte.toUnsignedInt(in.readByte())); - } - } - private void readInts32(IndexInput in, int count, IntersectVisitor visitor) throws IOException { in.readInts(scratch, 0, count); scratchIntsRef.ints = scratch; From c72f9f4e63f21f3b28c38cecf726a3c291b57116 Mon Sep 17 00:00:00 2001 From: "guofeng.my" Date: Wed, 5 Feb 2025 15:57:14 +0800 Subject: [PATCH 3/5] iter --- .../apache/lucene/util/bkd/DocIdsWriter.java | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java b/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java index f9a9b592207d..805d7079b981 100644 --- a/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java +++ b/lucene/core/src/java/org/apache/lucene/util/bkd/DocIdsWriter.java @@ -115,24 +115,30 @@ void writeDocIds(int[] docIds, int start, int count, DataOutput out) throws IOEx if (max <= 0xFFFFFF) { out.writeByte(BPV_24); // write them the same way we are reading them. - final int quarterLen = count >>> 2; - final int quarterLen3 = quarterLen * 3; - for (int i = 0; i < quarterLen3; ++i) { - scratch[i] = docIds[start + i] << 8; + int i; + for (i = 0; i < count - 7; i += 8) { + int doc1 = docIds[start + i]; + int doc2 = docIds[start + i + 1]; + int doc3 = docIds[start + i + 2]; + int doc4 = docIds[start + i + 3]; + int doc5 = docIds[start + i + 4]; + int doc6 = docIds[start + i + 5]; + int doc7 = docIds[start + i + 6]; + int doc8 = docIds[start + i + 7]; + long l1 = (doc1 & 0xffffffL) << 40 | (doc2 & 0xffffffL) << 16 | ((doc3 >>> 8) & 0xffffL); + long l2 = + (doc3 & 0xffL) << 56 + | (doc4 & 0xffffffL) << 32 + | (doc5 & 0xffffffL) << 8 + | ((doc6 >> 16) & 0xffL); + long l3 = (doc6 & 0xffffL) << 48 | (doc7 & 0xffffffL) << 24 | (doc8 & 0xffffffL); + out.writeLong(l1); + out.writeLong(l2); + out.writeLong(l3); } - for (int i = 0; i < quarterLen; i++) { - final int longIdx = start + i + quarterLen3; - scratch[i] |= docIds[longIdx] >>> 16; - scratch[i + quarterLen] |= (docIds[longIdx] >>> 8) & 0xFF; - scratch[i + quarterLen * 2] |= docIds[longIdx] & 0xFF; - } - for (int i = 0; i < quarterLen3; ++i) { - out.writeInt(scratch[i]); - } - - final int remainder = count & 0x3; - for (int i = 0; i < remainder; i++) { - out.writeInt(docIds[quarterLen * 4 + i]); + for (; i < count; ++i) { + out.writeShort((short) (docIds[start + i] >>> 8)); + out.writeByte((byte) docIds[start + i]); } } else { out.writeByte(BPV_32); @@ -256,7 +262,7 @@ private static void readDelta16(IndexInput in, int count, int[] docIDs) throws I } } - private void readInts24(IndexInput in, int count, int[] docIDs) throws IOException { + private static void readInts24(IndexInput in, int count, int[] docIDs) throws IOException { int i; for (i = 0; i < count - 7; i += 8) { long l1 = in.readLong(); From 2de3ecdcc45c765d6668013a8461b67fe2037915 Mon Sep 17 00:00:00 2001 From: "guofeng.my" Date: Thu, 6 Feb 2025 18:43:34 +0800 Subject: [PATCH 4/5] add CHANGES --- lucene/CHANGES.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index b36a48c2fd00..16f9e5394bf9 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -69,6 +69,8 @@ Improvements individual and bulk data retrieval overloads; avoid double buffering with slices. (Chris Hegarty) +* GITHUB#14176: Reduce virtual calls when visiting bpv24-encoded doc ids in BKD leaves. (Guo Feng) + Optimizations --------------------- From 41bfd86f231228aae7940a583beffc83f11489ec Mon Sep 17 00:00:00 2001 From: "guofeng.my" Date: Sat, 8 Feb 2025 16:21:10 +0800 Subject: [PATCH 5/5] move CHANGES entry to Optimizations --- lucene/CHANGES.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 1757658dd924..79fa1698cc30 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -78,8 +78,6 @@ Improvements * GITHUB#14154: Add UnwrappingReuseStrategy for AnalyzerWrapper that consults the wrapped analyzer's strategy to decide if components can be reused or need to be updated. (Mayya Sharipova) - -* GITHUB#14176: Reduce when visiting bpv24-encoded doc ids in BKD leaves. (Guo Feng) Optimizations @@ -95,6 +93,8 @@ Optimizations # GITHUB#14169: Optimize ContextQuery with big number of contexts. (Mayya Sharipova) +* GITHUB#14176: Reduce when visiting bpv24-encoded doc ids in BKD leaves. (Guo Feng) + Bug Fixes ---------------------