Index: src/java/org/apache/lucene/index/LogMergePolicy.java =================================================================== --- src/java/org/apache/lucene/index/LogMergePolicy.java (revision 600921) +++ src/java/org/apache/lucene/index/LogMergePolicy.java (working copy) @@ -19,6 +19,8 @@ import java.io.IOException; import java.util.Set; +import java.util.Arrays; +import java.util.Comparator; import org.apache.lucene.store.Directory; @@ -59,6 +61,7 @@ long maxMergeSize; int maxMergeDocs = DEFAULT_MAX_MERGE_DOCS; + private boolean requireContiguousMerge = false; private boolean useCompoundFile = true; private boolean useCompoundDocStore = true; private IndexWriter writer; @@ -68,6 +71,16 @@ writer.message("LMP: " + message); } + // nocommit javadoc + public void setRequireContiguousMerge(boolean v) { + requireContiguousMerge = v; + } + + // nocommit javadoc + public boolean getRequireContiguousMerge() { + return requireContiguousMerge; + } + /**
Returns the number of segments that are merged at * once and also controls the total number of segments * allowed to accumulate in the index.
*/ @@ -159,6 +172,7 @@ info.getUseCompoundFile() == useCompoundFile; } + // nocommit -- must make this work for non-contiguosu case too /** Returns the merges necessary to optimize the index. * This merge policy defines "optimized" to mean only one * segment in the index, where that segment has no @@ -245,6 +259,37 @@ return spec; } + private static class SegmentInfoAndLevel implements Comparable { + SegmentInfo info; + float level; + int index; + + public SegmentInfoAndLevel(SegmentInfo info, float level, int index) { + this.info = info; + this.level = level; + this.index = index; + } + + // Sorts largest to smallest + public int compareTo(Object o) { + SegmentInfoAndLevel other = (SegmentInfoAndLevel) o; + if (level < other.level) + return 1; + else if (level > other.level) + return -1; + else + return 0; + } + } + + private static class SortByIndex implements Comparator { + public int compare(Object o1, Object o2) { + final SegmentInfoAndLevel sl1 = (SegmentInfoAndLevel) o1; + final SegmentInfoAndLevel sl2 = (SegmentInfoAndLevel) o2; + return sl1.index - sl2.index; + } + } + /** Checks if any merges are now necessary and returns a * {@link MergePolicy.MergeSpecification} if so. A merge * is necessary when there are more than {@link @@ -260,7 +305,7 @@ // Compute levels, which is just log (base mergeFactor) // of the size of each segment - float[] levels = new float[numSegments]; + SegmentInfoAndLevel[] levels = new SegmentInfoAndLevel[numSegments]; final float norm = (float) Math.log(mergeFactor); final Directory directory = writer.getDirectory(); @@ -279,9 +324,12 @@ // Floor tiny segments if (size < 1) size = 1; - levels[i] = (float) Math.log(size)/norm; + levels[i] = new SegmentInfoAndLevel(info, (float) Math.log(size)/norm, i); } + if (!requireContiguousMerge) + Arrays.sort(levels); + final float levelFloor; if (minMergeSize <= 0) levelFloor = (float) 0.0; @@ -302,9 +350,9 @@ // Find max level of all segments not already // quantized. - float maxLevel = levels[start]; + float maxLevel = levels[start].level; for(int i=1+start;i