This is an automated email from the ASF dual-hosted git repository.
dsmiley pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new c78158b9811 SlowCompositeReaderWrapper: fix index sort and hasBlocks
(#4825)
c78158b9811 is described below
commit c78158b9811417543c4f7cdf99faed8d25c5943b
Author: David Smiley <[email protected]>
AuthorDate: Sun Sep 6 00:05:39 2026 -0400
SlowCompositeReaderWrapper: fix index sort and hasBlocks (#4825)
minor fixes; not seen in a realistic setting.
---
...owCompositeReaderWrapper-sort-hasblocks-fix.yml | 6 +++
.../solr/index/SlowCompositeReaderWrapper.java | 43 +++++++++++++---------
2 files changed, 31 insertions(+), 18 deletions(-)
diff --git
a/changelog/unreleased/SlowCompositeReaderWrapper-sort-hasblocks-fix.yml
b/changelog/unreleased/SlowCompositeReaderWrapper-sort-hasblocks-fix.yml
new file mode 100644
index 00000000000..c1f98f684cc
--- /dev/null
+++ b/changelog/unreleased/SlowCompositeReaderWrapper-sort-hasblocks-fix.yml
@@ -0,0 +1,6 @@
+# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
+title: SlowCompositeReaderWrapper no longer misreports the index sort and
hasBlocks of a multi-segment composite view; both were previously taken from
the first segment only, which is wrong whenever there is more than one segment.
+type: fixed # added, changed, fixed, deprecated, removed, dependency_update,
security, other
+authors:
+ - name: David Smiley
+links:
diff --git
a/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
index a242ce849a3..3b20a178107 100644
--- a/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
+++ b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
@@ -51,6 +51,7 @@ import org.apache.lucene.index.TermVectors;
import org.apache.lucene.index.Terms;
import org.apache.lucene.search.AcceptDocs;
import org.apache.lucene.search.KnnCollector;
+import org.apache.lucene.search.Sort;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.Version;
import org.apache.lucene.util.packed.PackedInts;
@@ -84,38 +85,44 @@ public final class SlowCompositeReaderWrapper extends
LeafReader {
* This method is sugar for getting an {@link LeafReader} from an {@link
IndexReader} of any kind.
* If the reader is already atomic, it is returned unchanged, otherwise
wrapped by this class.
*/
- public static LeafReader wrap(IndexReader reader) throws IOException {
- if (reader instanceof CompositeReader) {
- return new SlowCompositeReaderWrapper((CompositeReader) reader);
+ public static LeafReader wrap(IndexReader reader) {
+ if (reader instanceof CompositeReader compositeReader) {
+ return new SlowCompositeReaderWrapper(compositeReader);
} else {
assert reader instanceof LeafReader;
return (LeafReader) reader;
}
}
- SlowCompositeReaderWrapper(CompositeReader reader) throws IOException {
+ SlowCompositeReaderWrapper(CompositeReader reader) {
in = reader;
in.registerParentReader(this);
- if (reader.leaves().isEmpty()) {
+ List<LeafReaderContext> leaves = reader.leaves();
+ if (leaves.isEmpty()) {
metaData = new LeafMetaData(Version.LATEST.major, Version.LATEST, null,
false);
} else {
Version minVersion = Version.LATEST;
- for (LeafReaderContext leafReaderContext : reader.leaves()) {
- Version leafVersion =
leafReaderContext.reader().getMetaData().minVersion();
- if (leafVersion == null) {
- minVersion = null;
- break;
- } else if (minVersion.onOrAfter(leafVersion)) {
- minVersion = leafVersion;
+ boolean hasBlocks = false;
+ for (LeafReaderContext leafReaderContext : leaves) {
+ LeafMetaData leafMetaData = leafReaderContext.reader().getMetaData();
+ if (minVersion != null) {
+ Version leafVersion = leafMetaData.minVersion();
+ if (leafVersion == null) {
+ minVersion = null;
+ } else if (minVersion.onOrAfter(leafVersion)) {
+ minVersion = leafVersion;
+ }
}
+ // A block (child/nested docs), once written, is never split across
segments, so the
+ // composite view has blocks as soon as any one of its segments does.
+ hasBlocks |= leafMetaData.hasBlocks();
}
- LeafMetaData leafMetaData =
reader.leaves().get(0).reader().getMetaData();
+ LeafMetaData firstLeafMetaData =
leaves.getFirst().reader().getMetaData();
+ // The composite view is only actually sorted in the trivial single-leaf
case: concatenating
+ // multiple segments does not preserve their shared per-segment sort as
a sort of the whole.
+ Sort sort = leaves.size() == 1 ? firstLeafMetaData.sort() : null;
metaData =
- new LeafMetaData(
- leafMetaData.createdVersionMajor(),
- minVersion,
- leafMetaData.sort(),
- leafMetaData.hasBlocks());
+ new LeafMetaData(firstLeafMetaData.createdVersionMajor(),
minVersion, sort, hasBlocks);
}
fieldInfos = FieldInfos.getMergedFieldInfos(in);
}