jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mreut...@apache.org
Subject svn commit: r601342 - /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/
Date Wed, 05 Dec 2007 14:19:19 GMT
Author: mreutegg
Date: Wed Dec  5 06:19:18 2007
New Revision: 601342

URL: http://svn.apache.org/viewvc?rev=601342&view=rev
Log:
JCR-1213: UUIDDocId cache does not work properly because of weakReferences in combination
with new instance for combined indexreader

Added:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ForeignSegmentDocId.java
  (with props)
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocId.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndexReader.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/SearchIndex.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedIndexReader.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java?rev=601342&r1=601341&r2=601342&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java
Wed Dec  5 06:19:18 2007
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.query.lucene;
 
+import org.apache.jackrabbit.uuid.UUID;
 import org.apache.lucene.index.MultiReader;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermDocs;
@@ -24,6 +25,7 @@
 import java.io.IOException;
 import java.util.Map;
 import java.util.IdentityHashMap;
+import java.util.HashMap;
 
 /**
  * Extends a <code>MultiReader</code> with support for cached <code>TermDocs</code>
@@ -44,6 +46,11 @@
     private final Map readersByBase = new IdentityHashMap();
 
     /**
+     * Map of {@link OffsetReader}s, identified by creation tick.
+     */
+    private final Map readersByCreationTick = new HashMap();
+
+    /**
      * Document number cache if available. May be <code>null</code>.
      */
     private final DocNumberCache cache;
@@ -79,6 +86,8 @@
             maxDoc += subReaders[i].maxDoc();
             OffsetReader offsetReader = new OffsetReader(subReaders[i], starts[i]);
             readersByBase.put(subReaders[i].getBase().getBase(), offsetReader);
+            readersByCreationTick.put(
+                    Long.valueOf(subReaders[i].getCreationTick()), offsetReader);
         }
         starts[subReaders.length] = maxDoc;
     }
@@ -176,8 +185,40 @@
         return readers;
     }
 
-    //------------------------< internal >--------------------------------------
+    /**
+     * {@inheritDoc}
+     */
+    public ForeignSegmentDocId createDocId(UUID uuid) throws IOException {
+        Term id = new Term(FieldNames.UUID, uuid.toString());
+        int doc;
+        long tick;
+        for (int i = 0; i < subReaders.length; i++) {
+            TermDocs docs = subReaders[i].termDocs(id);
+            try {
+                if (docs.next()) {
+                    doc = docs.doc();
+                    tick = subReaders[i].getCreationTick();
+                    return new ForeignSegmentDocId(doc, tick);
+                }
+            } finally {
+                docs.close();
+            }
+        }
+        return null;
+    }
 
+    /**
+     * {@inheritDoc}
+     */
+    public int getDocumentNumber(ForeignSegmentDocId docId) {
+        OffsetReader r = (OffsetReader) readersByCreationTick.get(
+                new Long(docId.getCreationTick()));
+        if (r != null && !r.reader.isDeleted(docId.getDocNumber())) {
+            return r.offset + docId.getDocNumber();
+        }
+        return -1;
+    }
+    
     /**
      * Returns the reader index for document <code>n</code>.
      * Implementation copied from lucene MultiReader class.

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocId.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocId.java?rev=601342&r1=601341&r2=601342&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocId.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocId.java
Wed Dec  5 06:19:18 2007
@@ -16,15 +16,10 @@
  */
 package org.apache.jackrabbit.core.query.lucene;
 
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.index.TermDocs;
 import org.apache.jackrabbit.uuid.UUID;
 
 import java.io.IOException;
 import java.util.BitSet;
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
 
 /**
  * Implements a document id which can be based on a Node uuid or a lucene
@@ -43,7 +38,7 @@
          * @param reader the index reader.
          * @return always <code>-1</code>.
          */
