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);