Index: src/java/org/apache/lucene/index/MultiReader.java =================================================================== --- src/java/org/apache/lucene/index/MultiReader.java (revision 611183) +++ src/java/org/apache/lucene/index/MultiReader.java (working copy) @@ -39,6 +39,7 @@ private Hashtable normsCache = new Hashtable(); private int maxDoc = 0; private int numDocs = -1; + private int numDeletedDocs = -1; private boolean hasDeletions = false; /** @@ -203,6 +204,16 @@ return numDocs; } + public synchronized int numDeletedDocs() { + // Don't call ensureOpen() here (it could affect performance) + if (numDeletedDocs == -1) { + for (int i = 0; i < subReaders.length; i++) { + numDeletedDocs += subReaders[i].numDeletedDocs(); + } + } + return numDeletedDocs; + } + public int maxDoc() { // Don't call ensureOpen() here (it could affect performance) return maxDoc; @@ -228,6 +239,7 @@ protected void doDelete(int n) throws CorruptIndexException, IOException { numDocs = -1; // invalidate cache + numDeletedDocs = -1; // invalidate cache int i = readerIndex(n); // find segment num subReaders[i].deleteDocument(n - starts[i]); // dispatch to segment reader hasDeletions = true; @@ -238,7 +250,8 @@ subReaders[i].undeleteAll(); hasDeletions = false; - numDocs = -1; // invalidate cache + numDocs = -1; // invalidate cache + numDeletedDocs = -1; // invalidate cache } private int readerIndex(int n) { // find reader for doc n: Index: src/java/org/apache/lucene/index/FilterIndexReader.java =================================================================== --- src/java/org/apache/lucene/index/FilterIndexReader.java (revision 611183) +++ src/java/org/apache/lucene/index/FilterIndexReader.java (working copy) @@ -137,6 +137,11 @@ return in.numDocs(); } + public int numDeletedDocs() { + // Don't call ensureOpen() here (it could affect performance) + return in.numDeletedDocs(); + } + public int maxDoc() { // Don't call ensureOpen() here (it could affect performance) return in.maxDoc(); Index: src/java/org/apache/lucene/index/ParallelReader.java =================================================================== --- src/java/org/apache/lucene/index/ParallelReader.java (revision 611183) +++ src/java/org/apache/lucene/index/ParallelReader.java (working copy) @@ -53,6 +53,7 @@ private int maxDoc; private int numDocs; + private int numDeletedDocs; private boolean hasDeletions; /** Construct a ParallelReader. @@ -94,6 +95,7 @@ if (readers.size() == 0) { this.maxDoc = reader.maxDoc(); this.numDocs = reader.numDocs(); + this.numDeletedDocs = reader.numDeletedDocs(); this.hasDeletions = reader.hasDeletions(); } @@ -214,6 +216,11 @@ return numDocs; } + public int numDeletedDocs() { + // Don't call ensureOpen() here (it could affect performance) + return numDeletedDocs; + } + public int maxDoc() { // Don't call ensureOpen() here (it could affect performance) return maxDoc; Index: src/java/org/apache/lucene/index/SegmentReader.java =================================================================== --- src/java/org/apache/lucene/index/SegmentReader.java (revision 611183) +++ src/java/org/apache/lucene/index/SegmentReader.java (working copy) @@ -690,6 +690,11 @@ return n; } + public int numDeletedDocs() { + // Don't call ensureOpen() here (it could affect performance) + return deletedDocs == null ? 0 : deletedDocs.count(); + } + public int maxDoc() { // Don't call ensureOpen() here (it could affect performance) return si.docCount; Index: src/java/org/apache/lucene/index/IndexReader.java =================================================================== --- src/java/org/apache/lucene/index/IndexReader.java (revision 611183) +++ src/java/org/apache/lucene/index/IndexReader.java (working copy) @@ -509,6 +509,9 @@ /** Returns the number of documents in this index. */ public abstract int numDocs(); + /** Returns the number of deleted documents in this index. */ + public abstract int numDeletedDocs(); + /** Returns one greater than the largest possible document number. * This may be used to, e.g., determine how big to allocate an array which * will have an element for every document number in an index. Index: src/java/org/apache/lucene/index/MultiSegmentReader.java =================================================================== --- src/java/org/apache/lucene/index/MultiSegmentReader.java (revision 611183) +++ src/java/org/apache/lucene/index/MultiSegmentReader.java (working copy) @@ -39,6 +39,7 @@ private Hashtable normsCache = new Hashtable(); private int maxDoc = 0; private int numDocs = -1; + private int numDeletedDocs = -1; private boolean hasDeletions = false; /** Construct reading the named set of readers. */ @@ -245,6 +246,16 @@ return numDocs; } + public synchronized int numDeletedDocs() { + // Don't call ensureOpen() here (it could affect performance) + if (numDeletedDocs == -1) { + for (int i = 0; i < subReaders.length; i++) { + numDeletedDocs += subReaders[i].numDeletedDocs(); + } + } + return numDeletedDocs; + } + public int maxDoc() { // Don't call ensureOpen() here (it could affect performance) return maxDoc; @@ -270,6 +281,7 @@ protected void doDelete(int n) throws CorruptIndexException, IOException { numDocs = -1; // invalidate cache + numDeletedDocs = -1; // invalidate cache int i = readerIndex(n); // find segment num subReaders[i].deleteDocument(n - starts[i]); // dispatch to segment reader hasDeletions = true; @@ -281,6 +293,7 @@ hasDeletions = false; numDocs = -1; // invalidate cache + numDeletedDocs = -1; // invalidate cache } private int readerIndex(int n) { // find reader for doc n: