lucene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gol...@apache.org
Subject cvs commit: jakarta-lucene/src/java/org/apache/lucene/index MultiReader.java FilterIndexReader.java IndexReader.java SegmentReader.java
Date Fri, 16 Apr 2004 09:17:06 GMT
goller      2004/04/16 02:17:05

  Modified:    src/test/org/apache/lucene/index TestMultiReader.java
                        TestIndexReader.java TestFilterIndexReader.java
               src/java/org/apache/lucene/index MultiReader.java
                        FilterIndexReader.java IndexReader.java
                        SegmentReader.java
  Log:
  restructuring of IndexReader, SegmentReader,
  and Multireader in order to improve directory locking
  
  Revision  Changes    Path
  1.3       +98 -98    jakarta-lucene/src/test/org/apache/lucene/index/TestMultiReader.java
  
  Index: TestMultiReader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-lucene/src/test/org/apache/lucene/index/TestMultiReader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestMultiReader.java	29 Mar 2004 22:48:06 -0000	1.2
  +++ TestMultiReader.java	16 Apr 2004 09:17:05 -0000	1.3
  @@ -1,98 +1,98 @@
  -package org.apache.lucene.index;
  -
  -/**
  - * Copyright 2004 The Apache Software Foundation
  - *
  - * Licensed 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.
  - */
  -
  -import junit.framework.TestCase;
  -import org.apache.lucene.document.Document;
  -import org.apache.lucene.store.Directory;
  -import org.apache.lucene.store.RAMDirectory;
  -
  -import java.io.IOException;
  -
  -public class TestMultiReader extends TestCase {
  -  private Directory dir = new RAMDirectory();
  -  private Document doc1 = new Document();
  -  private Document doc2 = new Document();
  -  private SegmentReader reader1;
  -  private SegmentReader reader2;
  -  private SegmentReader [] readers = new SegmentReader[2];
  -  private SegmentInfos sis = new SegmentInfos();
  -  
  -  public TestMultiReader(String s) {
  -    super(s);
  -  }
  -
  -  protected void setUp() {
  -    DocHelper.setupDoc(doc1);
  -    DocHelper.setupDoc(doc2);
  -    DocHelper.writeDoc(dir, "seg-1", doc1);
  -    DocHelper.writeDoc(dir, "seg-2", doc2);
  -    
  -    try {
  -      sis.write(dir);
  -      reader1 = new SegmentReader(new SegmentInfo("seg-1", 1, dir));
  -      reader2 = new SegmentReader(new SegmentInfo("seg-2", 1, dir));
  -      readers[0] = reader1;
  -      readers[1] = reader2;      
  -    } catch (IOException e) {
  -      e.printStackTrace();
  -    }
  -  }
  -/*IndexWriter writer  = new IndexWriter(dir, new WhitespaceAnalyzer(), true);
  -      writer.addDocument(doc1);
  -      writer.addDocument(doc2);
  -      writer.close();*/
  -  protected void tearDown() {
  -
  -  }
  -  
  -  public void test() {
  -    assertTrue(dir != null);
  -    assertTrue(reader1 != null);
  -    assertTrue(reader2 != null);
  -    assertTrue(sis != null);
  -  }    
  -
  -  public void testDocument() {
  -    try {    
  -      sis.read(dir);
  -      MultiReader reader = new MultiReader(dir, readers);
  -      assertTrue(reader != null);
  -      Document newDoc1 = reader.document(0);
  -      assertTrue(newDoc1 != null);
  -      assertTrue(DocHelper.numFields(newDoc1) == DocHelper.numFields(doc1) - 2);
  -      Document newDoc2 = reader.document(1);
  -      assertTrue(newDoc2 != null);
  -      assertTrue(DocHelper.numFields(newDoc2) == DocHelper.numFields(doc2) - 2);
  -      TermFreqVector vector = reader.getTermFreqVector(0, DocHelper.TEXT_FIELD_2_KEY);
  -      assertTrue(vector != null);
  -    } catch (IOException e) {
  -      e.printStackTrace();
  -      assertTrue(false);
  -    }
  -  }
  -  
  -  public void testTermVectors() {
  -    try {
  -      MultiReader reader = new MultiReader(dir, readers);
  -      assertTrue(reader != null);
  -    } catch (IOException e) {
  -      e.printStackTrace();
  -      assertTrue(false);
  -    }
  -  }    
  -}
  +package org.apache.lucene.index;
  +
  +/**
  + * Copyright 2004 The Apache Software Foundation
  + *
  + * Licensed 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.
  + */
  +
  +import junit.framework.TestCase;
  +import org.apache.lucene.document.Document;
  +import org.apache.lucene.store.Directory;
  +import org.apache.lucene.store.RAMDirectory;
  +
  +import java.io.IOException;
  +
  +public class TestMultiReader extends TestCase {
  +  private Directory dir = new RAMDirectory();
  +  private Document doc1 = new Document();
  +  private Document doc2 = new Document();
  +  private SegmentReader reader1;
  +  private SegmentReader reader2;
  +  private SegmentReader [] readers = new SegmentReader[2];
  +  private SegmentInfos sis = new SegmentInfos();
  +  
  +  public TestMultiReader(String s) {
  +    super(s);
  +  }
  +
  +  protected void setUp() {
  +    DocHelper.setupDoc(doc1);
  +    DocHelper.setupDoc(doc2);
  +    DocHelper.writeDoc(dir, "seg-1", doc1);
  +    DocHelper.writeDoc(dir, "seg-2", doc2);
  +    
  +    try {
  +      sis.write(dir);
  +      reader1 = new SegmentReader(new SegmentInfo("seg-1", 1, dir));
  +      reader2 = new SegmentReader(new SegmentInfo("seg-2", 1, dir));
  +      readers[0] = reader1;
  +      readers[1] = reader2;      
  +    } catch (IOException e) {
  +      e.printStackTrace();
  +    }
  +  }
  +/*IndexWriter writer  = new IndexWriter(dir, new WhitespaceAnalyzer(), true);
  +      writer.addDocument(doc1);
  +      writer.addDocument(doc2);
  +      writer.close();*/
  +  protected void tearDown() {
  +
  +  }
  +  
  +  public void test() {
  +    assertTrue(dir != null);
  +    assertTrue(reader1 != null);
  +    assertTrue(reader2 != null);
  +    assertTrue(sis != null);
  +  }    
  +
  +  public void testDocument() {
  +    try {    
  +      sis.read(dir);
  +      MultiReader reader = new MultiReader(dir, sis, false, readers);
  +      assertTrue(reader != null);
  +      Document newDoc1 = reader.document(0);
  +      assertTrue(newDoc1 != null);
  +      assertTrue(DocHelper.numFields(newDoc1) == DocHelper.numFields(doc1) - 2);
  +      Document newDoc2 = reader.document(1);
  +      assertTrue(newDoc2 != null);
  +      assertTrue(DocHelper.numFields(newDoc2) == DocHelper.numFields(doc2) - 2);
  +      TermFreqVector vector = reader.getTermFreqVector(0, DocHelper.TEXT_FIELD_2_KEY);
  +      assertTrue(vector != null);
  +    } catch (IOException e) {
  +      e.printStackTrace();
  +      assertTrue(false);
  +    }
  +  }
  +  
  +  public void testTermVectors() {
  +    try {
  +      MultiReader reader = new MultiReader(dir, sis, false, readers);
  +      assertTrue(reader != null);
  +    } catch (IOException e) {
  +      e.printStackTrace();
  +      assertTrue(false);
  +    }
  +  }    
  +}
  
  
  
  1.7       +21 -5     jakarta-lucene/src/test/org/apache/lucene/index/TestIndexReader.java
  
  Index: TestIndexReader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-lucene/src/test/org/apache/lucene/index/TestIndexReader.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- TestIndexReader.java	29 Mar 2004 22:48:06 -0000	1.6
  +++ TestIndexReader.java	16 Apr 2004 09:17:05 -0000	1.7
  @@ -173,8 +173,15 @@
       }
   
   
  +    public void testDeleteReaderWriterConflictUnoptimized() throws IOException{
  +      deleteReaderWriterConflict(false);
  +    }
  +    
  +    public void testDeleteReaderWriterConflictOptimized() throws IOException{
  +        deleteReaderWriterConflict(true);
  +    }
   
  -    public void testDeleteReaderWriterConflict() throws IOException
  +    private void deleteReaderWriterConflict(boolean optimize) throws IOException
       {
           //Directory dir = new RAMDirectory();
           Directory dir = getDirectory(true);
  @@ -210,7 +217,8 @@
           // searchers. Because of this, deletions made via a previously open
           // reader, which would be applied to that reader's segment, are lost
           // for subsequent searchers/readers
  -        writer.optimize();
  +        if(optimize)
  +          writer.optimize();
           writer.close();
   
           // The reader should not see the new data
  @@ -288,8 +296,15 @@
           dir = getDirectory(true);
       }
   
  -
  -    public void testDeleteReaderReaderConflict() throws IOException
  +    public void testDeleteReaderReaderConflictUnoptimized() throws IOException{
  +      deleteReaderReaderConflict(false);
  +    }
  +    
  +    public void testDeleteReaderReaderConflictOptimized() throws IOException{
  +      deleteReaderReaderConflict(true);
  +    }
  +    
  +    private void deleteReaderReaderConflict(boolean optimize) throws IOException
       {
           Directory dir = getDirectory(true);
   
  @@ -307,7 +322,8 @@
               addDoc(writer, searchTerm2.text());
               addDoc(writer, searchTerm3.text());
           }
  -        writer.optimize();
  +        if(optimize)
  +          writer.optimize();
           writer.close();
   
           // OPEN TWO READERS
  
  
  
  1.4       +2 -2      jakarta-lucene/src/test/org/apache/lucene/index/TestFilterIndexReader.java
  
  Index: TestFilterIndexReader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-lucene/src/test/org/apache/lucene/index/TestFilterIndexReader.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestFilterIndexReader.java	29 Mar 2004 22:48:06 -0000	1.3
  +++ TestFilterIndexReader.java	16 Apr 2004 09:17:05 -0000	1.4
  @@ -81,12 +81,12 @@
   
       /** Filter terms with TestTermEnum. */
       public TermEnum terms() throws IOException {
  -      return new TestTermEnum(in.terms());
  +      return new TestTermEnum(baseReader.terms());
       }
   
       /** Filter positions with TestTermPositions. */
       public TermPositions termPositions() throws IOException {
  -      return new TestTermPositions(in.termPositions());
  +      return new TestTermPositions(baseReader.termPositions());
       }
     }
   
  
  
  
  1.4       +63 -46    jakarta-lucene/src/java/org/apache/lucene/index/MultiReader.java
  
  Index: MultiReader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-lucene/src/java/org/apache/lucene/index/MultiReader.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MultiReader.java	29 Mar 2004 22:48:02 -0000	1.3
  +++ MultiReader.java	16 Apr 2004 09:17:05 -0000	1.4
  @@ -31,32 +31,44 @@
    * @version $Id$
    */
   public class MultiReader extends IndexReader {
  -  private IndexReader[] readers;
  +  private IndexReader[] subReaders;
     private int[] starts;                           // 1st docno for each segment
     private Hashtable normsCache = new Hashtable();
     private int maxDoc = 0;
     private int numDocs = -1;
     private boolean hasDeletions = false;
   
  -  /** Construct reading the named set of readers. */
  -  public MultiReader(IndexReader[] readers) throws IOException {
  -    this(readers.length == 0 ? null : readers[0].directory(), readers);
  + /**
  +  * <p>Construct a MultiReader aggregating the named set of (sub)readers.
  +  * Directory locking for delete, undeleteAll, and setNorm operations is
  +  * left to the subreaders. </p>
  +  * <p>Note that all subreaders are closed if this Multireader is closed.</p>
  +  * @param readers set of (sub)readers
  +  * @throws IOException
  +  */
  +  public MultiReader(IndexReader[] subReaders) throws IOException {
  +    super(subReaders.length == 0 ? null : subReaders[0].directory());
  +    initialize(subReaders);
     }
   
     /** Construct reading the named set of readers. */
  -  public MultiReader(Directory directory, IndexReader[] readers)
  +  MultiReader(Directory directory, SegmentInfos sis, boolean closeDirectory, IndexReader[]
subReaders)
       throws IOException {
  -    super(directory);
  -    this.readers = readers;
  -    starts = new int[readers.length + 1];	  // build starts array
  -    for (int i = 0; i < readers.length; i++) {
  +    super(directory, sis, closeDirectory);
  +    initialize(subReaders);
  +  }
  +    
  +  private void initialize(IndexReader[] subReaders) throws IOException{
  +    this.subReaders = subReaders;
  +    starts = new int[subReaders.length + 1];	  // build starts array
  +    for (int i = 0; i < subReaders.length; i++) { 
         starts[i] = maxDoc;
  -      maxDoc += readers[i].maxDoc();		  // compute maxDocs
  +      maxDoc += subReaders[i].maxDoc();		  // compute maxDocs
   
  -      if (readers[i].hasDeletions())
  +      if (subReaders[i].hasDeletions())
           hasDeletions = true;
       }
  -    starts[readers.length] = maxDoc;
  +    starts[subReaders.length] = maxDoc;
     }
   
   
  @@ -69,20 +81,20 @@
     public TermFreqVector[] getTermFreqVectors(int n)
             throws IOException {
       int i = readerIndex(n);			  // find segment num
  -    return readers[i].getTermFreqVectors(n - starts[i]); // dispatch to segment
  +    return subReaders[i].getTermFreqVectors(n - starts[i]); // dispatch to segment
     }
   
     public TermFreqVector getTermFreqVector(int n, String field)
             throws IOException {
       int i = readerIndex(n);			  // find segment num
  -    return readers[i].getTermFreqVector(n - starts[i], field);
  +    return subReaders[i].getTermFreqVector(n - starts[i], field);
     }
   
     public synchronized int numDocs() {
       if (numDocs == -1) {			  // check cache
         int n = 0;				  // cache miss--recompute
  -      for (int i = 0; i < readers.length; i++)
  -	n += readers[i].numDocs();		  // sum from readers
  +      for (int i = 0; i < subReaders.length; i++)
  +	n += subReaders[i].numDocs();		  // sum from readers
         numDocs = n;
       }
       return numDocs;
  @@ -94,32 +106,32 @@
   
     public Document document(int n) throws IOException {
       int i = readerIndex(n);			  // find segment num
  -    return readers[i].document(n - starts[i]);	  // dispatch to segment reader
  +    return subReaders[i].document(n - starts[i]);	  // dispatch to segment reader
     }
   
     public boolean isDeleted(int n) {
       int i = readerIndex(n);			  // find segment num
  -    return readers[i].isDeleted(n - starts[i]);	  // dispatch to segment reader
  +    return subReaders[i].isDeleted(n - starts[i]);	  // dispatch to segment reader
     }
   
     public boolean hasDeletions() { return hasDeletions; }
   
  -  protected synchronized void doDelete(int n) throws IOException {
  +  protected void doDelete(int n) throws IOException {
       numDocs = -1;				  // invalidate cache
       int i = readerIndex(n);			  // find segment num
  -    readers[i].doDelete(n - starts[i]);		  // dispatch to segment reader
  +    subReaders[i].delete(n - starts[i]);		  // dispatch to segment reader
       hasDeletions = true;
     }
   
  -  public void undeleteAll() throws IOException {
  -    for (int i = 0; i < readers.length; i++)
  -      readers[i].undeleteAll();
  +  protected void doUndeleteAll() throws IOException {
  +    for (int i = 0; i < subReaders.length; i++)
  +      subReaders[i].undeleteAll();
       hasDeletions = false;
     }
   
     private int readerIndex(int n) {	  // find reader for doc n:
       int lo = 0;					  // search starts array
  -    int hi = readers.length - 1;                  // for first element less
  +    int hi = subReaders.length - 1;                  // for first element less
   
       while (hi >= lo) {
         int mid = (lo + hi) >> 1;
  @@ -129,7 +141,7 @@
         else if (n > midValue)
   	lo = mid + 1;
         else {                                      // found a match
  -        while (mid+1 < readers.length && starts[mid+1] == midValue) {
  +        while (mid+1 < subReaders.length && starts[mid+1] == midValue) {
             mid++;                                  // scan to last match
           }
   	return mid;
  @@ -144,8 +156,8 @@
         return bytes;				  // cache hit
   
       bytes = new byte[maxDoc()];
  -    for (int i = 0; i < readers.length; i++)
  -      readers[i].norms(field, bytes, starts[i]);
  +    for (int i = 0; i < subReaders.length; i++)
  +      subReaders[i].norms(field, bytes, starts[i]);
       normsCache.put(field, bytes);		  // update cache
       return bytes;
     }
  @@ -156,43 +168,48 @@
       if (bytes != null)                            // cache hit
         System.arraycopy(bytes, 0, result, offset, maxDoc());
   
  -    for (int i = 0; i < readers.length; i++)      // read from segments
  -      readers[i].norms(field, result, offset + starts[i]);
  +    for (int i = 0; i < subReaders.length; i++)      // read from segments
  +      subReaders[i].norms(field, result, offset + starts[i]);
     }
   
  -  public synchronized void setNorm(int n, String field, byte value)
  +  protected void doSetNorm(int n, String field, byte value)
       throws IOException {
       normsCache.remove(field);                     // clear cache
       int i = readerIndex(n);			  // find segment num
  -    readers[i].setNorm(n-starts[i], field, value); // dispatch
  +    subReaders[i].setNorm(n-starts[i], field, value); // dispatch
     }
   
     public TermEnum terms() throws IOException {
  -    return new MultiTermEnum(readers, starts, null);
  +    return new MultiTermEnum(subReaders, starts, null);
     }
   
     public TermEnum terms(Term term) throws IOException {
  -    return new MultiTermEnum(readers, starts, term);
  +    return new MultiTermEnum(subReaders, starts, term);
     }
   
     public int docFreq(Term t) throws IOException {
       int total = 0;				  // sum freqs in segments
  -    for (int i = 0; i < readers.length; i++)
  -      total += readers[i].docFreq(t);
  +    for (int i = 0; i < subReaders.length; i++)
  +      total += subReaders[i].docFreq(t);
       return total;
     }
   
     public TermDocs termDocs() throws IOException {
  -    return new MultiTermDocs(readers, starts);
  +    return new MultiTermDocs(subReaders, starts);
     }
   
     public TermPositions termPositions() throws IOException {
  -    return new MultiTermPositions(readers, starts);
  +    return new MultiTermPositions(subReaders, starts);
  +  }
  +  
  +  protected void doCommit() throws IOException {
  +    for (int i = 0; i < subReaders.length; i++)
  +      subReaders[i].commit();
     }
   
     protected synchronized void doClose() throws IOException {
  -    for (int i = 0; i < readers.length; i++)
  -      readers[i].close();
  +    for (int i = 0; i < subReaders.length; i++)
  +      subReaders[i].close();
     }
   
     /**
  @@ -201,8 +218,8 @@
     public Collection getFieldNames() throws IOException {
       // maintain a unique set of field names
       Set fieldSet = new HashSet();
  -    for (int i = 0; i < readers.length; i++) {
  -      IndexReader reader = readers[i];
  +    for (int i = 0; i < subReaders.length; i++) {
  +      IndexReader reader = subReaders[i];
         Collection names = reader.getFieldNames();
         // iterate through the field names and add them to the set
         for (Iterator iterator = names.iterator(); iterator.hasNext();) {
  @@ -219,8 +236,8 @@
     public Collection getFieldNames(boolean indexed) throws IOException {
       // maintain a unique set of field names
       Set fieldSet = new HashSet();
  -    for (int i = 0; i < readers.length; i++) {
  -      IndexReader reader = readers[i];
  +    for (int i = 0; i < subReaders.length; i++) {
  +      IndexReader reader = subReaders[i];
         Collection names = reader.getFieldNames(indexed);
         fieldSet.addAll(names);
       }
  @@ -230,8 +247,8 @@
     public Collection getIndexedFieldNames(boolean storedTermVector) {
       // maintain a unique set of field names
       Set fieldSet = new HashSet();
  -    for (int i = 0; i < readers.length; i++) {
  -        IndexReader reader = readers[i];
  +    for (int i = 0; i < subReaders.length; i++) {
  +        IndexReader reader = subReaders[i];
           Collection names = reader.getIndexedFieldNames(storedTermVector);
           fieldSet.addAll(names);
       }
  
  
  
  1.9       +34 -27    jakarta-lucene/src/java/org/apache/lucene/index/FilterIndexReader.java
  
  Index: FilterIndexReader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-lucene/src/java/org/apache/lucene/index/FilterIndexReader.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- FilterIndexReader.java	29 Mar 2004 22:48:02 -0000	1.8
  +++ FilterIndexReader.java	16 Apr 2004 09:17:05 -0000	1.9
  @@ -73,61 +73,68 @@
       public void close() throws IOException { in.close(); }
     }
   
  -  protected IndexReader in;
  +  protected IndexReader baseReader;
   
  -  public FilterIndexReader(IndexReader in) {
  -    super(in.directory());
  -    segmentInfos = in.segmentInfos;
  -    this.in = in;
  +  /**
  +   * <p>Construct a FilterIndexReader based on the specified base reader.
  +   * Directory locking for delete, undeleteAll, and setNorm operations is
  +   * left to the base reader.</p>
  +   * <p>Note that base reader is closed if this FilterIndexReader is closed.</p>
  +   * @param in specified base reader.
  +   */
  +  public FilterIndexReader(IndexReader baseReader) {
  +    super(baseReader.directory());
  +    this.baseReader = baseReader;
     }
   
     public TermFreqVector[] getTermFreqVectors(int docNumber)
             throws IOException {
  -    return in.getTermFreqVectors(docNumber);
  +    return baseReader.getTermFreqVectors(docNumber);
     }
   
     public TermFreqVector getTermFreqVector(int docNumber, String field)
             throws IOException {
  -    return in.getTermFreqVector(docNumber, field);
  +    return baseReader.getTermFreqVector(docNumber, field);
     }
   
  -  public int numDocs() { return in.numDocs(); }
  -  public int maxDoc() { return in.maxDoc(); }
  +  public int numDocs() { return baseReader.numDocs(); }
  +  public int maxDoc() { return baseReader.maxDoc(); }
   
  -  public Document document(int n) throws IOException { return in.document(n); }
  +  public Document document(int n) throws IOException { return baseReader.document(n); }
   
  -  public boolean isDeleted(int n) { return in.isDeleted(n); }
  -  public boolean hasDeletions() { return in.hasDeletions(); }
  -  public void undeleteAll() throws IOException { in.undeleteAll(); }
  +  public boolean isDeleted(int n) { return baseReader.isDeleted(n); }
  +  public boolean hasDeletions() { return baseReader.hasDeletions(); }
  +  protected void doUndeleteAll() throws IOException { baseReader.undeleteAll(); }
   
  -  public byte[] norms(String f) throws IOException { return in.norms(f); }
  +  public byte[] norms(String f) throws IOException { return baseReader.norms(f); }
     public void norms(String f, byte[] bytes, int offset) throws IOException {
  -    in.norms(f, bytes, offset);
  +    baseReader.norms(f, bytes, offset);
     }
  -  public void setNorm(int d, String f, byte b) throws IOException {
  -    in.setNorm(d, f, b);
  +  protected void doSetNorm(int d, String f, byte b) throws IOException {
  +    baseReader.setNorm(d, f, b);
     }
   
  -  public TermEnum terms() throws IOException { return in.terms(); }
  -  public TermEnum terms(Term t) throws IOException { return in.terms(t); }
  +  public TermEnum terms() throws IOException { return baseReader.terms(); }
  +  public TermEnum terms(Term t) throws IOException { return baseReader.terms(t); }
   
  -  public int docFreq(Term t) throws IOException { return in.docFreq(t); }
  +  public int docFreq(Term t) throws IOException { return baseReader.docFreq(t); }
   
  -  public TermDocs termDocs() throws IOException { return in.termDocs(); }
  +  public TermDocs termDocs() throws IOException { return baseReader.termDocs(); }
   
     public TermPositions termPositions() throws IOException {
  -    return in.termPositions();
  +    return baseReader.termPositions();
     }
   
  -  protected void doDelete(int n) throws IOException { in.doDelete(n); }
  -  protected void doClose() throws IOException { in.doClose(); }
  +  protected void doDelete(int n) throws IOException { baseReader.delete(n); }
  +  protected void doCommit() throws IOException { baseReader.commit(); }
  +  protected void doClose() throws IOException { baseReader.close(); }
   
     public Collection getFieldNames() throws IOException {
  -    return in.getFieldNames();
  +    return baseReader.getFieldNames();
     }
   
     public Collection getFieldNames(boolean indexed) throws IOException {
  -    return in.getFieldNames(indexed);
  +    return baseReader.getFieldNames(indexed);
     }
   
     /**
  @@ -137,6 +144,6 @@
      * @return Collection of Strings indicating the names of the fields
      */
     public Collection getIndexedFieldNames(boolean storedTermVector) {
  -    return in.getIndexedFieldNames(storedTermVector);
  +    return baseReader.getIndexedFieldNames(storedTermVector);
     }
   }
  
  
  
  1.30      +125 -27   jakarta-lucene/src/java/org/apache/lucene/index/IndexReader.java
  
  Index: IndexReader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-lucene/src/java/org/apache/lucene/index/IndexReader.java,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- IndexReader.java	29 Mar 2004 22:48:02 -0000	1.29
  +++ IndexReader.java	16 Apr 2004 09:17:05 -0000	1.30
  @@ -44,31 +44,69 @@
    @version $Id$
   */
   public abstract class IndexReader {
  +  
  +  /**
  +   * Constructor used if IndexReader is not owner of its directory. 
  +   * This is used for IndexReaders that are used within other IndexReaders that take care
or locking directories.
  +   * 
  +   * @param directory Directory where IndexReader files reside.
  +   */
     protected IndexReader(Directory directory) {
       this.directory = directory;
  -    stale = false;
       segmentInfos = null;
  +    directoryOwner = false;
  +    closeDirectory = false;
  +    stale = false;
  +    hasChanges = false;
  +    writeLock = null;
  +  }
  +  
  +  /**
  +   * Constructor used if IndexReader is owner of its directory.
  +   * If IndexReader is owner of its directory, it locks its directory in case of write
operations.
  +   * 
  +   * @param directory Directory where IndexReader files reside.
  +   * @param segmentInfos Used for write-l
  +   * @param closeDirectory
  +   */
  +  protected IndexReader(Directory directory, SegmentInfos segmentInfos, boolean closeDirectory)
{
  +    this.directory = directory;
  +    this.segmentInfos = segmentInfos;
  +    directoryOwner = true;
  +    this.closeDirectory = closeDirectory;
  +    stale = false;
  +    hasChanges = false;
  +    writeLock = null;
     }
   
  -  private Directory directory;
  +  final private Directory directory;
  +  
  +  final private boolean directoryOwner;
  +  final private SegmentInfos segmentInfos;
     private Lock writeLock;
  -  SegmentInfos segmentInfos = null;
  -  private boolean stale = false;
  +  private boolean stale;
  +  private boolean hasChanges;
  +  
  +  final private boolean closeDirectory;
   
     /** Returns an IndexReader reading the index in an FSDirectory in the named
      path. */
     public static IndexReader open(String path) throws IOException {
  -    return open(FSDirectory.getDirectory(path, false));
  +    return open(FSDirectory.getDirectory(path, false), true);
     }
   
     /** Returns an IndexReader reading the index in an FSDirectory in the named
      path. */
     public static IndexReader open(File path) throws IOException {
  -    return open(FSDirectory.getDirectory(path, false));
  +    return open(FSDirectory.getDirectory(path, false), true);
     }
  -
  +  
     /** Returns an IndexReader reading the index in the given Directory. */
     public static IndexReader open(final Directory directory) throws IOException {
  +    return open(directory, false);
  +  }
  +
  +  private static IndexReader open(final Directory directory, final boolean closeDirectory)
throws IOException {
       synchronized (directory) {			  // in- & inter-process sync
         return (IndexReader)new Lock.With(
             directory.makeLock(IndexWriter.COMMIT_LOCK_NAME),
  @@ -77,12 +115,12 @@
               SegmentInfos infos = new SegmentInfos();
               infos.read(directory);
               if (infos.size() == 1) {		  // index is optimized
  -              return new SegmentReader(infos, infos.info(0), true);
  +              return new SegmentReader(infos, infos.info(0), closeDirectory);
               } else {
                 IndexReader[] readers = new IndexReader[infos.size()];
                 for (int i = 0; i < infos.size(); i++)
  -                readers[i] = new SegmentReader(infos, infos.info(i), i==infos.size()-1);
  -              return new MultiReader(directory, readers);
  +                readers[i] = new SegmentReader(infos.info(i));
  +              return new MultiReader(directory, infos, closeDirectory, readers);
               }
             }
           }.run();
  @@ -272,7 +310,16 @@
      * @see #norms(String)
      * @see Similarity#decodeNorm(byte)
      */
  -  public abstract void setNorm(int doc, String field, byte value)
  +  public final synchronized  void setNorm(int doc, String field, byte value)
  +          throws IOException{
  +    if(directoryOwner)
  +      aquireWriteLock();
  +    doSetNorm(doc, field, value);
  +    hasChanges = true;
  +  }
  +          
  +  /** Implements setNorm in subclass.*/
  +  protected abstract void doSetNorm(int doc, String field, byte value) 
             throws IOException;
   
     /** Expert: Resets the normalization factor for the named field of the named
  @@ -346,16 +393,15 @@
     /** Returns an unpositioned {@link TermPositions} enumerator. */
     public abstract TermPositions termPositions() throws IOException;
   
  -  /** Deletes the document numbered <code>docNum</code>.  Once a document is
  -   deleted it will not appear in TermDocs or TermPostitions enumerations.
  -   Attempts to read its field with the {@link #document}
  -   method will result in an error.  The presence of this document may still be
  -   reflected in the {@link #docFreq} statistic, though
  -   this will be corrected eventually as the index is further modified.
  +  /**
  +   * Trys to acquire the WriteLock on this directory.
  +   * this method is only valid if this IndexReader is directory owner.
  +   * 
  +   * @throws IOException If WriteLock cannot be acquired.
      */
  -  public final synchronized void delete(int docNum) throws IOException {
  +  private void aquireWriteLock() throws IOException {
       if (stale)
  -      throw new IOException("IndexReader out of date and no longer valid for deletion");
  +      throw new IOException("IndexReader out of date and no longer valid for delete, undelete,
or setNorm operations");
   
       if (writeLock == null) {
         Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME);
  @@ -365,14 +411,27 @@
   
         // we have to check whether index has changed since this reader was opened.
         // if so, this reader is no longer valid for deletion
  -      if (segmentInfos != null && SegmentInfos.readCurrentVersion(directory) >
segmentInfos.getVersion()) {
  +      if (SegmentInfos.readCurrentVersion(directory) > segmentInfos.getVersion()) {
           stale = true;
           this.writeLock.release();
           this.writeLock = null;
  -        throw new IOException("IndexReader out of date and no longer valid for deletion");
  +        throw new IOException("IndexReader out of date and no longer valid for delete,
undelete, or setNorm operations");
         }
       }
  +  }
  +  
  +  /** Deletes the document numbered <code>docNum</code>.  Once a document is
  +   deleted it will not appear in TermDocs or TermPostitions enumerations.
  +   Attempts to read its field with the {@link #document}
  +   method will result in an error.  The presence of this document may still be
  +   reflected in the {@link #docFreq} statistic, though
  +   this will be corrected eventually as the index is further modified.
  +   */
  +  public final synchronized void delete(int docNum) throws IOException {
  +    if(directoryOwner)
  +      aquireWriteLock();
       doDelete(docNum);
  +    hasChanges = true;
     }
   
     /** Implements deletion of the document numbered <code>docNum</code>.
  @@ -402,19 +461,58 @@
     }
   
     /** Undeletes all documents currently marked as deleted in this index.*/
  -  public abstract void undeleteAll() throws IOException;
  +  public final synchronized void undeleteAll() throws IOException{
  +    if(directoryOwner)
  +      aquireWriteLock();
  +    doUndeleteAll();
  +    hasChanges = true;
  +  }
  +  
  +  /** Implements actual undeleteAll() in subclass. */
  +  protected abstract void doUndeleteAll() throws IOException;
   
     /**
  +   * Commit changes resulting from delete, undeleteAll, or setNorm operations
  +   * 
  +   * @throws IOException
  +   */
  +  protected final synchronized void commit() throws IOException{
  +    if(hasChanges){
  +      if(directoryOwner){
  +        synchronized (directory) {      // in- & inter-process sync
  +           new Lock.With(directory.makeLock(IndexWriter.COMMIT_LOCK_NAME),
  +                   IndexWriter.COMMIT_LOCK_TIMEOUT) {
  +             public Object doBody() throws IOException {
  +               doCommit();
  +               segmentInfos.write(directory);
  +               return null;
  +             }
  +           }.run();
  +         }
  +        if (writeLock != null) {
  +          writeLock.release();  // release write lock
  +          writeLock = null;
  +        }
  +      }
  +      else
  +        doCommit();
  +    }
  +    hasChanges = false;
  +  }
  +  
  +  /** Implements commit. */
  +  protected abstract void doCommit() throws IOException;
  +  
  +  /**
      * Closes files associated with this index.
      * Also saves any new deletions to disk.
      * No other methods should be called after this has been called.
      */
     public final synchronized void close() throws IOException {
  +    commit();
       doClose();
  -    if (writeLock != null) {
  -      writeLock.release();  // release write lock
  -      writeLock = null;
  -    }
  +    if(closeDirectory)
  +      directory.close();
     }
   
     /** Implements close. */
  
  
  
  1.21      +45 -63    jakarta-lucene/src/java/org/apache/lucene/index/SegmentReader.java
  
  Index: SegmentReader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-lucene/src/java/org/apache/lucene/index/SegmentReader.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- SegmentReader.java	29 Mar 2004 22:48:02 -0000	1.20
  +++ SegmentReader.java	16 Apr 2004 09:17:05 -0000	1.21
  @@ -37,7 +37,6 @@
    * @version $Id$
    */
   final class SegmentReader extends IndexReader {
  -  private boolean closeDirectory = false;
     private String segment;
   
     FieldInfos fieldInfos;
  @@ -49,6 +48,7 @@
     BitVector deletedDocs = null;
     private boolean deletedDocsDirty = false;
     private boolean normsDirty = false;
  +  private boolean undeleteAll = false;
   
     InputStream freqStream;
     InputStream proxStream;
  @@ -57,13 +57,18 @@
     CompoundFileReader cfsReader;
   
     private class Norm {
  -    public Norm(InputStream in) { this.in = in; }
  +    public Norm(InputStream in, int number) 
  +    { 
  +      this.in = in; 
  +      this.number = number;
  +    }
   
       private InputStream in;
       private byte[] bytes;
       private boolean dirty;
  +    private int number;
   
  -    private void reWrite(String name) throws IOException {
  +    private void reWrite() throws IOException {
         // NOTE: norms are re-written in regular directory, not cfs
         OutputStream out = directory().createFile(segment + ".tmp");
         try {
  @@ -71,7 +76,7 @@
         } finally {
           out.close();
         }
  -      String fileName = segment + ".f" + fieldInfos.fieldNumber(name);
  +      String fileName = segment + ".f" + number;
         directory().renameFile(segment + ".tmp", fileName);
         this.dirty = false;
       }
  @@ -81,14 +86,17 @@
   
     SegmentReader(SegmentInfos sis, SegmentInfo si, boolean closeDir)
             throws IOException {
  -    this(si);
  -    closeDirectory = closeDir;
  -    segmentInfos = sis;
  +    super(si.dir, sis, closeDir);
  +    initialize(si);
     }
   
  -  SegmentReader(SegmentInfo si)
  -          throws IOException {
  +  SegmentReader(SegmentInfo si) throws IOException {
       super(si.dir);
  +    initialize(si);
  +  }
  +          
  +   private void initialize(SegmentInfo si) throws IOException
  +   {
       segment = si.name;
   
       // Use compound file directory for some files, if it exists
  @@ -119,42 +127,29 @@
       }
     }
   
  -  protected final synchronized void doClose() throws IOException {
  -    if (deletedDocsDirty || normsDirty) {
  -      synchronized (directory()) {		  // in- & inter-process sync
  -        new Lock.With(directory().makeLock(IndexWriter.COMMIT_LOCK_NAME),
  -                IndexWriter.COMMIT_LOCK_TIMEOUT) {
  -          public Object doBody() throws IOException {
  -
  -            if (deletedDocsDirty) {               // re-write deleted 
  -              deletedDocs.write(directory(), segment + ".tmp");
  -              directory().renameFile(segment + ".tmp", segment + ".del");
  -            }
  -
  -            if (normsDirty) {               // re-write norms 
  -              Enumeration keys = norms.keys();
  -              Enumeration values = norms.elements();
  -              while (values.hasMoreElements()) {
  -                String field = (String) keys.nextElement();
  -                Norm norm = (Norm) values.nextElement();
  -                if (norm.dirty) {
  -                  norm.reWrite(field);
  -                }
  -              }
  -            }
  -
  -            if (segmentInfos != null)
  -              segmentInfos.write(directory());
  -            else
  -              directory().touchFile("segments");
  -            return null;
  -          }
  -        }.run();
  +  protected final void doCommit() throws IOException {
  +    if (deletedDocsDirty) {               // re-write deleted 
  +      deletedDocs.write(directory(), segment + ".tmp");
  +      directory().renameFile(segment + ".tmp", segment + ".del");
  +    }
  +    if(undeleteAll && directory().fileExists(segment + ".del")){
  +      directory().deleteFile(segment + ".del");
  +    }
  +    if (normsDirty) {               // re-write norms 
  +      Enumeration values = norms.elements();
  +      while (values.hasMoreElements()) {
  +        Norm norm = (Norm) values.nextElement();
  +        if (norm.dirty) {
  +          norm.reWrite();
  +        }
         }
  -      deletedDocsDirty = false;
  -      normsDirty = false;
       }
  -
  +    deletedDocsDirty = false;
  +    normsDirty = false;
  +    undeleteAll = false;
  +  }
  +  
  +  protected final void doClose() throws IOException {
       fieldsReader.close();
       tis.close();
   
  @@ -168,9 +163,6 @@
   
       if (cfsReader != null)
         cfsReader.close();
  -
  -    if (closeDirectory)
  -      directory().close();
     }
   
     static final boolean hasDeletions(SegmentInfo si) throws IOException {
  @@ -186,30 +178,20 @@
       return si.dir.fileExists(si.name + ".cfs");
     }
   
  -  protected final synchronized void doDelete(int docNum) throws IOException {
  +  protected final void doDelete(int docNum) throws IOException {
       if (deletedDocs == null)
         deletedDocs = new BitVector(maxDoc());
       deletedDocsDirty = true;
  +    undeleteAll = false;
       deletedDocs.set(docNum);
     }
   
  -  public synchronized void undeleteAll() throws IOException {
  -    synchronized (directory()) {		  // in- & inter-process sync
  -      new Lock.With(directory().makeLock(IndexWriter.COMMIT_LOCK_NAME),
  -              IndexWriter.COMMIT_LOCK_TIMEOUT) {
  -        public Object doBody() throws IOException {
  -          if (directory().fileExists(segment + ".del")) {
  -            directory().deleteFile(segment + ".del");
  -          }
  -          return null;
  -        }
  -      };
  +  protected final void doUndeleteAll() throws IOException {
         deletedDocs = null;
         deletedDocsDirty = false;
  -    }
  +      undeleteAll = true;
     }
   
  -
     final Vector files() throws IOException {
       Vector files = new Vector(16);
       final String ext[] = new String[]{
  @@ -334,7 +316,7 @@
       return norm.bytes;
     }
   
  -  public synchronized void setNorm(int doc, String field, byte value)
  +  protected final void doSetNorm(int doc, String field, byte value)
             throws IOException {
       Norm norm = (Norm) norms.get(field);
       if (norm == null)                             // not an indexed field
  @@ -374,7 +356,7 @@
           String fileName = segment + ".f" + fi.number;
           // look first for re-written file, then in compound format
           Directory d = directory().fileExists(fileName) ? directory() : cfsDir;
  -        norms.put(fi.name, new Norm(d.openFile(fileName)));
  +        norms.put(fi.name, new Norm(d.openFile(fileName), fi.number));
         }
       }
     }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: lucene-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: lucene-dev-help@jakarta.apache.org


Mime
View raw message