jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mreut...@apache.org
Subject svn commit: r597706 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene: AbstractIndex.java CommittableIndexReader.java ReadOnlyIndexReader.java VolatileIndex.java
Date Fri, 23 Nov 2007 17:27:56 GMT
Author: mreutegg
Date: Fri Nov 23 09:27:55 2007
New Revision: 597706

URL: http://svn.apache.org/viewvc?rev=597706&view=rev
Log:
JCR-1225: ReadOnlyIndexReaders are re-created on every access

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CommittableIndexReader.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ReadOnlyIndexReader.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/VolatileIndex.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java?rev=597706&r1=597705&r2=597706&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java
Fri Nov 23 09:27:55 2007
@@ -94,6 +94,11 @@
     private SharedIndexReader sharedReader;
 
     /**
+     * The most recent read-only reader if there is any.
+     */
+    private ReadOnlyIndexReader readOnlyReader;
+
+    /**
      * The indexing queue.
      */
     private IndexingQueue indexingQueue;
@@ -208,7 +213,7 @@
      * @return an <code>IndexReader</code> on this index.
      * @throws IOException if the reader cannot be obtained.
      */
-    protected synchronized IndexReader getIndexReader() throws IOException {
+    protected synchronized CommittableIndexReader getIndexReader() throws IOException {
         if (indexWriter != null) {
             indexWriter.close();
             log.debug("closing IndexWriter.");
@@ -232,7 +237,30 @@
     synchronized ReadOnlyIndexReader getReadOnlyIndexReader()
             throws IOException {
         // get current modifiable index reader
-        IndexReader modifiableReader = getIndexReader();
+        CommittableIndexReader modifiableReader = getIndexReader();
+        long modCount = modifiableReader.getModificationCount();
+        if (readOnlyReader != null) {
+            if (readOnlyReader.getDeletedDocsVersion() == modCount) {
+                // reader up-to-date
+                readOnlyReader.incrementRefCount();
+                return readOnlyReader;
+            } else {
+                // reader outdated
+                if (readOnlyReader.getRefCount() == 1) {
+                    // not in use, except by this index
+                    // update the reader
+                    readOnlyReader.updateDeletedDocs(modifiableReader);
+                    readOnlyReader.incrementRefCount();
+                    return readOnlyReader;
+                } else {
+                    // cannot update reader, it is still in use
+                    // need to create a new instance
+                    readOnlyReader.close();
+                    readOnlyReader = null;
+                }
+            }
+        }
+        // if we get here there is no up-to-date read-only reader
         // capture snapshot of deleted documents
         BitSet deleted = new BitSet(modifiableReader.maxDoc());
         for (int i = 0; i < modifiableReader.maxDoc(); i++) {
@@ -245,7 +273,9 @@
             CachingIndexReader cr = new CachingIndexReader(IndexReader.open(getDirectory()),
cache);
             sharedReader = new SharedIndexReader(cr);
         }
-        return new ReadOnlyIndexReader(sharedReader, deleted);
+        readOnlyReader = new ReadOnlyIndexReader(sharedReader, deleted, modCount);
+        readOnlyReader.incrementRefCount();
+        return readOnlyReader;
     }
 
     /**
@@ -330,6 +360,13 @@
             }
             indexReader = null;
         }
+        if (readOnlyReader != null) {
+            try {
+                readOnlyReader.close();
+            } catch (IOException e) {
+                log.warn("Exception closing index reader: " + e.toString());
+            }
+        }
         if (sharedReader != null) {
             try {
                 sharedReader.close();
@@ -352,6 +389,11 @@
      * @throws IOException if an error occurs while closing the reader.
      */
     protected synchronized void invalidateSharedReader() throws IOException {
+        // also close the read-only reader
+        if (readOnlyReader != null) {
+            readOnlyReader.close();
+            readOnlyReader = null;
+        }
         // invalidate shared reader
         if (sharedReader != null) {
             sharedReader.close();

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CommittableIndexReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CommittableIndexReader.java?rev=597706&r1=597705&r2=597706&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CommittableIndexReader.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CommittableIndexReader.java
Fri Nov 23 09:27:55 2007
@@ -18,6 +18,7 @@
 
 import org.apache.lucene.index.FilterIndexReader;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.CorruptIndexException;
 
 import java.io.IOException;
 
@@ -28,14 +29,36 @@
 class CommittableIndexReader extends FilterIndexReader {
 
     /**
+     * A modification count on this index reader. Initialied with
+     * {@link IndexReader#getVersion()} and incremented with every call to
+     * {@link #doDelete(int)}.
+     */
+    private volatile long modCount;
+
+    /**
      * Creates a new <code>CommittableIndexReader</code> based on <code>in</code>.
      *
      * @param in the <code>IndexReader</code> to wrap.
      */
     CommittableIndexReader(IndexReader in) {
         super(in);
+        modCount = in.getVersion();
     }
 
+    //------------------------< FilterIndexReader >-----------------------------
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * Increments the modification count.
+     */
+    protected void doDelete(int n) throws CorruptIndexException, IOException {
+        super.doDelete(n);
+        modCount++;
+    }
+
+    //------------------------< additional methods >----------------------------
+
     /**
      * Commits the documents marked as deleted to disc.
      *
@@ -43,5 +66,12 @@
      */
     void commitDeleted() throws IOException {
         commit();
+    }
+
+    /**
+     * @return the modification count of this index reader.
+     */
+    long getModificationCount() {
+        return modCount;
     }
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ReadOnlyIndexReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ReadOnlyIndexReader.java?rev=597706&r1=597705&r2=597706&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ReadOnlyIndexReader.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ReadOnlyIndexReader.java
Fri Nov 23 09:27:55 2007
@@ -44,21 +44,81 @@
     private final BitSet deleted;
 
     /**
+     * The version of the index reader from where the deleted BitSet was
+     * obtained from.
+     */
+    private long deletedDocsVersion;
+
+    /**
+     * A reference counter. When constructed the refCount is one.
+     */
+    private int refCount = 1;
+
+    /**
      * Creates a new index reader based on <code>reader</code> at
      * <code>modificationTick</code>.
-     * @param reader the underlying <code>IndexReader</code>.
-     * @param deleted the documents that are deleted in <code>reader</code>.
+     *
+     * @param reader             the underlying <code>IndexReader</code>.
+     * @param deleted            the documents that are deleted in
+     *                           <code>reader</code>.
+     * @param deletedDocsVersion the version of the index reader from where the
+     *                           deleted BitSet was obtained from.
      */
     public ReadOnlyIndexReader(SharedIndexReader reader,
-                               BitSet deleted) {
+                               BitSet deleted,
+                               long deletedDocsVersion) {
         super(reader);
         this.reader = reader;
         this.deleted = deleted;
+        this.deletedDocsVersion = deletedDocsVersion;
         // register this
         reader.addClient(this);
     }
 
     /**
+     * Increments the reference count on this index reader. The reference count
+     * is decremented on {@link #close()}.
+     */
+    synchronized void incrementRefCount() {
+        refCount++;
+    }
+
+    /**
+     * @return the current reference count value.
+     */
+    synchronized int getRefCount() {
+        return refCount;
+    }
+
+    /**
+     * @return version of the deleted docs.
+     */
+    long getDeletedDocsVersion() {
+        return deletedDocsVersion;
+    }
+
+    /**
+     * Updates the deleted documents in this index reader. When this method
+     * returns this index reader will have the same documents marked as deleted
+     * as the passed <code>reader</code>.
+     * <p/>
+     * This method is not thread-safe! Make sure no other thread is concurrently
+     * using this reader at the same time.
+     *
+     * @param reader the reader from where to obtain the deleted documents
+     *               info.
+     */
+    void updateDeletedDocs(CommittableIndexReader reader) {
+        int maxDoc = reader.maxDoc();
+        for (int i = 0; i < maxDoc; i++) {
+            if (reader.isDeleted(i)) {
+                deleted.set(i);
+            }
+        }
+        deletedDocsVersion = reader.getModificationCount();
+    }
+
+    /**
      * Returns the <code>DocId</code> of the parent of <code>n</code>
or
      * {@link DocId#NULL} if <code>n</code> does not have a parent
      * (<code>n</code> is the root node).
@@ -131,13 +191,19 @@
     }
 
     /**
-     * Unregisters this reader from the shared index reader. Specifically, this
-     * method does <b>not</b> close the underlying index reader, because it is
-     * shared by multiple <code>ReadOnlyIndexReader</code>s.
+     * Unregisters this reader from the shared index reader if the reference
+     * count for this reader drops to zero. Specifically, this method does
+     * <b>not</b> close the underlying index reader, because it is shared by
+     * multiple <code>ReadOnlyIndexReader</code>s.
+     *
      * @throws IOException if an error occurs while closing the reader.
      */
     protected void doClose() throws IOException {
-        reader.removeClient(this);
+        synchronized (this) {
+            if (--refCount == 0) {
+                reader.removeClient(this);
+            }
+        }
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/VolatileIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/VolatileIndex.java?rev=597706&r1=597705&r2=597706&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/VolatileIndex.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/VolatileIndex.java
Fri Nov 23 09:27:55 2007
@@ -123,7 +123,7 @@
      * @return the index reader for this index.
      * @throws IOException if an error occurs building a reader.
      */
-    protected synchronized IndexReader getIndexReader() throws IOException {
+    protected synchronized CommittableIndexReader getIndexReader() throws IOException {
         commitPending();
         return super.getIndexReader();
     }



Mime
View raw message