You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ar...@apache.org on 2008/06/25 04:52:24 UTC
svn commit: r671404 [4/10] -
/incubator/lucene.net/trunk/C#/src/Lucene.Net/Index/
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Index/IndexModifier.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Index/IndexModifier.cs?rev=671404&r1=671403&r2=671404&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Index/IndexModifier.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Index/IndexModifier.cs Tue Jun 24 19:52:22 2008
@@ -16,10 +16,12 @@
*/
using System;
-using Analyzer = Lucene.Net.Analysis.Analyzer;
+
using Document = Lucene.Net.Documents.Document;
using Directory = Lucene.Net.Store.Directory;
using FSDirectory = Lucene.Net.Store.FSDirectory;
+using LockObtainFailedException = Lucene.Net.Store.LockObtainFailedException;
+using Analyzer = Lucene.Net.Analysis.Analyzer;
namespace Lucene.Net.Index
{
@@ -86,6 +88,8 @@
/// </summary>
/// <author> Daniel Naber
/// </author>
+ /// <deprecated> Please use {@link IndexWriter} instead.
+ /// </deprecated>
public class IndexModifier
{
private void InitBlock()
@@ -119,6 +123,12 @@
/// <param name="create"><code>true</code> to create the index or overwrite the existing one;
/// <code>false</code> to append to the existing index
/// </param>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public IndexModifier(Directory directory, Analyzer analyzer, bool create)
{
InitBlock();
@@ -135,6 +145,12 @@
/// <param name="create"><code>true</code> to create the index or overwrite the existing one;
/// <code>false</code> to append to the existing index
/// </param>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public IndexModifier(System.String dirName, Analyzer analyzer, bool create)
{
InitBlock();
@@ -152,6 +168,12 @@
/// <param name="create"><code>true</code> to create the index or overwrite the existing one;
/// <code>false</code> to append to the existing index
/// </param>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public IndexModifier(System.IO.FileInfo file, Analyzer analyzer, bool create)
{
InitBlock();
@@ -160,7 +182,12 @@
}
/// <summary> Initialize an IndexWriter.</summary>
- /// <throws> IOException </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
protected internal virtual void Init(Directory directory, Analyzer analyzer, bool create)
{
this.directory = directory;
@@ -183,7 +210,12 @@
}
/// <summary> Close the IndexReader and open an IndexWriter.</summary>
- /// <throws> IOException </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
protected internal virtual void CreateIndexWriter()
{
if (indexWriter == null)
@@ -194,16 +226,22 @@
indexReader = null;
}
indexWriter = new IndexWriter(directory, analyzer, false);
+ // IndexModifier cannot use ConcurrentMergeScheduler
+ // because it synchronizes on the directory which can
+ // cause deadlock
+ indexWriter.SetMergeScheduler(new SerialMergeScheduler());
indexWriter.SetInfoStream(infoStream);
indexWriter.SetUseCompoundFile(useCompoundFile);
- indexWriter.SetMaxBufferedDocs(maxBufferedDocs);
+ if (maxBufferedDocs != IndexWriter.DISABLE_AUTO_FLUSH)
+ indexWriter.SetMaxBufferedDocs(maxBufferedDocs);
indexWriter.SetMaxFieldLength(maxFieldLength);
indexWriter.SetMergeFactor(mergeFactor);
}
}
/// <summary> Close the IndexWriter and open an IndexReader.</summary>
- /// <throws> IOException </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
protected internal virtual void CreateIndexReader()
{
if (indexReader == null)
@@ -218,7 +256,12 @@
}
/// <summary> Make sure all changes are written to disk.</summary>
- /// <throws> IOException </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual void Flush()
{
lock (directory)
@@ -244,9 +287,15 @@
/// {@link #SetMaxFieldLength(int)} terms for a given field, the remainder are
/// discarded.
/// </summary>
- /// <seealso cref="Analyzer)">
+ /// <seealso cref="IndexWriter.AddDocument(Document, Analyzer)">
/// </seealso>
/// <throws> IllegalStateException if the index is closed </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual void AddDocument(Document doc, Analyzer docAnalyzer)
{
lock (directory)
@@ -264,9 +313,15 @@
/// {@link #SetMaxFieldLength(int)} terms for a given field, the remainder are
/// discarded.
/// </summary>
- /// <seealso cref="IndexWriter#AddDocument(Document)">
+ /// <seealso cref="IndexWriter.AddDocument(Document)">
/// </seealso>
/// <throws> IllegalStateException if the index is closed </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual void AddDocument(Document doc)
{
AddDocument(doc, null);
@@ -280,9 +335,18 @@
/// </summary>
/// <returns> the number of documents deleted
/// </returns>
- /// <seealso cref="IndexReader#DeleteDocuments(Term)">
+ /// <seealso cref="IndexReader.DeleteDocuments(Term)">
/// </seealso>
/// <throws> IllegalStateException if the index is closed </throws>
+ /// <throws> StaleReaderException if the index has changed </throws>
+ /// <summary> since this reader was opened
+ /// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual int DeleteDocuments(Term term)
{
lock (directory)
@@ -294,8 +358,16 @@
}
/// <summary> Deletes the document numbered <code>docNum</code>.</summary>
- /// <seealso cref="IndexReader#DeleteDocument(int)">
+ /// <seealso cref="IndexReader.DeleteDocument(int)">
/// </seealso>
+ /// <throws> StaleReaderException if the index has changed </throws>
+ /// <summary> since this reader was opened
+ /// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
/// <throws> IllegalStateException if the index is closed </throws>
public virtual void DeleteDocument(int docNum)
{
@@ -309,9 +381,9 @@
/// <summary> Returns the number of documents currently in this index.</summary>
- /// <seealso cref="IndexWriter#DocCount()">
+ /// <seealso cref="IndexWriter.DocCount()">
/// </seealso>
- /// <seealso cref="IndexReader#NumDocs()">
+ /// <seealso cref="IndexReader.NumDocs()">
/// </seealso>
/// <throws> IllegalStateException if the index is closed </throws>
public virtual int DocCount()
@@ -333,9 +405,15 @@
/// <summary> Merges all segments together into a single segment, optimizing an index
/// for search.
/// </summary>
- /// <seealso cref="IndexWriter#Optimize()">
+ /// <seealso cref="IndexWriter.Optimize()">
/// </seealso>
/// <throws> IllegalStateException if the index is closed </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual void Optimize()
{
lock (directory)
@@ -350,7 +428,7 @@
/// {@link #GetMaxFieldLength()} is reached will be printed to this.
/// <p>Example: <tt>index.setInfoStream(System.err);</tt>
/// </summary>
- /// <seealso cref="IndexWriter#SetInfoStream(PrintStream)">
+ /// <seealso cref="IndexWriter.SetInfoStream(PrintStream)">
/// </seealso>
/// <throws> IllegalStateException if the index is closed </throws>
public virtual void SetInfoStream(System.IO.StreamWriter infoStream)
@@ -366,9 +444,14 @@
}
}
- /// <throws> IOException </throws>
- /// <seealso cref="IndexModifier#SetInfoStream(PrintStream)">
+ /// <seealso cref="IndexModifier.SetInfoStream(PrintStream)">
/// </seealso>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual System.IO.TextWriter GetInfoStream()
{
lock (directory)
@@ -383,7 +466,7 @@
/// for each segment are merged into a single file once the segment creation
/// is finished. This is done regardless of what directory is in use.
/// </summary>
- /// <seealso cref="IndexWriter#SetUseCompoundFile(boolean)">
+ /// <seealso cref="IndexWriter.SetUseCompoundFile(boolean)">
/// </seealso>
/// <throws> IllegalStateException if the index is closed </throws>
public virtual void SetUseCompoundFile(bool useCompoundFile)
@@ -399,9 +482,14 @@
}
}
- /// <throws> IOException </throws>
- /// <seealso cref="IndexModifier#SetUseCompoundFile(boolean)">
+ /// <seealso cref="IndexModifier.SetUseCompoundFile(boolean)">
/// </seealso>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual bool GetUseCompoundFile()
{
lock (directory)
@@ -423,7 +511,7 @@
/// is your memory, but you should anticipate an OutOfMemoryError.<p/>
/// By default, no more than 10,000 terms will be indexed for a field.
/// </summary>
- /// <seealso cref="IndexWriter#SetMaxFieldLength(int)">
+ /// <seealso cref="IndexWriter.SetMaxFieldLength(int)">
/// </seealso>
/// <throws> IllegalStateException if the index is closed </throws>
public virtual void SetMaxFieldLength(int maxFieldLength)
@@ -439,9 +527,14 @@
}
}
- /// <throws> IOException </throws>
- /// <seealso cref="IndexModifier#SetMaxFieldLength(int)">
+ /// <seealso cref="IndexModifier.SetMaxFieldLength(int)">
/// </seealso>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual int GetMaxFieldLength()
{
lock (directory)
@@ -461,7 +554,7 @@
/// <p>The default value is 10.
///
/// </summary>
- /// <seealso cref="IndexWriter#SetMaxBufferedDocs(int)">
+ /// <seealso cref="IndexWriter.SetMaxBufferedDocs(int)">
/// </seealso>
/// <throws> IllegalStateException if the index is closed </throws>
/// <throws> IllegalArgumentException if maxBufferedDocs is smaller than 2 </throws>
@@ -478,9 +571,14 @@
}
}
- /// <throws> IOException </throws>
- /// <seealso cref="IndexModifier#SetMaxBufferedDocs(int)">
+ /// <seealso cref="IndexModifier.SetMaxBufferedDocs(int)">
/// </seealso>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual int GetMaxBufferedDocs()
{
lock (directory)
@@ -501,7 +599,7 @@
/// <p>This must never be less than 2. The default value is 10.
///
/// </summary>
- /// <seealso cref="IndexWriter#SetMergeFactor(int)">
+ /// <seealso cref="IndexWriter.SetMergeFactor(int)">
/// </seealso>
/// <throws> IllegalStateException if the index is closed </throws>
public virtual void SetMergeFactor(int mergeFactor)
@@ -517,9 +615,14 @@
}
}
- /// <throws> IOException </throws>
- /// <seealso cref="IndexModifier#SetMergeFactor(int)">
+ /// <seealso cref="IndexModifier.SetMergeFactor(int)">
/// </seealso>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual int GetMergeFactor()
{
lock (directory)
@@ -534,6 +637,8 @@
///
/// </summary>
/// <throws> IllegalStateException if the index has been closed before already </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual void Close()
{
lock (directory)
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Index/IndexReader.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Index/IndexReader.cs?rev=671404&r1=671403&r2=671404&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Index/IndexReader.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Index/IndexReader.cs Tue Jun 24 19:52:22 2008
@@ -16,13 +16,11 @@
*/
using System;
+
using Document = Lucene.Net.Documents.Document;
using FieldSelector = Lucene.Net.Documents.FieldSelector;
+using Lucene.Net.Store;
using Similarity = Lucene.Net.Search.Similarity;
-using Directory = Lucene.Net.Store.Directory;
-using FSDirectory = Lucene.Net.Store.FSDirectory;
-using IndexInput = Lucene.Net.Store.IndexInput;
-using Lock = Lucene.Net.Store.Lock;
namespace Lucene.Net.Index
{
@@ -39,93 +37,48 @@
/// rely on a given document having the same number between sessions.
/// <p> An IndexReader can be opened on a directory for which an IndexWriter is
/// opened already, but it cannot be used to delete documents from the index then.
+ /// <p>
+ /// NOTE: for backwards API compatibility, several methods are not listed
+ /// as abstract, but have no useful implementations in this base class and
+ /// instead always throw UnsupportedOperationException. Subclasses are
+ /// strongly encouraged to override these methods, but in many cases may not
+ /// need to.
+ /// </p>
/// </summary>
- /// <author> Doug Cutting
- /// </author>
- /// <version> $Id: IndexReader.java 497612 2007-01-18 22:47:03Z mikemccand $
+ /// <version> $Id: IndexReader.java 598462 2007-11-26 23:31:39Z dnaber $
/// </version>
public abstract class IndexReader
{
- private class AnonymousClassFindSegmentsFile : SegmentInfos.FindSegmentsFile
- {
- private void InitBlock(bool closeDirectory)
- {
- this.closeDirectory = closeDirectory;
- }
- private bool closeDirectory;
- internal AnonymousClassFindSegmentsFile(bool closeDirectory, Lucene.Net.Store.Directory Param1) : base(Param1)
- {
- InitBlock(closeDirectory);
- }
-
- public override System.Object DoBody(System.String segmentFileName)
- {
-
- SegmentInfos infos = new SegmentInfos();
- infos.Read(directory, segmentFileName);
-
- if (infos.Count == 1)
- {
- // index is optimized
- return SegmentReader.Get(infos, infos.Info(0), closeDirectory);
- }
- else
- {
-
- // To reduce the chance of hitting FileNotFound
- // (and having to retry), we open segments in
- // reverse because IndexWriter merges & deletes
- // the newest segments first.
-
- IndexReader[] readers = new IndexReader[infos.Count];
- for (int i = infos.Count - 1; i >= 0; i--)
- {
- try
- {
- readers[i] = SegmentReader.Get(infos.Info(i));
- }
- catch (System.IO.IOException e)
- {
- // Close all readers we had opened:
- for (i++; i < infos.Count; i++)
- {
- readers[i].Close();
- }
- throw e;
- }
- }
-
- return new MultiReader(directory, infos, closeDirectory, readers);
- }
- }
- }
- private class AnonymousClassFindSegmentsFile1 : SegmentInfos.FindSegmentsFile
+ private class AnonymousClassFindSegmentsFile:SegmentInfos.FindSegmentsFile
{
- internal AnonymousClassFindSegmentsFile1(System.IO.FileInfo Param1):base(Param1)
+ internal AnonymousClassFindSegmentsFile(System.IO.FileInfo Param1):base(Param1)
{
}
- public override System.Object DoBody(System.String segmentFileName)
+ protected internal override System.Object DoBody(System.String segmentFileName)
{
return (long) FSDirectory.FileModified(fileDirectory, segmentFileName);
}
}
- private class AnonymousClassFindSegmentsFile2 : SegmentInfos.FindSegmentsFile
+ private class AnonymousClassFindSegmentsFile1:SegmentInfos.FindSegmentsFile
{
private void InitBlock(Lucene.Net.Store.Directory directory2)
{
this.directory2 = directory2;
}
private Lucene.Net.Store.Directory directory2;
- internal AnonymousClassFindSegmentsFile2(Lucene.Net.Store.Directory directory2, Lucene.Net.Store.Directory Param1):base(Param1)
+ internal AnonymousClassFindSegmentsFile1(Lucene.Net.Store.Directory directory2, Lucene.Net.Store.Directory Param1):base(Param1)
{
InitBlock(directory2);
}
- public override System.Object DoBody(System.String segmentFileName)
+ protected internal override System.Object DoBody(System.String segmentFileName)
{
return (long) directory2.FileModified(segmentFileName);
}
}
+ /// <summary> Constants describing field properties, for example used for
+ /// {@link IndexReader#GetFieldNames(FieldOption)}.
+ /// </summary>
public sealed class FieldOption
{
private System.String option;
@@ -140,114 +93,237 @@
{
return this.option;
}
- // all fields
+ /// <summary>All fields </summary>
public static readonly FieldOption ALL = new FieldOption("ALL");
- // all indexed fields
+ /// <summary>All indexed fields </summary>
public static readonly FieldOption INDEXED = new FieldOption("INDEXED");
- // all fields which are not indexed
+ /// <summary>All fields that store payloads </summary>
+ public static readonly FieldOption STORES_PAYLOADS = new FieldOption("STORES_PAYLOADS");
+ /// <summary>All fields which are not indexed </summary>
public static readonly FieldOption UNINDEXED = new FieldOption("UNINDEXED");
- // all fields which are indexed with termvectors enables
+ /// <summary>All fields which are indexed with termvectors enabled </summary>
public static readonly FieldOption INDEXED_WITH_TERMVECTOR = new FieldOption("INDEXED_WITH_TERMVECTOR");
- // all fields which are indexed but don't have termvectors enabled
+ /// <summary>All fields which are indexed but don't have termvectors enabled </summary>
public static readonly FieldOption INDEXED_NO_TERMVECTOR = new FieldOption("INDEXED_NO_TERMVECTOR");
- // all fields where termvectors are enabled. Please note that only standard termvector fields are returned
+ /// <summary>All fields with termvectors enabled. Please note that only standard termvector fields are returned </summary>
public static readonly FieldOption TERMVECTOR = new FieldOption("TERMVECTOR");
- // all field with termvectors wiht positions enabled
+ /// <summary>All fields with termvectors with position values enabled </summary>
public static readonly FieldOption TERMVECTOR_WITH_POSITION = new FieldOption("TERMVECTOR_WITH_POSITION");
- // all fields where termvectors with offset position are set
+ /// <summary>All fields with termvectors with offset values enabled </summary>
public static readonly FieldOption TERMVECTOR_WITH_OFFSET = new FieldOption("TERMVECTOR_WITH_OFFSET");
- // all fields where termvectors with offset and position values set
+ /// <summary>All fields with termvectors with offset values and position values enabled </summary>
public static readonly FieldOption TERMVECTOR_WITH_POSITION_OFFSET = new FieldOption("TERMVECTOR_WITH_POSITION_OFFSET");
}
- /// <summary> 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.
- ///
+ private bool closed;
+ protected internal bool hasChanges;
+
+ private volatile int refCount;
+
+ // for testing
+ internal virtual int GetRefCount()
+ {
+ lock (this)
+ {
+ return refCount;
+ }
+ }
+
+ /// <summary> Increments the refCount of this IndexReader instance. RefCounts are used to determine
+ /// when a reader can be closed safely, i. e. as soon as no other IndexReader is referencing
+ /// it anymore.
/// </summary>
- /// <param name="directory">Directory where IndexReader files reside.
- /// </param>
- protected internal IndexReader(Directory directory)
+ protected internal virtual void IncRef()
{
- this.directory = directory;
+ lock (this)
+ {
+ System.Diagnostics.Debug.Assert(refCount > 0);
+ refCount++;
+ }
}
- /// <summary> 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.
+ /// <summary> Decreases the refCount of this IndexReader instance. If the refCount drops
+ /// to 0, then pending changes are committed to the index and this reader is closed.
///
/// </summary>
- /// <param name="directory">Directory where IndexReader files reside.
- /// </param>
- /// <param name="segmentInfos">Used for write-l
- /// </param>
- /// <param name="">closeDirectory
- /// </param>
- internal IndexReader(Directory directory, SegmentInfos segmentInfos, bool closeDirectory)
+ /// <throws> IOException in case an IOException occurs in commit() or doClose() </throws>
+ protected internal virtual void DecRef()
{
- Init(directory, segmentInfos, closeDirectory, true);
+ lock (this)
+ {
+ System.Diagnostics.Debug.Assert(refCount > 0);
+ if (refCount == 1)
+ {
+ Commit();
+ DoClose();
+ }
+ refCount--;
+ }
}
- internal virtual void Init(Directory directory, SegmentInfos segmentInfos, bool closeDirectory, bool directoryOwner)
+ /// <deprecated> will be deleted when IndexReader(Directory) is deleted
+ /// </deprecated>
+ /// <seealso cref="Directory()">
+ /// </seealso>
+ private Directory directory;
+
+ /// <summary> Legacy Constructor for backwards compatibility.
+ ///
+ /// <p>
+ /// This Constructor should not be used, it exists for backwards
+ /// compatibility only to support legacy subclasses that did not "own"
+ /// a specific directory, but needed to specify something to be returned
+ /// by the directory() method. Future subclasses should delegate to the
+ /// no arg constructor and implement the directory() method as appropriate.
+ ///
+ /// </summary>
+ /// <param name="directory">Directory to be returned by the directory() method
+ /// </param>
+ /// <seealso cref="Directory()">
+ /// </seealso>
+ /// <deprecated> - use IndexReader()
+ /// </deprecated>
+ protected internal IndexReader(Directory directory):this()
{
this.directory = directory;
- this.segmentInfos = segmentInfos;
- this.directoryOwner = directoryOwner;
- this.closeDirectory = closeDirectory;
}
- private Directory directory;
- private bool directoryOwner;
- private bool closeDirectory;
- protected internal IndexFileDeleter deleter;
-
- private SegmentInfos segmentInfos;
- private Lock writeLock;
- private bool stale;
- private bool hasChanges;
+ protected internal IndexReader()
+ {
+ refCount = 1;
+ }
- /// <summary>Used by commit() to record pre-commit state in case
- /// rollback is necessary
- /// </summary>
- private bool rollbackHasChanges;
- private SegmentInfos rollbackSegmentInfos;
+ /// <throws> AlreadyClosedException if this IndexReader is closed </throws>
+ protected internal void EnsureOpen()
+ {
+ if (refCount <= 0)
+ {
+ throw new AlreadyClosedException("this IndexReader is closed");
+ }
+ }
/// <summary>Returns an IndexReader reading the index in an FSDirectory in the named
- /// path.
+ /// path.
/// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
+ /// <param name="path">the path to the index directory
+ /// </param>
public static IndexReader Open(System.String path)
{
- return Open(FSDirectory.GetDirectory(path), true);
+ return Open(FSDirectory.GetDirectory(path), true, null);
}
/// <summary>Returns an IndexReader reading the index in an FSDirectory in the named
- /// path.
+ /// path.
/// </summary>
+ /// <param name="path">the path to the index directory
+ /// </param>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public static IndexReader Open(System.IO.FileInfo path)
{
- return Open(FSDirectory.GetDirectory(path), true);
+ return Open(FSDirectory.GetDirectory(path), true, null);
}
- /// <summary>Returns an IndexReader reading the index in the given Directory. </summary>
+ /// <summary>Returns an IndexReader reading the index in the given Directory.</summary>
+ /// <param name="directory">the index directory
+ /// </param>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public static IndexReader Open(Directory directory)
{
- return Open(directory, false);
+ return Open(directory, false, null);
}
- private static IndexReader Open(Directory directory, bool closeDirectory)
+ /// <summary>Expert: returns an IndexReader reading the index in the given
+ /// Directory, with a custom {@link IndexDeletionPolicy}.
+ /// </summary>
+ /// <param name="directory">the index directory
+ /// </param>
+ /// <param name="deletionPolicy">a custom deletion policy (only used
+ /// if you use this reader to perform deletes or to set
+ /// norms); see {@link IndexWriter} for details.
+ /// </param>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
+ public static IndexReader Open(Directory directory, IndexDeletionPolicy deletionPolicy)
+ {
+ return Open(directory, false, deletionPolicy);
+ }
+
+ private static IndexReader Open(Directory directory, bool closeDirectory, IndexDeletionPolicy deletionPolicy)
+ {
+ return DirectoryIndexReader.Open(directory, closeDirectory, deletionPolicy);
+ }
+
+ /// <summary> Refreshes an IndexReader if the index has changed since this instance
+ /// was (re)opened.
+ /// <p>
+ /// Opening an IndexReader is an expensive operation. This method can be used
+ /// to refresh an existing IndexReader to reduce these costs. This method
+ /// tries to only load segments that have changed or were created after the
+ /// IndexReader was (re)opened.
+ /// <p>
+ /// If the index has not changed since this instance was (re)opened, then this
+ /// call is a NOOP and returns this instance. Otherwise, a new instance is
+ /// returned. The old instance is <b>not</b> closed and remains usable.<br>
+ /// <b>Note:</b> The re-opened reader instance and the old instance might share
+ /// the same resources. For this reason no index modification operations
+ /// (e. g. {@link #DeleteDocument(int)}, {@link #SetNorm(int, String, byte)})
+ /// should be performed using one of the readers until the old reader instance
+ /// is closed. <b>Otherwise, the behavior of the readers is undefined.</b>
+ /// <p>
+ /// You can determine whether a reader was actually reopened by comparing the
+ /// old instance with the instance returned by this method:
+ /// <pre>
+ /// IndexReader reader = ...
+ /// ...
+ /// IndexReader new = r.reopen();
+ /// if (new != reader) {
+ /// ... // reader was reopened
+ /// reader.close();
+ /// }
+ /// reader = new;
+ /// ...
+ /// </pre>
+ ///
+ /// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
+ public virtual IndexReader Reopen()
{
-
- return (IndexReader) new AnonymousClassFindSegmentsFile(closeDirectory, directory).run();
+ lock (this)
+ {
+ throw new System.NotSupportedException("This reader does not support reopen().");
+ }
}
- /// <summary>Returns the directory this index resides in. </summary>
+ /// <summary> Returns the directory associated with this index. The Default
+ /// implementation returns the directory specified by subclasses when
+ /// delegating to the IndexReader(Directory) constructor, or throws an
+ /// UnsupportedOperationException if one was not specified.
+ /// </summary>
+ /// <throws> UnsupportedOperationException if no directory </throws>
public virtual Directory Directory()
{
- return directory;
+ EnsureOpen();
+ if (null != directory)
+ {
+ return directory;
+ }
+ else
+ {
+ throw new System.NotSupportedException("This reader does not support this method.");
+ }
}
/// <summary> Returns the time the index in the named directory was last modified.
/// Do not use this to check whether the reader is still up-to-date, use
/// {@link #IsCurrent()} instead.
/// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public static long LastModified(System.String directory)
{
return LastModified(new System.IO.FileInfo(directory));
@@ -257,18 +333,22 @@
/// Do not use this to check whether the reader is still up-to-date, use
/// {@link #IsCurrent()} instead.
/// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public static long LastModified(System.IO.FileInfo fileDirectory)
{
- return (long) ((System.Int64) new AnonymousClassFindSegmentsFile1(fileDirectory).run());
+ return (long) ((System.Int64) new AnonymousClassFindSegmentsFile(fileDirectory).Run());
}
/// <summary> Returns the time the index in the named directory was last modified.
/// Do not use this to check whether the reader is still up-to-date, use
/// {@link #IsCurrent()} instead.
/// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public static long LastModified(Directory directory2)
{
- return (long) ((System.Int64) new AnonymousClassFindSegmentsFile2(directory2, directory2).run());
+ return (long) ((System.Int64) new AnonymousClassFindSegmentsFile1(directory2, directory2).Run());
}
/// <summary> Reads version number from segments files. The version number is
@@ -280,7 +360,8 @@
/// </param>
/// <returns> version number.
/// </returns>
- /// <throws> IOException if segments file cannot be read </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public static long GetCurrentVersion(System.String directory)
{
return GetCurrentVersion(new System.IO.FileInfo(directory));
@@ -295,7 +376,8 @@
/// </param>
/// <returns> version number.
/// </returns>
- /// <throws> IOException if segments file cannot be read </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public static long GetCurrentVersion(System.IO.FileInfo directory)
{
Directory dir = FSDirectory.GetDirectory(directory);
@@ -313,35 +395,84 @@
/// </param>
/// <returns> version number.
/// </returns>
- /// <throws> IOException if segments file cannot be read. </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public static long GetCurrentVersion(Directory directory)
{
return SegmentInfos.ReadCurrentVersion(directory);
}
- /// <summary> Version number when this IndexReader was opened.</summary>
+ /// <summary> Version number when this IndexReader was opened. Not implemented in the IndexReader base class.</summary>
+ /// <throws> UnsupportedOperationException unless overridden in subclass </throws>
public virtual long GetVersion()
{
- return segmentInfos.GetVersion();
+ throw new System.NotSupportedException("This reader does not support this method.");
}
- /// <summary> Check whether this IndexReader still works on a current version of the index.
- /// If this is not the case you will need to re-open the IndexReader to
- /// make sure you see the latest changes made to the index.
+ /// <summary><p>For IndexReader implementations that use
+ /// TermInfosReader to read terms, this sets the
+ /// indexDivisor to subsample the number of indexed terms
+ /// loaded into memory. This has the same effect as {@link
+ /// IndexWriter#setTermIndexInterval} except that setting
+ /// must be done at indexing time while this setting can be
+ /// set per reader. When set to N, then one in every
+ /// N*termIndexInterval terms in the index is loaded into
+ /// memory. By setting this to a value > 1 you can reduce
+ /// memory usage, at the expense of higher latency when
+ /// loading a TermInfo. The default value is 1.</p>
///
+ /// <b>NOTE:</b> you must call this before the term
+ /// index is loaded. If the index is already loaded,
+ /// an IllegalStateException is thrown.
/// </summary>
- /// <throws> IOException </throws>
+ /// <throws> IllegalStateException if the term index has already been loaded into memory </throws>
+ public virtual void SetTermInfosIndexDivisor(int indexDivisor)
+ {
+ throw new System.NotSupportedException("This reader does not support this method.");
+ }
+
+ /// <summary><p>For IndexReader implementations that use
+ /// TermInfosReader to read terms, this returns the
+ /// current indexDivisor.
+ /// </summary>
+ /// <seealso cref="setTermInfosIndexDivisor">
+ /// </seealso>
+ public virtual int GetTermInfosIndexDivisor()
+ {
+ throw new System.NotSupportedException("This reader does not support this method.");
+ }
+
+ /// <summary> Check whether this IndexReader is still using the
+ /// current (i.e., most recently committed) version of the
+ /// index. If a writer has committed any changes to the
+ /// index since this reader was opened, this will return
+ /// <code>false</code>, in which case you must open a new
+ /// IndexReader in order to see the changes. See the
+ /// description of the <a href="IndexWriter.html#autoCommit"><code>autoCommit</code></a>
+ /// flag which controls when the {@link IndexWriter}
+ /// actually commits changes to the index.
+ ///
+ /// <p>
+ /// Not implemented in the IndexReader base class.
+ /// </p>
+ /// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
+ /// <throws> UnsupportedOperationException unless overridden in subclass </throws>
public virtual bool IsCurrent()
{
- return SegmentInfos.ReadCurrentVersion(directory) == segmentInfos.GetVersion();
+ throw new System.NotSupportedException("This reader does not support this method.");
}
- /// <summary> Checks is the index is optimized (if it has a single segment and no deletions)</summary>
+ /// <summary> Checks is the index is optimized (if it has a single segment and
+ /// no deletions). Not implemented in the IndexReader base class.
+ /// </summary>
/// <returns> <code>true</code> if the index is optimized; <code>false</code> otherwise
/// </returns>
+ /// <throws> UnsupportedOperationException unless overridden in subclass </throws>
public virtual bool IsOptimized()
{
- return segmentInfos.Count == 1 && HasDeletions() == false;
+ throw new System.NotSupportedException("This reader does not support this method.");
}
/// <summary> Return an array of term frequency vectors for the specified document.
@@ -382,6 +513,28 @@
/// </seealso>
abstract public TermFreqVector GetTermFreqVector(int docNumber, System.String field);
+ /// <summary> Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays of
+ /// the {@link TermFreqVector}.
+ /// </summary>
+ /// <param name="docNumber">The number of the document to load the vector for
+ /// </param>
+ /// <param name="field">The name of the field to load
+ /// </param>
+ /// <param name="mapper">The {@link TermVectorMapper} to process the vector. Must not be null
+ /// </param>
+ /// <throws> IOException if term vectors cannot be accessed or if they do not exist on the field and doc. specified. </throws>
+ /// <summary>
+ /// </summary>
+ abstract public void GetTermFreqVector(int docNumber, System.String field, TermVectorMapper mapper);
+
+ /// <summary> Map all the term vectors for all fields in a Document</summary>
+ /// <param name="docNumber">The number of the document to load the vector for
+ /// </param>
+ /// <param name="mapper">The {@link TermVectorMapper} to process the vector. Must not be null
+ /// </param>
+ /// <throws> IOException if term vectors cannot be accessed or if they do not exist on the field and doc. specified. </throws>
+ abstract public void GetTermFreqVector(int docNumber, TermVectorMapper mapper);
+
/// <summary> Returns <code>true</code> if an index exists at the specified directory.
/// If the directory does not exist or if there is no index in it.
/// <code>false</code> is returned.
@@ -405,14 +558,7 @@
public static bool IndexExists(System.IO.FileInfo directory)
{
- if (System.IO.Directory.Exists(directory.FullName))
- {
- return SegmentInfos.GetCurrentSegmentGeneration(System.IO.Directory.GetFileSystemEntries(directory.FullName)) != - 1;
- }
- else
- {
- return false;
- }
+ return SegmentInfos.GetCurrentSegmentGeneration(System.IO.Directory.GetFileSystemEntries(directory.FullName)) != - 1;
}
/// <summary> Returns <code>true</code> if an index exists at the specified directory.
@@ -438,17 +584,20 @@
public abstract int MaxDoc();
/// <summary>Returns the stored fields of the <code>n</code><sup>th</sup>
- /// <code>Document</code> in this index.
+ /// <code>Document</code> in this index.
/// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual Document Document(int n)
{
+ EnsureOpen();
return Document(n, null);
}
/// <summary> Get the {@link Lucene.Net.Documents.Document} at the <code>n</code><sup>th</sup> position. The {@link Lucene.Net.Documents.FieldSelector}
/// may be used to determine what {@link Lucene.Net.Documents.Field}s to load and how they should be loaded.
///
- /// <b>NOTE:</b> If this Reader (more specifically, the underlying {@link FieldsReader} is closed before the lazy {@link Lucene.Net.Documents.Field} is
+ /// <b>NOTE:</b> If this Reader (more specifically, the underlying <code>FieldsReader</code>) is closed before the lazy {@link Lucene.Net.Documents.Field} is
/// loaded an exception may be thrown. If you want the value of a lazy {@link Lucene.Net.Documents.Field} to be available after closing you must
/// explicitly load it or fetch the Document again with a new loader.
///
@@ -460,7 +609,8 @@
/// </param>
/// <returns> The stored fields of the {@link Lucene.Net.Documents.Document} at the nth position
/// </returns>
- /// <throws> IOException If there is a problem reading this document </throws>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
/// <summary>
/// </summary>
/// <seealso cref="Lucene.Net.Documents.Fieldable">
@@ -487,6 +637,7 @@
{
// backward compatible implementation.
// SegmentReader has an efficient implementation.
+ EnsureOpen();
return Norms(field) != null;
}
@@ -494,7 +645,7 @@
/// every document. This is used by the search code to score documents.
///
/// </summary>
- /// <seealso cref="Lucene.Net.Documents.Field#SetBoost(float)">
+ /// <seealso cref="Lucene.Net.Documents.Field.SetBoost(float)">
/// </seealso>
public abstract byte[] Norms(System.String field);
@@ -502,27 +653,36 @@
/// document. This is used by the search code to score documents.
///
/// </summary>
- /// <seealso cref="Lucene.Net.Documents.Field#SetBoost(float)">
+ /// <seealso cref="Lucene.Net.Documents.Field.SetBoost(float)">
/// </seealso>
public abstract void Norms(System.String field, byte[] bytes, int offset);
/// <summary>Expert: Resets the normalization factor for the named field of the named
/// document. The norm represents the product of the field's {@link
- /// Fieldable#SetBoost(float) boost} and its {@link Similarity#LengthNorm(String,
+ /// Lucene.Net.Documents.Fieldable#SetBoost(float) boost} and its {@link Similarity#LengthNorm(String,
/// int) length normalization}. Thus, to preserve the length normalization
/// values when resetting this, one should base the new value upon the old.
///
/// </summary>
- /// <seealso cref="#Norms(String)">
+ /// <seealso cref="Norms(String)">
/// </seealso>
- /// <seealso cref="Similarity#DecodeNorm(byte)">
+ /// <seealso cref="Similarity.DecodeNorm(byte)">
/// </seealso>
+ /// <throws> StaleReaderException if the index has changed </throws>
+ /// <summary> since this reader was opened
+ /// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public void SetNorm(int doc, System.String field, byte value_Renamed)
{
lock (this)
{
- if (directoryOwner)
- AquireWriteLock();
+ EnsureOpen();
+ AcquireWriteLock();
hasChanges = true;
DoSetNorm(doc, field, value_Renamed);
}
@@ -535,28 +695,47 @@
/// document.
///
/// </summary>
- /// <seealso cref="#Norms(String)">
+ /// <seealso cref="Norms(String)">
/// </seealso>
- /// <seealso cref="Similarity#DecodeNorm(byte)">
+ /// <seealso cref="Similarity.DecodeNorm(byte)">
+ ///
/// </seealso>
+ /// <throws> StaleReaderException if the index has changed </throws>
+ /// <summary> since this reader was opened
+ /// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual void SetNorm(int doc, System.String field, float value_Renamed)
{
+ EnsureOpen();
SetNorm(doc, field, Similarity.EncodeNorm(value_Renamed));
}
- /// <summary>Returns an enumeration of all the terms in the index.
- /// The enumeration is ordered by Term.compareTo(). Each term
- /// is greater than all that precede it in the enumeration.
+ /// <summary>Returns an enumeration of all the terms in the index. The
+ /// enumeration is ordered by Term.compareTo(). Each term is greater
+ /// than all that precede it in the enumeration. Note that after
+ /// calling terms(), {@link TermEnum#Next()} must be called
+ /// on the resulting enumeration before calling other methods such as
+ /// {@link TermEnum#Term()}.
/// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public abstract TermEnum Terms();
- /// <summary>Returns an enumeration of all terms after a given term.
- /// The enumeration is ordered by Term.compareTo(). Each term
- /// is greater than all that precede it in the enumeration.
+ /// <summary>Returns an enumeration of all terms starting at a given term. If
+ /// the given term does not exist, the enumeration is positioned at the
+ /// first term greater than the supplied therm. The enumeration is
+ /// ordered by Term.compareTo(). Each term is greater than all that
+ /// precede it in the enumeration.
/// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public abstract TermEnum Terms(Term t);
- /// <summary>Returns the number of documents containing the term <code>t</code>. </summary>
+ /// <summary>Returns the number of documents containing the term <code>t</code>.</summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public abstract int DocFreq(Term t);
/// <summary>Returns an enumeration of all the documents which contain
@@ -569,14 +748,17 @@
/// <p>The enumeration is ordered by document number. Each document number
/// is greater than all that precede it in the enumeration.
/// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual TermDocs TermDocs(Term term)
{
+ EnsureOpen();
TermDocs termDocs = TermDocs();
termDocs.Seek(term);
return termDocs;
}
- /// <summary>Returns an unpositioned {@link TermDocs} enumerator. </summary>
+ /// <summary>Returns an unpositioned {@link TermDocs} enumerator.</summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public abstract TermDocs TermDocs();
/// <summary>Returns an enumeration of all the documents which contain
@@ -591,51 +773,23 @@
/// pos<sub>freq-1</sub>>
/// ><sup>*</sup>
/// </ul>
- /// <p> This positional information faciliates phrase and proximity searching.
+ /// <p> This positional information facilitates phrase and proximity searching.
/// <p>The enumeration is ordered by document number. Each document number is
/// greater than all that precede it in the enumeration.
/// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public virtual TermPositions TermPositions(Term term)
{
+ EnsureOpen();
TermPositions termPositions = TermPositions();
termPositions.Seek(term);
return termPositions;
}
- /// <summary>Returns an unpositioned {@link TermPositions} enumerator. </summary>
+ /// <summary>Returns an unpositioned {@link TermPositions} enumerator.</summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public abstract TermPositions TermPositions();
- /// <summary> Tries to acquire the WriteLock on this directory.
- /// this method is only valid if this IndexReader is directory owner.
- ///
- /// </summary>
- /// <throws> IOException If WriteLock cannot be acquired. </throws>
- private void AquireWriteLock()
- {
- if (stale)
- throw new System.IO.IOException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
-
- if (this.writeLock == null)
- {
- Lock writeLock = directory.MakeLock(IndexWriter.WRITE_LOCK_NAME);
- if (!writeLock.Obtain(IndexWriter.WRITE_LOCK_TIMEOUT))
- // obtain write lock
- {
- throw new System.IO.IOException("Index locked for write: " + writeLock);
- }
- this.writeLock = writeLock;
-
- // 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.ReadCurrentVersion(directory) > segmentInfos.GetVersion())
- {
- stale = true;
- this.writeLock.Release();
- this.writeLock = null;
- throw new System.IO.IOException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
- }
- }
- }
/// <summary>Deletes the document numbered <code>docNum</code>. Once a document is
@@ -644,13 +798,23 @@
/// 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.
+ ///
+ /// </summary>
+ /// <throws> StaleReaderException if the index has changed </throws>
+ /// <summary> since this reader was opened
/// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public void DeleteDocument(int docNum)
{
lock (this)
{
- if (directoryOwner)
- AquireWriteLock();
+ EnsureOpen();
+ AcquireWriteLock();
hasChanges = true;
DoDelete(docNum);
}
@@ -670,11 +834,22 @@
/// passes it to this method.
/// See {@link #DeleteDocument(int)} for information about when this deletion will
/// become effective.
+ ///
/// </summary>
/// <returns> the number of documents deleted
/// </returns>
+ /// <throws> StaleReaderException if the index has changed </throws>
+ /// <summary> since this reader was opened
+ /// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public int DeleteDocuments(Term term)
{
+ EnsureOpen();
TermDocs docs = TermDocs(term);
if (docs == null)
return 0;
@@ -694,13 +869,24 @@
return n;
}
- /// <summary>Undeletes all documents currently marked as deleted in this index.</summary>
+ /// <summary>Undeletes all documents currently marked as deleted in this index.
+ ///
+ /// </summary>
+ /// <throws> StaleReaderException if the index has changed </throws>
+ /// <summary> since this reader was opened
+ /// </summary>
+ /// <throws> LockObtainFailedException if another writer </throws>
+ /// <summary> has this index open (<code>write.lock</code> could not
+ /// be obtained)
+ /// </summary>
+ /// <throws> CorruptIndexException if the index is corrupt </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public void UndeleteAll()
{
lock (this)
{
- if (directoryOwner)
- AquireWriteLock();
+ EnsureOpen();
+ AcquireWriteLock();
hasChanges = true;
DoUndeleteAll();
}
@@ -709,38 +895,26 @@
/// <summary>Implements actual undeleteAll() in subclass. </summary>
protected internal abstract void DoUndeleteAll();
- /// <summary> Should internally checkpoint state that will change
- /// during commit so that we can rollback if necessary.
+ /// <summary>Does nothing by default. Subclasses that require a write lock for
+ /// index modifications must implement this method.
/// </summary>
- internal virtual void StartCommit()
+ protected internal virtual void AcquireWriteLock()
{
- if (directoryOwner)
+ lock (this)
{
- rollbackSegmentInfos = (SegmentInfos) segmentInfos.Clone();
+ /* NOOP */
}
- rollbackHasChanges = hasChanges;
}
- /// <summary> Rolls back state to just before the commit (this is
- /// called by commit() if there is some exception while
- /// committing).
- /// </summary>
- internal virtual void RollbackCommit()
+ /// <summary> </summary>
+ /// <throws> IOException </throws>
+ public void Flush()
{
- if (directoryOwner)
+ lock (this)
{
- for (int i = 0; i < segmentInfos.Count; i++)
- {
- // Rollback each segmentInfo. Because the
- // SegmentReader holds a reference to the
- // SegmentInfo we can't [easily] just replace
- // segmentInfos, so we reset it in place instead:
- segmentInfos.Info(i).Reset(rollbackSegmentInfos.Info(i));
- }
- rollbackSegmentInfos = null;
+ EnsureOpen();
+ Commit();
}
-
- hasChanges = rollbackHasChanges;
}
/// <summary> Commit changes resulting from delete, undeleteAll, or
@@ -749,96 +923,20 @@
/// If an exception is hit, then either no changes or all
/// changes will have been committed to the index
/// (transactional semantics).
- ///
/// </summary>
- /// <throws> IOException </throws>
- public void Commit()
+ /// <throws> IOException if there is a low-level IO error </throws>
+ protected internal void Commit()
{
lock (this)
{
if (hasChanges)
{
- if (deleter == null)
- {
- // In the MultiReader case, we share this deleter
- // across all SegmentReaders:
- SetDeleter(new IndexFileDeleter(segmentInfos, directory));
- }
- if (directoryOwner)
- {
-
- // Should not be necessary: no prior commit should
- // have left pending files, so just defensive:
- deleter.ClearPendingFiles();
-
- System.String oldInfoFileName = segmentInfos.GetCurrentSegmentFileName();
- System.String nextSegmentsFileName = segmentInfos.GetNextSegmentFileName();
-
- // Checkpoint the state we are about to change, in
- // case we have to roll back:
- StartCommit();
-
- bool success = false;
- try
- {
- DoCommit();
- segmentInfos.Write(directory);
- success = true;
- }
- finally
- {
-
- if (!success)
- {
-
- // Rollback changes that were made to
- // SegmentInfos but failed to get [fully]
- // committed. This way this reader instance
- // remains consistent (matched to what's
- // actually in the index):
- RollbackCommit();
-
- // Erase any pending files that we were going to delete:
- deleter.ClearPendingFiles();
-
- // Remove possibly partially written next
- // segments file:
- deleter.DeleteFile(nextSegmentsFileName);
-
- // Recompute deletable files & remove them (so
- // partially written .del files, etc, are
- // removed):
- deleter.FindDeletableFiles();
- deleter.DeleteFiles();
- }
- }
-
- // Attempt to delete all files we just obsoleted:
- deleter.DeleteFile(oldInfoFileName);
- deleter.CommitPendingFiles();
-
- if (writeLock != null)
- {
- writeLock.Release(); // release write lock
- writeLock = null;
- }
- }
- else
- DoCommit();
+ DoCommit();
}
hasChanges = false;
}
}
- protected internal virtual void SetDeleter(IndexFileDeleter deleter)
- {
- this.deleter = deleter;
- }
- protected internal virtual IndexFileDeleter GetDeleter()
- {
- return deleter;
- }
-
/// <summary>Implements commit. </summary>
protected internal abstract void DoCommit();
@@ -846,36 +944,22 @@
/// Also saves any new deletions to disk.
/// No other methods should be called after this has been called.
/// </summary>
+ /// <throws> IOException if there is a low-level IO error </throws>
public void Close()
{
lock (this)
{
- Commit();
- DoClose();
- if (closeDirectory)
- directory.Close();
+ if (!closed)
+ {
+ DecRef();
+ closed = true;
+ }
}
}
/// <summary>Implements close. </summary>
protected internal abstract void DoClose();
- /// <summary>Release the write lock, if needed. </summary>
- ~IndexReader()
- {
- try
- {
- if (writeLock != null)
- {
- writeLock.Release(); // release write lock
- writeLock = null;
- }
- }
- finally
- {
- }
- }
-
/// <summary> Get a list of unique field names that exist in this index and have the specified
/// field option information.
@@ -893,7 +977,7 @@
/// </summary>
/// <param name="directory">the directory to check for a lock
/// </param>
- /// <throws> IOException if there is a problem with accessing the index </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public static bool IsLocked(Directory directory)
{
return directory.MakeLock(IndexWriter.WRITE_LOCK_NAME).IsLocked();
@@ -904,7 +988,7 @@
/// </summary>
/// <param name="directory">the directory to check for a lock
/// </param>
- /// <throws> IOException if there is a problem with accessing the index </throws>
+ /// <throws> IOException if there is a low-level IO error </throws>
public static bool IsLocked(System.String directory)
{
Directory dir = FSDirectory.GetDirectory(directory);
@@ -987,13 +1071,7 @@
{
int bufLen = (int) System.Math.Min(chunk, len);
ii.ReadBytes(buffer, 0, bufLen);
-
- byte[] byteArray = new byte[buffer.Length];
- for (int index=0; index < buffer.Length; index++)
- byteArray[index] = (byte) buffer[index];
-
- f.Write(byteArray, 0, bufLen);
-
+ f.Write(buffer, 0, bufLen);
len -= bufLen;
}