IndexReader.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:36k
- /*
- * 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.
- */
- using System;
- using Document = Lucene.Net.Documents.Document;
- using Field = Lucene.Net.Documents.Field;
- 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
- {
-
- /// <summary>IndexReader is an abstract class, providing an interface for accessing an
- /// index. Search of an index is done entirely through this abstract interface,
- /// so that any subclass which implements it is searchable.
- /// <p> Concrete subclasses of IndexReader are usually constructed with a call to
- /// one of the static <code>open()</code> methods, e.g. {@link #Open(String)}.
- /// <p> For efficiency, in this API documents are often referred to via
- /// <i>document numbers</i>, non-negative integers which each name a unique
- /// document in the index. These document numbers are ephemeral--they may change
- /// as documents are added to and deleted from an index. Clients should thus not
- /// rely on a given document having the same number between sessions.
- /// </summary>
- /// <summary><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.
- /// </summary>
- /// <author> Doug Cutting
- /// </author>
- /// <version> $Id: IndexReader.java 354917 2005-12-08 00:22:00Z ehatcher $
- /// </version>
- public abstract class IndexReader
- {
- private class AnonymousClassWith : Lock.With
- {
- private void InitBlock(Lucene.Net.Store.Directory directory, bool closeDirectory)
- {
- this.directory = directory;
- this.closeDirectory = closeDirectory;
- }
- private Lucene.Net.Store.Directory directory;
- private bool closeDirectory;
- internal AnonymousClassWith(Lucene.Net.Store.Directory directory, bool closeDirectory, Lucene.Net.Store.Lock Param1, long Param2):base(Param1, Param2)
- {
- InitBlock(directory, closeDirectory);
- }
- public override System.Object DoBody()
- {
- SegmentInfos infos = new SegmentInfos();
- infos.Read(directory);
- if (infos.Count == 1)
- {
- // index is optimized
- return SegmentReader.Get(infos, infos.Info(0), closeDirectory);
- }
- IndexReader[] readers = new IndexReader[infos.Count];
- for (int i = 0; i < infos.Count; i++)
- readers[i] = SegmentReader.Get(infos.Info(i));
- return new MultiReader(directory, infos, closeDirectory, readers);
- }
- }
- private class AnonymousClassWith1 : Lock.With
- {
- private void InitBlock(IndexReader enclosingInstance)
- {
- this.enclosingInstance = enclosingInstance;
- }
- private IndexReader enclosingInstance;
- public IndexReader Enclosing_Instance
- {
- get
- {
- return enclosingInstance;
- }
-
- }
- internal AnonymousClassWith1(IndexReader enclosingInstance, Lucene.Net.Store.Lock Param1, long Param2) : base(Param1, Param2)
- {
- InitBlock(enclosingInstance);
- }
- public override System.Object DoBody()
- {
- Enclosing_Instance.DoCommit();
- Enclosing_Instance.segmentInfos.Write(Enclosing_Instance.directory);
- return null;
- }
- }
-
- public sealed class FieldOption
- {
- private System.String option;
- internal FieldOption()
- {
- }
- internal FieldOption(System.String option)
- {
- this.option = option;
- }
- public override System.String ToString()
- {
- return this.option;
- }
- // all fields
- public static readonly FieldOption ALL = new FieldOption("ALL");
- // all indexed fields
- public static readonly FieldOption INDEXED = new FieldOption("INDEXED");
- // all fields which are not indexed
- public static readonly FieldOption UNINDEXED = new FieldOption("UNINDEXED");
- // all fields which are indexed with termvectors enables
- public static readonly FieldOption INDEXED_WITH_TERMVECTOR = new FieldOption("INDEXED_WITH_TERMVECTOR");
- // all fields which are indexed but don't have termvectors enabled
- 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
- public static readonly FieldOption TERMVECTOR = new FieldOption("TERMVECTOR");
- // all field with termvectors wiht positions enabled
- public static readonly FieldOption TERMVECTOR_WITH_POSITION = new FieldOption("TERMVECTOR_WITH_POSITION");
- // all fields where termvectors with offset position are set
- public static readonly FieldOption TERMVECTOR_WITH_OFFSET = new FieldOption("TERMVECTOR_WITH_OFFSET");
- // all fields where termvectors with offset and position values set
- 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.
- ///
- /// </summary>
- /// <param name="directory">Directory where IndexReader files reside.
- /// </param>
- protected internal IndexReader(Directory directory)
- {
- this.directory = directory;
- }
-
- /// <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>
- /// <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)
- {
- Init(directory, segmentInfos, closeDirectory, true);
- }
-
- internal virtual void Init(Directory directory, SegmentInfos segmentInfos, bool closeDirectory, bool directoryOwner)
- {
- this.directory = directory;
- this.segmentInfos = segmentInfos;
- this.directoryOwner = directoryOwner;
- this.closeDirectory = closeDirectory;
- }
-
- private Directory directory;
- private bool directoryOwner;
- private bool closeDirectory;
-
- private SegmentInfos segmentInfos;
- private Lock writeLock;
- private bool stale;
- private bool hasChanges;
-
-
- /// <summary>Returns an IndexReader reading the index in an FSDirectory in the named
- /// path.
- /// </summary>
- public static IndexReader Open(System.String path)
- {
- return Open(FSDirectory.GetDirectory(path, false), true);
- }
-
- /// <summary>Returns an IndexReader reading the index in an FSDirectory in the named
- /// path.
- /// </summary>
- public static IndexReader Open(System.IO.FileInfo path)
- {
- return Open(FSDirectory.GetDirectory(path, false), true);
- }
-
- /// <summary>Returns an IndexReader reading the index in the given Directory. </summary>
- public static IndexReader Open(Directory directory)
- {
- return Open(directory, false);
- }
-
- private static IndexReader Open(Directory directory, bool closeDirectory)
- {
- lock (directory)
- {
- // in- & inter-process sync
- return (IndexReader) new AnonymousClassWith(directory, closeDirectory, directory.MakeLock(IndexWriter.COMMIT_LOCK_NAME), IndexWriter.COMMIT_LOCK_TIMEOUT).Run();
- }
- }
-
- /// <summary>Returns the directory this index resides in. </summary>
- public virtual Directory Directory()
- {
- return directory;
- }
-
- /// <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>
- public static long LastModified(System.String directory)
- {
- return LastModified(new System.IO.FileInfo(directory));
- }
-
- /// <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>
- public static long LastModified(System.IO.FileInfo directory)
- {
- return FSDirectory.FileModified(directory, IndexFileNames.SEGMENTS);
- }
-
- /// <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>
- public static long LastModified(Directory directory)
- {
- return directory.FileModified(IndexFileNames.SEGMENTS);
- }
-
- /// <summary> Reads version number from segments files. The version number is
- /// initialized with a timestamp and then increased by one for each change of
- /// the index.
- ///
- /// </summary>
- /// <param name="directory">where the index resides.
- /// </param>
- /// <returns> version number.
- /// </returns>
- /// <throws> IOException if segments file cannot be read </throws>
- public static long GetCurrentVersion(System.String directory)
- {
- return GetCurrentVersion(new System.IO.FileInfo(directory));
- }
-
- /// <summary> Reads version number from segments files. The version number is
- /// initialized with a timestamp and then increased by one for each change of
- /// the index.
- ///
- /// </summary>
- /// <param name="directory">where the index resides.
- /// </param>
- /// <returns> version number.
- /// </returns>
- /// <throws> IOException if segments file cannot be read </throws>
- public static long GetCurrentVersion(System.IO.FileInfo directory)
- {
- Directory dir = FSDirectory.GetDirectory(directory, false);
- long version = GetCurrentVersion(dir);
- dir.Close();
- return version;
- }
-
- /// <summary> Reads version number from segments files. The version number is
- /// initialized with a timestamp and then increased by one for each change of
- /// the index.
- ///
- /// </summary>
- /// <param name="directory">where the index resides.
- /// </param>
- /// <returns> version number.
- /// </returns>
- /// <throws> IOException if segments file cannot be read. </throws>
- public static long GetCurrentVersion(Directory directory)
- {
- return SegmentInfos.ReadCurrentVersion(directory);
- }
-
- /// <summary> Version number when this IndexReader was opened.</summary>
- public virtual long GetVersion()
- {
- return segmentInfos.GetVersion();
- }
-
- /// <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>
- /// <throws> IOException </throws>
- public virtual bool IsCurrent()
- {
- if (SegmentInfos.ReadCurrentVersion(directory) != segmentInfos.GetVersion())
- {
- return false;
- }
- return true;
- }
-
- /// <summary> Return an array of term frequency vectors for the specified document.
- /// The array contains a vector for each vectorized field in the document.
- /// Each vector contains terms and frequencies for all terms in a given vectorized field.
- /// If no such fields existed, the method returns null. The term vectors that are
- /// returned my either be of type TermFreqVector or of type TermPositionsVector if
- /// positions or offsets have been stored.
- ///
- /// </summary>
- /// <param name="docNumber">document for which term frequency vectors are returned
- /// </param>
- /// <returns> array of term frequency vectors. May be null if no term vectors have been
- /// stored for the specified document.
- /// </returns>
- /// <throws> IOException if index cannot be accessed </throws>
- /// <seealso cref="Lucene.Net.document.Field.TermVector">
- /// </seealso>
- abstract public TermFreqVector[] GetTermFreqVectors(int docNumber);
-
-
- /// <summary> Return a term frequency vector for the specified document and field. The
- /// returned vector contains terms and frequencies for the terms in
- /// the specified field of this document, if the field had the storeTermVector
- /// flag set. If termvectors had been stored with positions or offsets, a
- /// TermPositionsVector is returned.
- ///
- /// </summary>
- /// <param name="docNumber">document for which the term frequency vector is returned
- /// </param>
- /// <param name="field">field for which the term frequency vector is returned.
- /// </param>
- /// <returns> term frequency vector May be null if field does not exist in the specified
- /// document or term vector was not stored.
- /// </returns>
- /// <throws> IOException if index cannot be accessed </throws>
- /// <seealso cref="Lucene.Net.document.Field.TermVector">
- /// </seealso>
- abstract public TermFreqVector GetTermFreqVector(int docNumber, System.String field);
-
- /// <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.
- /// </summary>
- /// <param name="directory">the directory to check for an index
- /// </param>
- /// <returns> <code>true</code> if an index exists; <code>false</code> otherwise
- /// </returns>
- public static bool IndexExists(System.String directory)
- {
- bool tmpBool;
- if (System.IO.File.Exists((new System.IO.FileInfo(System.IO.Path.Combine(directory, IndexFileNames.SEGMENTS))).FullName))
- tmpBool = true;
- else
- tmpBool = System.IO.Directory.Exists((new System.IO.FileInfo(System.IO.Path.Combine(directory, IndexFileNames.SEGMENTS))).FullName);
- return tmpBool;
- }
-
- /// <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.
- /// </summary>
- /// <param name="directory">the directory to check for an index
- /// </param>
- /// <returns> <code>true</code> if an index exists; <code>false</code> otherwise
- /// </returns>
- public static bool IndexExists(System.IO.FileInfo directory)
- {
- bool tmpBool;
- if (System.IO.File.Exists((new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, IndexFileNames.SEGMENTS))).FullName))
- tmpBool = true;
- else
- tmpBool = System.IO.Directory.Exists((new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, IndexFileNames.SEGMENTS))).FullName);
- return tmpBool;
- }
-
- /// <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.
- /// </summary>
- /// <param name="directory">the directory to check for an index
- /// </param>
- /// <returns> <code>true</code> if an index exists; <code>false</code> otherwise
- /// </returns>
- /// <throws> IOException if there is a problem with accessing the index </throws>
- public static bool IndexExists(Directory directory)
- {
- return directory.FileExists(IndexFileNames.SEGMENTS);
- }
-
- /// <summary>Returns the number of documents in this index. </summary>
- public abstract int NumDocs();
-
- /// <summary>Returns one greater than the largest possible document number.
- /// This may be used to, e.g., determine how big to allocate an array which
- /// will have an element for every document number in an index.
- /// </summary>
- public abstract int MaxDoc();
-
- /// <summary>Returns the stored fields of the <code>n</code><sup>th</sup>
- /// <code>Document</code> in this index.
- /// </summary>
- public abstract Document Document(int n);
-
- /// <summary>Returns true if document <i>n</i> has been deleted </summary>
- public abstract bool IsDeleted(int n);
-
- /// <summary>Returns true if any documents have been deleted </summary>
- public abstract bool HasDeletions();
-
- /// <summary>Returns true if there are norms stored for this field. </summary>
- public virtual bool HasNorms(System.String field)
- {
- // backward compatible implementation.
- // SegmentReader has an efficient implementation.
- return Norms(field) != null;
- }
-
- /// <summary>Returns the byte-encoded normalization factor for the named field of
- /// every document. This is used by the search code to score documents.
- ///
- /// </summary>
- /// <seealso cref="Field.SetBoost(float)">
- /// </seealso>
- public abstract byte[] Norms(System.String field);
-
- /// <summary>Reads the byte-encoded normalization factor for the named field of every
- /// document. This is used by the search code to score documents.
- ///
- /// </summary>
- /// <seealso cref="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
- /// Field#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>
- /// <seealso cref="Similarity.DecodeNorm(byte)">
- /// </seealso>
- public void SetNorm(int doc, System.String field, byte value_Renamed)
- {
- lock (this)
- {
- if (directoryOwner)
- AquireWriteLock();
- DoSetNorm(doc, field, value_Renamed);
- hasChanges = true;
- }
- }
-
- /// <summary>Implements setNorm in subclass.</summary>
- protected internal abstract void DoSetNorm(int doc, System.String field, byte value_Renamed);
-
- /// <summary>Expert: Resets the normalization factor for the named field of the named
- /// document.
- ///
- /// </summary>
- /// <seealso cref="Norms(String)">
- /// </seealso>
- /// <seealso cref="Similarity.DecodeNorm(byte)">
- /// </seealso>
- public virtual void SetNorm(int doc, System.String field, float value_Renamed)
- {
- 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>
- 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>
- public abstract TermEnum Terms(Term t);
-
- /// <summary>Returns the number of documents containing the term <code>t</code>. </summary>
- public abstract int DocFreq(Term t);
-
- /// <summary>Returns an enumeration of all the documents which contain
- /// <code>term</code>. For each document, the document number, the frequency of
- /// the term in that document is also provided, for use in search scoring.
- /// Thus, this method implements the mapping:
- /// <p><ul>
- /// Term => <docNum, freq><sup>*</sup>
- /// </ul>
- /// <p>The enumeration is ordered by document number. Each document number
- /// is greater than all that precede it in the enumeration.
- /// </summary>
- public virtual TermDocs TermDocs(Term term)
- {
- TermDocs termDocs = TermDocs();
- termDocs.Seek(term);
- return termDocs;
- }
-
- /// <summary>Returns an unpositioned {@link TermDocs} enumerator. </summary>
- public abstract TermDocs TermDocs();
-
- /// <summary>Returns an enumeration of all the documents which contain
- /// <code>term</code>. For each document, in addition to the document number
- /// and frequency of the term in that document, a list of all of the ordinal
- /// positions of the term in the document is available. Thus, this method
- /// implements the mapping:
- ///
- /// <p><ul>
- /// Term => <docNum, freq,
- /// <pos<sub>1</sub>, pos<sub>2</sub>, ...
- /// pos<sub>freq-1</sub>>
- /// ><sup>*</sup>
- /// </ul>
- /// <p> This positional information faciliates 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>
- public virtual TermPositions TermPositions(Term term)
- {
- TermPositions termPositions = TermPositions();
- termPositions.Seek(term);
- return termPositions;
- }
-
- /// <summary>Returns an unpositioned {@link TermPositions} enumerator. </summary>
- 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
- /// 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.
- ///
- /// </summary>
- /// <deprecated> Use {@link #DeleteDocument(int docNum)} instead.
- /// </deprecated>
- public void Delete(int docNum)
- {
- lock (this)
- {
- DeleteDocument(docNum);
- }
- }
-
- /// <summary>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.
- /// </summary>
- //UPGRADE_NOTE: Synchronized keyword was removed from method 'DeleteDocument'. Lock expression was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1027'"
- public void DeleteDocument(int docNum)
- {
- lock (this)
- {
- if (directoryOwner)
- AquireWriteLock();
- DoDelete(docNum);
- hasChanges = true;
- }
- }
-
-
- /// <summary>Implements deletion of the document numbered <code>docNum</code>.
- /// Applications should call {@link #Delete(int)} or {@link #Delete(Term)}.
- /// </summary>
- protected internal abstract void DoDelete(int docNum);
-
- /// <summary>Deletes all documents containing <code>term</code>.
- /// This is useful if one uses a document field to hold a unique ID string for
- /// the document. Then to delete such a document, one merely constructs a
- /// term with the appropriate field and the unique ID string as its text and
- /// passes it to this method.
- /// See {@link #Delete(int)} for information about when this deletion will
- /// become effective.
- /// </summary>
- /// <returns> the number of documents deleted
- ///
- /// </returns>
- /// <deprecated> Use {@link #DeleteDocuments(Term term)} instead.
- /// </deprecated>
- public int Delete(Term term)
- {
- return DeleteDocuments(term);
- }
-
- /// <summary>Deletes all documents containing <code>term</code>.
- /// This is useful if one uses a document field to hold a unique ID string for
- /// the document. Then to delete such a document, one merely constructs a
- /// term with the appropriate field and the unique ID string as its text and
- /// passes it to this method.
- /// See {@link #Delete(int)} for information about when this deletion will
- /// become effective.
- /// </summary>
- /// <returns> the number of documents deleted
- /// </returns>
- public int DeleteDocuments(Term term)
- {
- TermDocs docs = TermDocs(term);
- if (docs == null)
- return 0;
- int n = 0;
- try
- {
- while (docs.Next())
- {
- DeleteDocument(docs.Doc());
- n++;
- }
- }
- finally
- {
- docs.Close();
- }
- return n;
- }
-
- /// <summary>Undeletes all documents currently marked as deleted in this index.</summary>
- public void UndeleteAll()
- {
- lock (this)
- {
- if (directoryOwner)
- AquireWriteLock();
- DoUndeleteAll();
- hasChanges = true;
- }
- }
-
- /// <summary>Implements actual undeleteAll() in subclass. </summary>
- protected internal abstract void DoUndeleteAll();
-
- /// <summary> Commit changes resulting from delete, undeleteAll, or setNorm operations
- ///
- /// </summary>
- /// <throws> IOException </throws>
- protected internal void Commit()
- {
- lock (this)
- {
- if (hasChanges)
- {
- if (directoryOwner)
- {
- lock (directory)
- {
- // in- & inter-process sync
- new AnonymousClassWith1(this, directory.MakeLock(IndexWriter.COMMIT_LOCK_NAME), IndexWriter.COMMIT_LOCK_TIMEOUT).Run();
- }
- if (writeLock != null)
- {
- writeLock.Release(); // release write lock
- writeLock = null;
- }
- }
- else
- DoCommit();
- }
- hasChanges = false;
- }
- }
-
- /// <summary>Implements commit. </summary>
- protected internal abstract void DoCommit();
-
- /// <summary> Closes files associated with this index.
- /// Also saves any new deletions to disk.
- /// No other methods should be called after this has been called.
- /// </summary>
- public void Close()
- {
- lock (this)
- {
- Commit();
- DoClose();
- if (closeDirectory)
- directory.Close();
- System.GC.SuppressFinalize(this);
- }
- }
-
- /// <summary>Implements close. </summary>
- protected internal abstract void DoClose();
-
- /// <summary>Release the write lock, if needed. </summary>
- ~IndexReader()
- {
- if (writeLock != null)
- {
- writeLock.Release(); // release write lock
- writeLock = null;
- }
- }
-
- /// <summary> Returns a list of all unique field names that exist in the index pointed
- /// to by this IndexReader.
- /// </summary>
- /// <returns> Collection of Strings indicating the names of the fields
- /// </returns>
- /// <throws> IOException if there is a problem with accessing the index </throws>
- /// <summary>
- /// </summary>
- /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
- /// </deprecated>
- public abstract System.Collections.ICollection GetFieldNames();
-
- /// <summary> Returns a list of all unique field names that exist in the index pointed
- /// to by this IndexReader. The boolean argument specifies whether the fields
- /// returned are indexed or not.
- /// </summary>
- /// <param name="indexed"><code>true</code> if only indexed fields should be returned;
- /// <code>false</code> if only unindexed fields should be returned.
- /// </param>
- /// <returns> Collection of Strings indicating the names of the fields
- /// </returns>
- /// <throws> IOException if there is a problem with accessing the index </throws>
- /// <summary>
- /// </summary>
- /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
- /// </deprecated>
- public abstract System.Collections.ICollection GetFieldNames(bool indexed);
-
- /// <summary> </summary>
- /// <param name="storedTermVector">if true, returns only Indexed fields that have term vector info,
- /// else only indexed fields without term vector info
- /// </param>
- /// <returns> Collection of Strings indicating the names of the fields
- ///
- /// </returns>
- /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
- /// </deprecated>
- public virtual System.Collections.ICollection GetIndexedFieldNames(bool storedTermVector)
- {
- if (storedTermVector)
- {
- System.Collections.Hashtable fieldSet = new System.Collections.Hashtable();
- foreach (object item in GetIndexedFieldNames(Field.TermVector.YES))
- {
- if (fieldSet.ContainsKey(item) == false)
- {
- fieldSet.Add(item, item);
- }
- }
- foreach (object item in GetIndexedFieldNames(Field.TermVector.WITH_POSITIONS))
- {
- if (fieldSet.ContainsKey(item) == false)
- {
- fieldSet.Add(item, item);
- }
- }
- foreach (object item in GetIndexedFieldNames(Field.TermVector.WITH_OFFSETS))
- {
- if (fieldSet.ContainsKey(item) == false)
- {
- fieldSet.Add(item, item);
- }
- }
- foreach (object item in GetIndexedFieldNames(Field.TermVector.WITH_POSITIONS_OFFSETS))
- {
- if (fieldSet.ContainsKey(item) == false)
- {
- fieldSet.Add(item, item);
- }
- }
- return fieldSet;
- }
- else
- return GetIndexedFieldNames(Field.TermVector.NO);
- }
-
- /// <summary> Get a list of unique field names that exist in this index, are indexed, and have
- /// the specified term vector information.
- ///
- /// </summary>
- /// <param name="tvSpec">specifies which term vector information should be available for the fields
- /// </param>
- /// <returns> Collection of Strings indicating the names of the fields
- ///
- /// </returns>
- /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
- /// </deprecated>
- public abstract System.Collections.ICollection GetIndexedFieldNames(Field.TermVector tvSpec);
-
- /// <summary> Get a list of unique field names that exist in this index and have the specified
- /// field option information.
- /// </summary>
- /// <param name="fldOption">specifies which field option should be available for the returned fields
- /// </param>
- /// <returns> Collection of Strings indicating the names of the fields.
- /// </returns>
- /// <seealso cref="IndexReader.FieldOption">
- /// </seealso>
- public abstract System.Collections.ICollection GetFieldNames(FieldOption fldOption);
-
- /// <summary> Returns <code>true</code> iff the index in the named directory is
- /// currently locked.
- /// </summary>
- /// <param name="directory">the directory to check for a lock
- /// </param>
- /// <throws> IOException if there is a problem with accessing the index </throws>
- public static bool IsLocked(Directory directory)
- {
- return directory.MakeLock(IndexWriter.WRITE_LOCK_NAME).IsLocked() || directory.MakeLock(IndexWriter.COMMIT_LOCK_NAME).IsLocked();
- }
-
- /// <summary> Returns <code>true</code> iff the index in the named directory is
- /// currently locked.
- /// </summary>
- /// <param name="directory">the directory to check for a lock
- /// </param>
- /// <throws> IOException if there is a problem with accessing the index </throws>
- public static bool IsLocked(System.String directory)
- {
- Directory dir = FSDirectory.GetDirectory(directory, false);
- bool result = IsLocked(dir);
- dir.Close();
- return result;
- }
-
- /// <summary> Forcibly unlocks the index in the named directory.
- /// <P>
- /// Caution: this should only be used by failure recovery code,
- /// when it is known that no other process nor thread is in fact
- /// currently accessing this index.
- /// </summary>
- public static void Unlock(Directory directory)
- {
- directory.MakeLock(IndexWriter.WRITE_LOCK_NAME).Release();
- directory.MakeLock(IndexWriter.COMMIT_LOCK_NAME).Release();
- }
-
- /// <summary> Prints the filename and size of each file within a given compound file.
- /// Add the -extract flag to extract files to the current working directory.
- /// In order to make the extracted version of the index work, you have to copy
- /// the segments file from the compound index into the directory where the extracted files are stored.
- /// </summary>
- /// <param name="args">Usage: Lucene.Net.index.IndexReader [-extract] <cfsfile>
- /// </param>
- [STAThread]
- public static void Main(System.String[] args)
- {
- System.String filename = null;
- bool extract = false;
-
- for (int i = 0; i < args.Length; ++i)
- {
- if (args[i].Equals("-extract"))
- {
- extract = true;
- }
- else if (filename == null)
- {
- filename = args[i];
- }
- }
-
- if (filename == null)
- {
- System.Console.Out.WriteLine("Usage: Lucene.Net.index.IndexReader [-extract] <cfsfile>");
- return ;
- }
-
- Directory dir = null;
- CompoundFileReader cfr = null;
-
- try
- {
- System.IO.FileInfo file = new System.IO.FileInfo(filename);
- System.String dirname = new System.IO.FileInfo(file.FullName).DirectoryName;
- filename = file.Name;
- dir = FSDirectory.GetDirectory(dirname, false);
- cfr = new CompoundFileReader(dir, filename);
-
- System.String[] files = cfr.List();
- System.Array.Sort(files); // sort the array of filename so that the output is more readable
-
- for (int i = 0; i < files.Length; ++i)
- {
- long len = cfr.FileLength(files[i]);
-
- if (extract)
- {
- System.Console.Out.WriteLine("extract " + files[i] + " with " + len + " bytes to local directory...");
- IndexInput ii = cfr.OpenInput(files[i]);
-
- System.IO.FileStream f = new System.IO.FileStream(files[i], System.IO.FileMode.Create);
-
- // read and write with a small buffer, which is more effectiv than reading byte by byte
- byte[] buffer = new byte[1024];
- int chunk = buffer.Length;
- while (len > 0)
- {
- 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);
- len -= bufLen;
- }
-
- f.Close();
- ii.Close();
- }
- else
- System.Console.Out.WriteLine(files[i] + ": " + len + " bytes");
- }
- }
- catch (System.IO.IOException ioe)
- {
- System.Console.Error.WriteLine(ioe.StackTrace);
- }
- finally
- {
- try
- {
- if (dir != null)
- dir.Close();
- if (cfr != null)
- cfr.Close();
- }
- catch (System.IO.IOException ioe)
- {
- System.Console.Error.WriteLine(ioe.StackTrace);
- }
- }
- }
- }
- }