-        final int getDocumentNumber(IndexReader reader) {
+        final int getDocumentNumber(MultiIndexReader reader) {
             return -1;
         }
 
@@ -75,7 +70,7 @@
      *         if it is invalid (e.g. does not exist).
      * @throws IOException if an error occurs while reading from the index.
      */
-    abstract int getDocumentNumber(IndexReader reader) throws IOException;
+    abstract int getDocumentNumber(MultiIndexReader reader) throws IOException;
 
     /**
      * Applies an offset to this <code>DocId</code>. The returned <code>DocId</code>
@@ -141,7 +136,7 @@
         /**
          * @inheritDoc
          */
-        int getDocumentNumber(IndexReader reader) {
+        int getDocumentNumber(MultiIndexReader reader) {
             return docNumber;
         }
 
@@ -185,17 +180,10 @@
         private final long msb;
 
         /**
-         * The index reader that was used to calculate the document number.
-         * If <code>null</code> then the document number has not yet been
-         * calculated.
+         * The previously calculated foreign segment document id.
          */
-        private Reference reader;
-
-        /**
-         * The previously calculated document number.
-         */
-        private int docNumber;
-
+        private ForeignSegmentDocId doc;
+        
         /**
          * Creates a <code>DocId</code> based on a Node uuid.
          *
@@ -212,32 +200,26 @@
         /**
          * @inheritDoc
          */
-        int getDocumentNumber(IndexReader reader) throws IOException {
-            synchronized (this) {
-                if (this.reader != null && reader.equals(this.reader.get())) {
-                    return docNumber;
-                }
+        int getDocumentNumber(MultiIndexReader reader) throws IOException {
+            int realDoc = -1;
+            ForeignSegmentDocId segDocId = doc;
+            if (segDocId != null) {
+                realDoc = reader.getDocumentNumber(segDocId);
             }
-            Term id = new Term(FieldNames.UUID, new UUID(msb, lsb).toString());
-            TermDocs docs = reader.termDocs(id);
-            int doc = -1;
-            try {
-                if (docs.next()) {
-                    doc = docs.doc();
+            if (realDoc == -1) {
+                // Cached doc was invalid => create new one
+                segDocId = reader.createDocId(new UUID(msb, lsb));
+                if (segDocId != null) {
+                    realDoc = reader.getDocumentNumber(segDocId);
+                    doc = segDocId;
                 }
-            } finally {
-                docs.close();
-            }
-            synchronized (this) {
-                docNumber = doc;
-                this.reader = new WeakReference(reader);
             }
-            return doc;
+            return realDoc;
         }
 
         /**
          * This implementation will return <code>this</code>. Document number
is
-         * not known until resolved in {@link #getDocumentNumber(IndexReader)}.
+         * not known until resolved in {@link #getDocumentNumber(MultiIndexReader)}.
          *
          * @inheritDoc
          */

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ForeignSegmentDocId.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ForeignSegmentDocId.java?rev=601342&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ForeignSegmentDocId.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ForeignSegmentDocId.java
Wed Dec  5 06:19:18 2007
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+package org.apache.jackrabbit.core.query.lucene;
+
+import java.io.IOException;
+import java.util.BitSet;
+
+/**
+ * A <code>DocId</code> that contains a document number and the creation tick
+ * of the index segment.
+ */
+final class ForeignSegmentDocId extends DocId {
+
+    /**
+     * The document number.
+     */
+    private final int docNumber;
+
+    /**
+     * The creation tick of the index segment.
+     */
+    private final long creationTick;
+
+    /**
+     * Creates a <code>DocId</code> based on a document number in the index
+     * segment with the given <code>creationTick</code>.
+     *
+     * @param docNumber    the lucene document number.
+     * @param creationTick the creation tick of the index segment.
+     */
+    ForeignSegmentDocId(int docNumber, long creationTick) {
+        this.docNumber = docNumber;
+        this.creationTick = creationTick;
+    }
+
+    /**
+     * @return the document number in the foreign index segment.
+     */
+    int getDocNumber() {
+        return docNumber;
+    }
+
+    /**
+     * @return the creation tick of the foreign index segment.
+     */
+    long getCreationTick() {
+        return creationTick;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    int getDocumentNumber(MultiIndexReader reader) throws IOException {
+        return reader.getDocumentNumber(this);
+    }
+
+    /**
+     * This implementation will return <code>this</code>. Document number is
+     * not known until resolved in {@link #getDocumentNumber(MultiIndexReader)}.
+     *
+     * {@inheritDoc}
+     */
+    DocId applyOffset(int offset) {
+        return this;
+    }
+
+    /**
+     * Always returns <code>true</code> because this calls is in context of the
+     * index segment where this DocId lives. Within this segment this DocId is
+     * always valid. Whether the target of this DocId is valid can only be
+     * checked in the method {@link #getDocumentNumber(MultiIndexReader)}.
+     *
+     * @param deleted the deleted documents in the segment where this DocId
+     *                lives.
+     * @return always <code>true</code>.
+     */
+    boolean isValid(BitSet deleted) {
+        return true;
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ForeignSegmentDocId.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java?rev=601342&r1=601341&r2=601342&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
Wed Dec  5 06:19:18 2007
@@ -689,7 +689,7 @@
      * @return an <code>IndexReader</code>.
      * @throws IOException if an error occurs constructing the <code>IndexReader</code>.
      */
-    public IndexReader getIndexReader() throws IOException {
+    public CachingMultiReader getIndexReader() throws IOException {
         synchronized (updateMonitor) {
             if (multiReader != null) {
                 multiReader.incrementRefCount();

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndexReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndexReader.java?rev=601342&r1=601341&r2=601342&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndexReader.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndexReader.java
Wed Dec  5 06:19:18 2007
@@ -17,6 +17,9 @@
 package org.apache.jackrabbit.core.query.lucene;
 
 import org.apache.lucene.index.IndexReader;
+import org.apache.jackrabbit.uuid.UUID;
+
+import java.io.IOException;
 
 /**
  * <code>MultiIndexReader</code> exposes methods to get access to the contained
@@ -29,4 +32,25 @@
      *         <code>MultiIndexReader</code>.
      */
     public IndexReader[] getIndexReaders();
+
+    /**
+     * Creates a document id for the given <code>uuid</code>.
+     *
+     * @param uuid the uuid of the node.
+     * @return a foreign segment doc id or <code>null</code> if there is no node
+     *         with the given <code>uuid</code>.
+     * @throws IOException if an error occurs while reading from the index.
+     */
+    public ForeignSegmentDocId createDocId(UUID uuid) throws IOException;
+
+    /**
+     * Returns the document number for the passed <code>docId</code>. If the
id
+     * is invalid <code>-1</code> is returned.
+     *
+     * @param docId the document id to resolve.
+     * @return the document number or <code>-1</code> if it is invalid (e.g.
+     *         does not exist).
+     * @throws IOException if an error occurs while reading from the index.
+     */
+    public int getDocumentNumber(ForeignSegmentDocId docId) throws IOException;
 }

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=601342&r1=601341&r2=601342&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
Wed Dec  5 06:19:18 2007
@@ -98,6 +98,16 @@
     }
 
     /**
+     * Returns the tick value when the underlying {@link CachingIndexReader} was
+     * created.
+     *
+     * @return the creation tick for the underlying reader.
+     */
+    long getCreationTick() {
+        return reader.getCreationTick();
+    }
+
+    /**
      * 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>.

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java?rev=601342&r1=601341&r2=601342&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
Wed Dec  5 06:19:18 2007
@@ -770,19 +770,18 @@
     protected IndexReader getIndexReader(boolean includeSystemIndex)
             throws IOException {
         QueryHandler parentHandler = getContext().getParentHandler();
-        IndexReader parentReader = null;
+        CachingMultiReader parentReader = null;
         if (parentHandler instanceof SearchIndex && includeSystemIndex) {
             parentReader = ((SearchIndex) parentHandler).index.getIndexReader();
         }
 
-        IndexReader reader = index.getIndexReader();
+        CachingMultiReader reader = index.getIndexReader();
         if (parentReader != null) {
-            // todo FIXME not type safe
-            CachingMultiReader[] readers = {(CachingMultiReader) reader,
-                                            (CachingMultiReader) parentReader};
-            reader = new CombinedIndexReader(readers);
+            CachingMultiReader[] readers = {reader, parentReader};
+            return new CombinedIndexReader(readers);
+        } else {
+            return reader;
         }
-        return reader;
     }
 
     /**
@@ -1190,6 +1189,34 @@
                 hash = 31 * hash + subReaders[i].hashCode();
             }
             return hash;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public ForeignSegmentDocId createDocId(UUID uuid) throws IOException {
+            for (int i = 0; i < subReaders.length; i++) {
+                CachingMultiReader subReader = subReaders[i];
+                ForeignSegmentDocId doc = subReader.createDocId(uuid);
+                if (doc != null) {
+                    return doc;
+                }
+            }
+            return null;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public int getDocumentNumber(ForeignSegmentDocId docId) {
+            for (int i = 0; i < subReaders.length; i++) {
+                CachingMultiReader subReader = subReaders[i];
+                int realDoc = subReader.getDocumentNumber(docId);
+                if (realDoc >= 0) {
+                    return realDoc;
+                }
+            }
+            return -1;
         }
     }
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedIndexReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedIndexReader.java?rev=601342&r1=601341&r2=601342&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedIndexReader.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedIndexReader.java
Wed Dec  5 06:19:18 2007
@@ -55,6 +55,16 @@
     }
 
     /**
+     * Returns the tick value when the underlying {@link CachingIndexReader} was
+     * created.
+     *
+     * @return the creation tick for the underlying reader.
+     */
+    long getCreationTick() {
+        return getBase().getCreationTick();
+    }
+
+    /**
      * 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).



Mime
View raw message