This is an automated email from the ASF dual-hosted git repository.

cpoerschke pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_9x by this push:
     new 58a280607f6 SOLR-17636: make Lucene's BPReorderingMergePolicy 
configurable in Solr (#2641)
58a280607f6 is described below

commit 58a280607f6f1ed0ecadcd3bd7c2ff427340bd5e
Author: Christine Poerschke <cpoersc...@apache.org>
AuthorDate: Wed Apr 16 10:05:42 2025 +0100

    SOLR-17636: make Lucene's BPReorderingMergePolicy configurable in Solr 
(#2641)
    
    (cherry picked from commit 57de0e8dece2f333a624b6498d139af31d00038c)
---
 .../solr/index/BPReorderingMergePolicyFactory.java | 53 ++++++++++++++++++
 .../apache/solr/index/MergePolicyFactoryArgs.java  |  2 +-
 .../solr/index/WrapperMergePolicyFactory.java      |  6 +-
 .../solrconfig-bpreorderingmergepolicyfactory.xml  | 64 ++++++++++++++++++++++
 .../apache/solr/update/SolrIndexConfigTest.java    | 20 +++++++
 5 files changed, 141 insertions(+), 4 deletions(-)

diff --git 
a/solr/core/src/java/org/apache/solr/index/BPReorderingMergePolicyFactory.java 
b/solr/core/src/java/org/apache/solr/index/BPReorderingMergePolicyFactory.java
new file mode 100644
index 00000000000..5a5113d681b
--- /dev/null
+++ 
b/solr/core/src/java/org/apache/solr/index/BPReorderingMergePolicyFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.index;
+
+import java.util.Set;
+import org.apache.lucene.index.MergePolicy;
+import org.apache.lucene.misc.index.BPIndexReorderer;
+import org.apache.lucene.misc.index.BPReorderingMergePolicy;
+import org.apache.solr.core.SolrResourceLoader;
+import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.util.SolrPluginUtils;
+
+/** A {@link MergePolicyFactory} for {@code BPReorderingMergePolicy} objects. 
*/
+public class BPReorderingMergePolicyFactory extends WrapperMergePolicyFactory {
+
+  private static final String BPR_PREFIX = "bpr.prefix";
+
+  private final BPIndexReorderer reorderer;
+
+  public BPReorderingMergePolicyFactory(
+      SolrResourceLoader resourceLoader, MergePolicyFactoryArgs args, 
IndexSchema schema) {
+    super(resourceLoader, args, schema);
+    reorderer = new BPIndexReorderer();
+    MergePolicyFactoryArgs bprArgs = 
filterWrappedMergePolicyFactoryArgs(BPR_PREFIX);
+    if (bprArgs != null) {
+      final String fields = (String) bprArgs.remove("fields");
+      if (fields != null) {
+        reorderer.setFields(Set.of(fields.split(",")));
+      }
+      SolrPluginUtils.invokeSetters(reorderer, bprArgs.args.entrySet());
+    }
+  }
+
+  @Override
+  protected MergePolicy getMergePolicyInstance(MergePolicy wrappedMP) {
+    final MergePolicy mp = new BPReorderingMergePolicy(wrappedMP, reorderer);
+    return mp;
+  }
+}
diff --git 
a/solr/core/src/java/org/apache/solr/index/MergePolicyFactoryArgs.java 
b/solr/core/src/java/org/apache/solr/index/MergePolicyFactoryArgs.java
index 4cc55a77e58..9923b940953 100644
--- a/solr/core/src/java/org/apache/solr/index/MergePolicyFactoryArgs.java
+++ b/solr/core/src/java/org/apache/solr/index/MergePolicyFactoryArgs.java
@@ -24,7 +24,7 @@ import org.apache.solr.util.SolrPluginUtils;
 
 public class MergePolicyFactoryArgs {
 
-  private final Map<String, Object> args;
+  final Map<String, Object> args;
 
   public MergePolicyFactoryArgs() {
     this.args = new HashMap<>();
diff --git 
a/solr/core/src/java/org/apache/solr/index/WrapperMergePolicyFactory.java 
b/solr/core/src/java/org/apache/solr/index/WrapperMergePolicyFactory.java
index 8aa61ef8edf..d2ce876cbe0 100644
--- a/solr/core/src/java/org/apache/solr/index/WrapperMergePolicyFactory.java
+++ b/solr/core/src/java/org/apache/solr/index/WrapperMergePolicyFactory.java
@@ -38,7 +38,7 @@ public abstract class WrapperMergePolicyFactory extends 
MergePolicyFactory {
   protected WrapperMergePolicyFactory(
       SolrResourceLoader resourceLoader, MergePolicyFactoryArgs args, 
IndexSchema schema) {
     super(resourceLoader, args, schema);
-    wrappedMergePolicyArgs = filterWrappedMergePolicyFactoryArgs();
+    wrappedMergePolicyArgs = 
filterWrappedMergePolicyFactoryArgs(WRAPPED_PREFIX);
     if (wrappedMergePolicyArgs == null) {
       wrappedMergePolicyClassName = null;
     } else {
@@ -108,8 +108,8 @@ public abstract class WrapperMergePolicyFactory extends 
MergePolicyFactory {
    * Returns a {@link MergePolicyFactoryArgs} for the wrapped {@link 
MergePolicyFactory}. This
    * method also removes all args from this instance's args.
    */
-  private MergePolicyFactoryArgs filterWrappedMergePolicyFactoryArgs() {
-    final String wrappedPolicyPrefix = (String) args.remove(WRAPPED_PREFIX);
+  protected MergePolicyFactoryArgs filterWrappedMergePolicyFactoryArgs(String 
wrappedPrefix) {
+    final String wrappedPolicyPrefix = (String) args.remove(wrappedPrefix);
     if (wrappedPolicyPrefix == null) {
       return null;
     }
diff --git 
a/solr/core/src/test-files/solr/collection1/conf/solrconfig-bpreorderingmergepolicyfactory.xml
 
b/solr/core/src/test-files/solr/collection1/conf/solrconfig-bpreorderingmergepolicyfactory.xml
new file mode 100644
index 00000000000..c9144c24fbf
--- /dev/null
+++ 
b/solr/core/src/test-files/solr/collection1/conf/solrconfig-bpreorderingmergepolicyfactory.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" ?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<config>
+  <luceneMatchVersion>${tests.luceneMatchVersion:LATEST}</luceneMatchVersion>
+  <directoryFactory name="DirectoryFactory" 
class="${solr.directoryFactory:solr.MockDirectoryFactory}"/>
+  <schemaFactory class="ClassicIndexSchemaFactory"/>
+
+  <indexConfig>
+    <mergePolicyFactory 
class="org.apache.solr.index.BPReorderingMergePolicyFactory">
+      <str name="wrapped.prefix">in</str>
+      <str 
name="in.class">org.apache.solr.util.RandomForceMergePolicyFactory</str>
+      <str name="bpr.prefix">bpr</str>
+      <int name="bpr.minDocFreq">1</int>
+      <float name="bpr.maxDocFreq">1</float>
+      <int name="bpr.minPartitionSize">32</int>
+      <int name="bpr.maxIters">20</int>
+      <double name="bpr.RAMBudgetMB">42.42</double>
+      <str name="bpr.fields">foo,bar</str>
+      <int name="minNaturalMergeNumDocs">1</int>
+      <float name="minNaturalMergeRatioFromBiggestSegment">0.0</float>
+    </mergePolicyFactory>
+    <lockType>${solr.tests.lockType:single}</lockType>
+  </indexConfig>
+
+  <requestHandler name="/select" class="solr.SearchHandler" />
+
+  <updateHandler class="solr.DirectUpdateHandler2">
+    <updateLog>
+      <str name="dir">${solr.ulog.dir:}</str>
+    </updateLog>
+
+    <autoCommit>
+      <maxTime>${solr.autoCommit.maxTime:-1}</maxTime>
+      <openSearcher>false</openSearcher>
+    </autoCommit>
+
+    <autoSoftCommit>
+      <maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
+    </autoSoftCommit>
+  </updateHandler>
+  <initParams path="/select">
+    <lst name="defaults">
+      <str name="df">text</str>
+    </lst>
+  </initParams>
+
+</config>
diff --git a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java 
b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java
index 2a59bbb8312..54c58df9d90 100644
--- a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java
+++ b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java
@@ -24,6 +24,7 @@ import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.index.MergePolicy;
 import org.apache.lucene.index.SimpleMergedSegmentWarmer;
 import org.apache.lucene.index.TieredMergePolicy;
+import org.apache.lucene.misc.index.BPReorderingMergePolicy;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.SortField;
 import org.apache.solr.SolrTestCaseJ4;
@@ -55,6 +56,8 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 {
       "solrconfig-concurrentmergescheduler.xml";
   private static final String solrConfigFileNameSortingMergePolicyFactory =
       "solrconfig-sortingmergepolicyfactory.xml";
+  private static final String solrConfigFileNameBPReorderingMergePolicyFactory 
=
+      "solrconfig-bpreorderingmergepolicyfactory.xml";
   private static final String schemaFileName = "schema.xml";
 
   private static boolean compoundMergePolicySort = false;
@@ -169,6 +172,23 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 {
     assertEquals("SortingMergePolicy.getSort", expected, actual);
   }
 
+  public void testBPReorderingMPSolrIndexConfigCreation() throws Exception {
+    SolrConfig solrConfig =
+        new SolrConfig(instanceDir, 
solrConfigFileNameBPReorderingMergePolicyFactory);
+    SolrIndexConfig solrIndexConfig = new SolrIndexConfig(solrConfig, null);
+    assertNotNull(solrIndexConfig);
+    IndexSchema indexSchema = 
IndexSchemaFactory.buildIndexSchema(schemaFileName, solrConfig);
+
+    h.getCore().setLatestSchema(indexSchema);
+    IndexWriterConfig iwc = solrIndexConfig.toIndexWriterConfig(h.getCore());
+
+    final MergePolicy mergePolicy = iwc.getMergePolicy();
+    assertNotNull("null mergePolicy", mergePolicy);
+    assertTrue(
+        "mergePolicy (" + mergePolicy + ") is not a BPReorderingMergePolicy",
+        mergePolicy instanceof BPReorderingMergePolicy);
+  }
+
   public void testMergedSegmentWarmerIndexConfigCreation() throws Exception {
     SolrConfig solrConfig =
         new SolrConfig(instanceDir, 
solrConfigFileNameWarmerRandomMergePolicyFactory);

Reply via email to