Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 795386) +++ CHANGES.txt (working copy) @@ -314,6 +314,10 @@ StopAnalzyer and replace it with an immutable implementation of CharArraySet. (Simon Willnauer via Mark Miller) +31. LUCENE-1742: SegmentInfos, SegmentInfo and SegmentReader have been + made public as expert, experimental APIs. These APIs may suddenly + change from release to release (Jason Rutherglen via Mike + McCandless). Bug fixes Index: src/java/org/apache/lucene/index/SegmentInfo.java =================================================================== --- src/java/org/apache/lucene/index/SegmentInfo.java (revision 795386) +++ src/java/org/apache/lucene/index/SegmentInfo.java (working copy) @@ -28,7 +28,14 @@ import java.util.ArrayList; import java.util.Collections; -final class SegmentInfo { +/** + * Information about a segment such as it's name, directory, and files related + * to the segment. + * + * *

NOTE: This API is new and still experimental + * (subject to change suddenly in the next release)

+ */ +public final class SegmentInfo { static final int NO = -1; // e.g. no norms; no deletes; static final int YES = 1; // e.g. have norms; have deletes; @@ -150,7 +157,7 @@ } // returns Map - Map getDiagnostics() { + public Map getDiagnostics() { return diagnostics; } @@ -251,7 +258,7 @@ /** Returns total size in bytes of all of files used by * this segment. */ - long sizeInBytes() throws IOException { + public long sizeInBytes() throws IOException { if (sizeInBytes == -1) { List files = files(); final int size = files.size(); @@ -267,7 +274,7 @@ return sizeInBytes; } - boolean hasDeletions() + public boolean hasDeletions() throws IOException { // Cases: // @@ -325,7 +332,7 @@ return si; } - String getDelFileName() { + public String getDelFileName() { if (delGen == NO) { // In this case we know there is no deletion filename // against this segment @@ -341,7 +348,7 @@ * * @param fieldNumber the field index to check */ - boolean hasSeparateNorms(int fieldNumber) + public boolean hasSeparateNorms(int fieldNumber) throws IOException { if ((normGen == null && preLockless) || (normGen != null && normGen[fieldNumber] == CHECK_DIR)) { // Must fallback to directory file exists check: @@ -357,7 +364,7 @@ /** * Returns true if any fields in this segment have separate norms. */ - boolean hasSeparateNorms() + public boolean hasSeparateNorms() throws IOException { if (normGen == null) { if (!preLockless) { @@ -424,7 +431,7 @@ * * @param number field index */ - String getNormFileName(int number) throws IOException { + public String getNormFileName(int number) throws IOException { String prefix; long gen; @@ -470,7 +477,7 @@ * Returns true if this segment is stored as a compound * file; else, false. */ - boolean getUseCompoundFile() throws IOException { + public boolean getUseCompoundFile() throws IOException { if (isCompoundFile == NO) { return false; } else if (isCompoundFile == YES) { @@ -480,7 +487,7 @@ } } - int getDelCount() throws IOException { + public int getDelCount() throws IOException { if (delCount == -1) { if (hasDeletions()) { final String delFileName = getDelFileName(); @@ -497,11 +504,11 @@ assert delCount <= docCount; } - int getDocStoreOffset() { + public int getDocStoreOffset() { return docStoreOffset; } - boolean getDocStoreIsCompoundFile() { + public boolean getDocStoreIsCompoundFile() { return docStoreIsCompoundFile; } @@ -510,7 +517,7 @@ clearFiles(); } - String getDocStoreSegment() { + public String getDocStoreSegment() { return docStoreSegment; } @@ -559,7 +566,7 @@ clearFiles(); } - boolean getHasProx() { + public boolean getHasProx() { return hasProx; } Index: src/java/org/apache/lucene/index/SegmentReader.java =================================================================== --- src/java/org/apache/lucene/index/SegmentReader.java (revision 795386) +++ src/java/org/apache/lucene/index/SegmentReader.java (working copy) @@ -39,7 +39,11 @@ import org.apache.lucene.util.CloseableThreadLocal; /** @version $Id */ -class SegmentReader extends IndexReader implements Cloneable { +/** + *

NOTE: This API is new and still experimental + * (subject to change suddenly in the next release)

+ */ +public class SegmentReader extends IndexReader implements Cloneable { protected boolean readOnly; private SegmentInfo si; @@ -676,7 +680,7 @@ /** * Clones the norm bytes. May be overridden by subclasses. New and experimental. - * @param bv Byte array to clone + * @param bytes Byte array to clone * @return New BitVector */ protected byte[] cloneNormBytes(byte[] bytes) { Index: src/java/org/apache/lucene/index/LogMergePolicy.java =================================================================== --- src/java/org/apache/lucene/index/LogMergePolicy.java (revision 795386) +++ src/java/org/apache/lucene/index/LogMergePolicy.java (working copy) @@ -65,7 +65,7 @@ private boolean useCompoundFile = true; private boolean useCompoundDocStore = true; - private IndexWriter writer; + protected IndexWriter writer; protected boolean verbose() { return writer != null && writer.verbose(); @@ -154,7 +154,8 @@ protected long sizeDocs(SegmentInfo info) throws IOException { if (calibrateSizeByDeletes) { - return (info.docCount - (long)info.getDelCount()); + int delCount = writer.numDeletedDocs(info); + return (info.docCount - (long)delCount); } else { return info.docCount; } @@ -163,7 +164,8 @@ protected long sizeBytes(SegmentInfo info) throws IOException { long byteSize = info.sizeInBytes(); if (calibrateSizeByDeletes) { - float delRatio = (info.docCount <= 0 ? 0.0f : ((float)info.getDelCount() / (float)info.docCount)); + int delCount = writer.numDeletedDocs(info); + float delRatio = (info.docCount <= 0 ? 0.0f : ((float)delCount / (float)info.docCount)); return (info.docCount <= 0 ? byteSize : (long)((float)byteSize * (1.0f - delRatio))); } else { return byteSize; @@ -186,12 +188,13 @@ (numToOptimize != 1 || isOptimized(writer, optimizeInfo)); } - /** Returns true if this single nfo is optimized (has no + /** Returns true if this single info is optimized (has no * pending norms or deletes, is in the same dir as the * writer, and matches the current compound file setting */ private boolean isOptimized(IndexWriter writer, SegmentInfo info) throws IOException { - return !info.hasDeletions() && + boolean hasDeletions = writer.numDeletedDocs(info) > 0; + return !hasDeletions && !info.hasSeparateNorms() && info.dir == writer.getDirectory() && info.getUseCompoundFile() == useCompoundFile; @@ -303,16 +306,8 @@ int firstSegmentWithDeletions = -1; for(int i=0;i 0) { if (verbose()) message(" segment " + info.name + " has deletions"); if (firstSegmentWithDeletions == -1) Index: src/java/org/apache/lucene/index/SegmentInfos.java =================================================================== --- src/java/org/apache/lucene/index/SegmentInfos.java (revision 795386) +++ src/java/org/apache/lucene/index/SegmentInfos.java (working copy) @@ -34,7 +34,14 @@ import java.util.HashMap; import java.util.Map; -final class SegmentInfos extends Vector { +/** + * A collection of segmentInfo objects with methods for operating on + * those segments in relation to the file system. + * + *

NOTE: This API is new and still experimental + * (subject to change suddenly in the next release)

+ */ +public final class SegmentInfos extends Vector { /** The file format version, a negative number. */ /* Works since counter, the old 1st entry, is always >= 0 */ @@ -767,7 +774,7 @@ version = other.version; } - public final void rollbackCommit(Directory dir) throws IOException { + final void rollbackCommit(Directory dir) throws IOException { if (pendingSegnOutput != null) { try { pendingSegnOutput.close(); @@ -796,7 +803,7 @@ * end, so that it is not visible to readers. Once this * is called you must call {@link #finishCommit} to complete * the commit or {@link #rollbackCommit} to abort it. */ - public final void prepareCommit(Directory dir) throws IOException { + final void prepareCommit(Directory dir) throws IOException { if (pendingSegnOutput != null) throw new IllegalStateException("prepareCommit was already called"); write(dir); @@ -822,7 +829,7 @@ return files; } - public final void finishCommit(Directory dir) throws IOException { + final void finishCommit(Directory dir) throws IOException { if (pendingSegnOutput == null) throw new IllegalStateException("prepareCommit was not called"); boolean success = false; @@ -882,12 +889,12 @@ /** Writes & syncs to the Directory dir, taking care to * remove the segments file on exception */ - public final void commit(Directory dir) throws IOException { + final void commit(Directory dir) throws IOException { prepareCommit(dir); finishCommit(dir); } - synchronized String segString(Directory directory) { + public synchronized String segString(Directory directory) { StringBuffer buffer = new StringBuffer(); final int count = size(); for(int i = 0; i < count; i++) { @@ -906,7 +913,7 @@ return userData; } - public void setUserData(Map data) { + void setUserData(Map data) { if (data == null) { userData = Collections.EMPTY_MAP; } else { @@ -925,7 +932,7 @@ } // Used only for testing - boolean hasExternalSegments(Directory dir) { + public boolean hasExternalSegments(Directory dir) { final int numSegments = size(); for(int i=0;i 0)