Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 925469) +++ CHANGES.txt (working copy) @@ -193,6 +193,12 @@ documents (previously this was hardwired to 5), using IndexWriterConfig.setMaxThreadStates. (Mike McCandless) +* LUCENE-2331: Add NoMergePolicy which never returns any merges to execute. In + addition, add NoMergeScheduler which never executes any merges. These two are + convenient classes in case you want to disable segment merges by IndexWriter + without tweaking a particular MergePolicy parameters, such as mergeFactor. + MergeScheduler's methods are now public. (Shai Erera via ?) + Optimizations * LUCENE-2075: Terms dict cache is now shared across threads instead Index: src/java/org/apache/lucene/index/MergeScheduler.java =================================================================== --- src/java/org/apache/lucene/index/MergeScheduler.java (revision 925469) +++ src/java/org/apache/lucene/index/MergeScheduler.java (working copy) @@ -26,14 +26,13 @@ * * @lucene.experimental */ - public abstract class MergeScheduler { /** Run the merges provided by {@link IndexWriter#getNextMerge()}. */ - abstract void merge(IndexWriter writer) + public abstract void merge(IndexWriter writer) throws CorruptIndexException, IOException; /** Close this MergeScheduler. */ - abstract void close() + public abstract void close() throws CorruptIndexException, IOException; } Index: src/java/org/apache/lucene/index/NoMergePolicy.java =================================================================== --- src/java/org/apache/lucene/index/NoMergePolicy.java (revision 0) +++ src/java/org/apache/lucene/index/NoMergePolicy.java (revision 0) @@ -0,0 +1,78 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +import java.io.IOException; +import java.util.Set; + +/** + * A {@link MergePolicy} which never returns merges to execute (hence it's + * name). It is also a singleton and can be accessed through + * {@link NoMergePolicy#NO_COMPOUND_FILES} if you want to indicate the index + * does not use compound files, or through {@link NoMergePolicy#COMPOUND_FILES} + * otherwise. Use it if you want to prevent an {@link IndexWriter} from ever + * executing merges, without going through the hassle of tweaking a merge + * policy's settings to achieve that, such as changing its merge factor. + */ +public final class NoMergePolicy extends MergePolicy { + + /** + * A singleton {@link NoMergePolicy} which indicates the index does not use + * compound files. + */ + public static final MergePolicy NO_COMPOUND_FILES = new NoMergePolicy(false); + + /** + * A singleton {@link NoMergePolicy} which indicates the index uses compound + * files. + */ + public static final MergePolicy COMPOUND_FILES = new NoMergePolicy(true); + + private final boolean useCompoundFile; + + private NoMergePolicy(boolean useCompoundFile) { + // prevent instantiation + this.useCompoundFile = useCompoundFile; + } + + @Override + public void close() {} + + @Override + public MergeSpecification findMerges(SegmentInfos segmentInfos) + throws CorruptIndexException, IOException { return null; } + + @Override + public MergeSpecification findMergesForOptimize(SegmentInfos segmentInfos, + int maxSegmentCount, Set segmentsToOptimize) + throws CorruptIndexException, IOException { return null; } + + @Override + public MergeSpecification findMergesToExpungeDeletes(SegmentInfos segmentInfos) + throws CorruptIndexException, IOException { return null; } + + @Override + public boolean useCompoundDocStore(SegmentInfos segments) { return useCompoundFile; } + + @Override + public boolean useCompoundFile(SegmentInfos segments, SegmentInfo newSegment) { return useCompoundFile; } + + @Override + public void setIndexWriter(IndexWriter writer) {} + +} Property changes on: src\java\org\apache\lucene\index\NoMergePolicy.java ___________________________________________________________________ Added: svn:keywords + Date Author Id Revision HeadURL Added: svn:eol-style + native Index: src/java/org/apache/lucene/index/NoMergeScheduler.java =================================================================== --- src/java/org/apache/lucene/index/NoMergeScheduler.java (revision 0) +++ src/java/org/apache/lucene/index/NoMergeScheduler.java (revision 0) @@ -0,0 +1,47 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +import java.io.IOException; + +/** + * A {@link MergeScheduler} which never executes any merges. It is also a + * singleton and can be accessed through {@link NoMergeScheduler#INSTANCE}. Use + * it if you want to prevent an {@link IndexWriter} from ever executing merges, + * irregardles of the {@link MergePolicy} used. Note that you can achieve the + * same thing by using {@link NoMergePolicy}, however with + * {@link NoMergeScheduler} you also ensure that no unnecessary code of any + * {@link MergeScheduler} implementation is ever executed. Hence it is + * recommended to use both if you want to disable merges from ever happening. + */ +public final class NoMergeScheduler extends MergeScheduler { + + /** The single instance of {@link NoMergeScheduler} */ + public static final MergeScheduler INSTANCE = new NoMergeScheduler(); + + private NoMergeScheduler() { + // prevent instantiation + } + + @Override + public void close() {} + + @Override + public void merge(IndexWriter writer) throws CorruptIndexException, IOException {} + +} Property changes on: src\java\org\apache\lucene\index\NoMergeScheduler.java ___________________________________________________________________ Added: svn:keywords + Date Author Id Revision HeadURL Added: svn:eol-style + native Index: src/test/org/apache/lucene/index/TestNoMergePolicy.java =================================================================== --- src/test/org/apache/lucene/index/TestNoMergePolicy.java (revision 0) +++ src/test/org/apache/lucene/index/TestNoMergePolicy.java (revision 0) @@ -0,0 +1,76 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +import static org.junit.Assert.*; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; + +import org.apache.lucene.util.LuceneTestCaseJ4; +import org.junit.Test; + +public class TestNoMergePolicy extends LuceneTestCaseJ4 { + + @Test + public void testNoMergePolicy() throws Exception { + MergePolicy mp = NoMergePolicy.NO_COMPOUND_FILES; + assertNull(mp.findMerges(null)); + assertNull(mp.findMergesForOptimize(null, 0, null)); + assertNull(mp.findMergesToExpungeDeletes(null)); + assertFalse(mp.useCompoundDocStore(null)); + assertFalse(mp.useCompoundFile(null, null)); + mp.close(); + } + + @Test + public void testCompoundFiles() throws Exception { + assertFalse(NoMergePolicy.NO_COMPOUND_FILES.useCompoundDocStore(null)); + assertFalse(NoMergePolicy.NO_COMPOUND_FILES.useCompoundFile(null, null)); + assertTrue(NoMergePolicy.COMPOUND_FILES.useCompoundDocStore(null)); + assertTrue(NoMergePolicy.COMPOUND_FILES.useCompoundFile(null, null)); + } + + @Test + public void testFinalSingleton() throws Exception { + assertTrue(Modifier.isFinal(NoMergePolicy.class.getModifiers())); + Constructor[] ctors = NoMergePolicy.class.getDeclaredConstructors(); + assertEquals("expected 1 private ctor only: " + Arrays.toString(ctors), 1, ctors.length); + assertTrue("that 1 should be private: " + ctors[0], Modifier.isPrivate(ctors[0].getModifiers())); + } + + @Test + public void testMethodsOverridden() throws Exception { + // Ensures that all methods of MergePolicy are overridden. That's important + // to ensure that NoMergePolicy overrides everything, so that no unexpected + // behavior/error occurs + for (Method m : NoMergePolicy.class.getMethods()) { + // getDeclaredMethods() returns just those methods that are declared on + // NoMergePolicy. getMethods() returns those that are visible in that + // context, including ones from Object. So just filter out Object. If in + // the future MergePolicy will extend a different class than Object, this + // will need to change. + if (m.getDeclaringClass() != Object.class) { + assertTrue(m + " is not overridden !", m.getDeclaringClass() == NoMergePolicy.class); + } + } + } + +} Property changes on: src\test\org\apache\lucene\index\TestNoMergePolicy.java ___________________________________________________________________ Added: svn:keywords + Date Author Id Revision HeadURL Added: svn:eol-style + native Index: src/test/org/apache/lucene/index/TestNoMergeScheduler.java =================================================================== --- src/test/org/apache/lucene/index/TestNoMergeScheduler.java (revision 0) +++ src/test/org/apache/lucene/index/TestNoMergeScheduler.java (revision 0) @@ -0,0 +1,64 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +import static org.junit.Assert.*; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; + +import org.apache.lucene.util.LuceneTestCaseJ4; +import org.junit.Test; + +public class TestNoMergeScheduler extends LuceneTestCaseJ4 { + + @Test + public void testNoMergeScheduler() throws Exception { + MergeScheduler ms = NoMergeScheduler.INSTANCE; + ms.close(); + ms.merge(null); + } + + @Test + public void testFinalSingleton() throws Exception { + assertTrue(Modifier.isFinal(NoMergeScheduler.class.getModifiers())); + Constructor[] ctors = NoMergeScheduler.class.getDeclaredConstructors(); + assertEquals("expected 1 private ctor only: " + Arrays.toString(ctors), 1, ctors.length); + assertTrue("that 1 should be private: " + ctors[0], Modifier.isPrivate(ctors[0].getModifiers())); + } + + @Test + public void testMethodsOverridden() throws Exception { + // Ensures that all methods of MergePolicy are overridden. That's important + // to ensure that NoMergePolicy overrides everything, so that no unexpected + // behavior/error occurs + for (Method m : NoMergeScheduler.class.getMethods()) { + // getDeclaredMethods() returns just those methods that are declared on + // NoMergeScheduler. getMethods() returns those that are visible in that + // context, including ones from Object. So just filter out Object. If in + // the future MergeScheduler will extend a different class than Object, + // this will need to change. + if (m.getDeclaringClass() != Object.class) { + assertTrue(m + " is not overridden !", m.getDeclaringClass() == NoMergeScheduler.class); + } + } + } + +} Property changes on: src\test\org\apache\lucene\index\TestNoMergeScheduler.java ___________________________________________________________________ Added: svn:keywords + Date Author Id Revision HeadURL Added: svn:eol-style + native