LUCENE-2331: add NoMergePolicy, NoMergeScheduler

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/branches/newtrunk@926289 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2010-03-22 19:51:33 +00:00
parent 08b0a689da
commit c8c5dfa543
6 changed files with 272 additions and 3 deletions

View File

@ -197,6 +197,12 @@ New features
even when getReader (near-real-timer reader) is not in use, through
IndexWriterConfig.enable/disableReaderPooling. (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 Mike McCandless)
Optimizations
* LUCENE-2075: Terms dict cache is now shared across threads instead

View File

@ -26,14 +26,13 @@ import java.io.IOException;
*
* @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;
}

View File

@ -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<SegmentInfo> 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) {}
}

View File

@ -0,0 +1,46 @@
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 {}
}

View File

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

View File

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