/* * 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.lucene.index; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.TestUtil; import org.apache.lucene.util.Version; import org.junit.Test; public class TestOneMergeWrappingMergePolicy extends LuceneTestCase { private static class PredeterminedMergePolicy extends MergePolicy { final private MergePolicy.MergeSpecification merges; final private MergePolicy.MergeSpecification forcedMerges; final private MergePolicy.MergeSpecification forcedDeletesMerges; public PredeterminedMergePolicy( MergePolicy.MergeSpecification merges, MergePolicy.MergeSpecification forcedMerges, MergePolicy.MergeSpecification forcedDeletesMerges) { this.merges = merges; this.forcedMerges = forcedMerges; this.forcedDeletesMerges = forcedDeletesMerges; } @Override public MergePolicy.MergeSpecification findMerges(MergeTrigger mergeTrigger, SegmentInfos segmentInfos, IndexWriter writer) throws IOException { return merges; } @Override public MergePolicy.MergeSpecification findForcedMerges(SegmentInfos segmentInfos, int maxSegmentCount, Map<SegmentCommitInfo,Boolean> segmentsToMerge, IndexWriter writer) throws IOException { return forcedMerges; } @Override public MergePolicy.MergeSpecification findForcedDeletesMerges(SegmentInfos segmentInfos, IndexWriter writer) throws IOException { return forcedDeletesMerges; } } private static class WrappedOneMerge extends MergePolicy.OneMerge { final MergePolicy.OneMerge original; public WrappedOneMerge(MergePolicy.OneMerge original) { super(original.segments); this.original = original; } } @Test public void testSegmentsAreWrapped() throws IOException { try (final Directory dir = newDirectory()) { // first create random merge specs final MergePolicy.MergeSpecification msM = createRandomMergeSpecification(dir); final MergePolicy.MergeSpecification msF = createRandomMergeSpecification(dir); final MergePolicy.MergeSpecification msD = createRandomMergeSpecification(dir); // secondly, pass them to the predetermined merge policy constructor final MergePolicy originalMP = new PredeterminedMergePolicy(msM, msF, msD); // thirdly wrap the predetermined merge policy final MergePolicy oneMergeWrappingMP = new OneMergeWrappingMergePolicy( originalMP, merge -> new WrappedOneMerge(merge)); // finally, ask for merges and check what we got implTestSegmentsAreWrapped(msM, oneMergeWrappingMP.findMerges(null, null, null)); implTestSegmentsAreWrapped(msF, oneMergeWrappingMP.findForcedMerges(null, 0, null, null)); implTestSegmentsAreWrapped(msD, oneMergeWrappingMP.findForcedDeletesMerges(null, null)); } } private static void implTestSegmentsAreWrapped(MergePolicy.MergeSpecification originalMS, MergePolicy.MergeSpecification testMS) { // wrapping does not add or remove merge specs assertEquals((originalMS == null), (testMS == null)); if (originalMS == null) return; assertEquals(originalMS.merges.size(), testMS.merges.size()); // wrapping does not re-order merge specs for (int ii = 0; ii < originalMS.merges.size(); ++ii) { final MergePolicy.OneMerge originalOM = originalMS.merges.get(ii); final MergePolicy.OneMerge testOM = testMS.merges.get(ii); // wrapping wraps assertTrue(testOM instanceof WrappedOneMerge); final WrappedOneMerge wrappedOM = (WrappedOneMerge)testOM; // and what is wrapped is what was originally passed in assertEquals(originalOM, wrappedOM.original); } } private static MergePolicy.MergeSpecification createRandomMergeSpecification(Directory dir) { MergePolicy.MergeSpecification ms; if (0 < random().nextInt(10)) { // ~ 1 in 10 times return null ms = new MergePolicy.MergeSpecification(); // append up to 10 (random non-sensical) one merge objects for (int ii = 0; ii < random().nextInt(10); ++ii) { final SegmentInfo si = new SegmentInfo( dir, // dir Version.LATEST, // version Version.LATEST, // min version TestUtil.randomSimpleString(random()), // name random().nextInt(), // maxDoc random().nextBoolean(), // isCompoundFile null, // codec Collections.emptyMap(), // diagnostics TestUtil.randomSimpleString(// id random(), StringHelper.ID_LENGTH, StringHelper.ID_LENGTH).getBytes(StandardCharsets.US_ASCII), Collections.emptyMap(), // attributes null /* indexSort */); final List<SegmentCommitInfo> segments = new LinkedList<SegmentCommitInfo>(); segments.add(new SegmentCommitInfo(si, 0, 0, 0, 0)); ms.add(new MergePolicy.OneMerge(segments)); } } return null; } }