2 * Copyright 2004 The Apache Software Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 using Document
= Lucene
.Net
.Documents
.Document
;
19 using Field
= Lucene
.Net
.Documents
.Field
;
20 using Similarity
= Lucene
.Net
.Search
.Similarity
;
21 using Directory
= Lucene
.Net
.Store
.Directory
;
22 using FSDirectory
= Lucene
.Net
.Store
.FSDirectory
;
23 using IndexInput
= Lucene
.Net
.Store
.IndexInput
;
24 using Lock
= Lucene
.Net
.Store
.Lock
;
26 namespace Lucene
.Net
.Index
29 /// <summary>IndexReader is an abstract class, providing an interface for accessing an
30 /// index. Search of an index is done entirely through this abstract interface,
31 /// so that any subclass which implements it is searchable.
32 /// <p> Concrete subclasses of IndexReader are usually constructed with a call to
33 /// one of the static <code>open()</code> methods, e.g. {@link #Open(String)}.
34 /// <p> For efficiency, in this API documents are often referred to via
35 /// <i>document numbers</i>, non-negative integers which each name a unique
36 /// document in the index. These document numbers are ephemeral--they may change
37 /// as documents are added to and deleted from an index. Clients should thus not
38 /// rely on a given document having the same number between sessions.
40 /// <summary><p> An IndexReader can be opened on a directory for which an IndexWriter is
41 /// opened already, but it cannot be used to delete documents from the index then.
43 /// <author> Doug Cutting
45 /// <version> $Id: IndexReader.cs,v 1.4 2006/10/02 17:08:52 joeshaw Exp $
47 public abstract class IndexReader
49 private class AnonymousClassWith
: Lock
.With
51 private void InitBlock(Lucene
.Net
.Store
.Directory directory
, bool closeDirectory
)
53 this.directory
= directory
;
54 this.closeDirectory
= closeDirectory
;
56 private Lucene
.Net
.Store
.Directory directory
;
57 private bool closeDirectory
;
58 internal AnonymousClassWith(Lucene
.Net
.Store
.Directory directory
, bool closeDirectory
, Lucene
.Net
.Store
.Lock Param1
, long Param2
):base(Param1
, Param2
)
60 InitBlock(directory
, closeDirectory
);
62 public override System
.Object
DoBody()
64 SegmentInfos infos
= new SegmentInfos();
65 infos
.Read(directory
);
69 return SegmentReader
.Get(infos
, infos
.Info(0), closeDirectory
);
71 IndexReader
[] readers
= new IndexReader
[infos
.Count
];
72 for (int i
= 0; i
< infos
.Count
; i
++)
73 readers
[i
] = SegmentReader
.Get(infos
.Info(i
));
74 return new MultiReader(directory
, infos
, closeDirectory
, readers
);
77 private class AnonymousClassWith1
: Lock
.With
79 private void InitBlock(IndexReader enclosingInstance
)
81 this.enclosingInstance
= enclosingInstance
;
83 private IndexReader enclosingInstance
;
84 public IndexReader Enclosing_Instance
88 return enclosingInstance
;
92 internal AnonymousClassWith1(IndexReader enclosingInstance
, Lucene
.Net
.Store
.Lock Param1
, long Param2
) : base(Param1
, Param2
)
94 InitBlock(enclosingInstance
);
96 public override System
.Object
DoBody()
98 Enclosing_Instance
.DoCommit();
99 Enclosing_Instance
.segmentInfos
.Write(Enclosing_Instance
.directory
);
104 public sealed class FieldOption
106 private System
.String option
;
107 internal FieldOption()
110 internal FieldOption(System
.String option
)
112 this.option
= option
;
114 public override System
.String
ToString()
119 public static readonly FieldOption ALL
= new FieldOption("ALL");
120 // all indexed fields
121 public static readonly FieldOption INDEXED
= new FieldOption("INDEXED");
122 // all fields which are not indexed
123 public static readonly FieldOption UNINDEXED
= new FieldOption("UNINDEXED");
124 // all fields which are indexed with termvectors enables
125 public static readonly FieldOption INDEXED_WITH_TERMVECTOR
= new FieldOption("INDEXED_WITH_TERMVECTOR");
126 // all fields which are indexed but don't have termvectors enabled
127 public static readonly FieldOption INDEXED_NO_TERMVECTOR
= new FieldOption("INDEXED_NO_TERMVECTOR");
128 // all fields where termvectors are enabled. Please note that only standard termvector fields are returned
129 public static readonly FieldOption TERMVECTOR
= new FieldOption("TERMVECTOR");
130 // all field with termvectors wiht positions enabled
131 public static readonly FieldOption TERMVECTOR_WITH_POSITION
= new FieldOption("TERMVECTOR_WITH_POSITION");
132 // all fields where termvectors with offset position are set
133 public static readonly FieldOption TERMVECTOR_WITH_OFFSET
= new FieldOption("TERMVECTOR_WITH_OFFSET");
134 // all fields where termvectors with offset and position values set
135 public static readonly FieldOption TERMVECTOR_WITH_POSITION_OFFSET
= new FieldOption("TERMVECTOR_WITH_POSITION_OFFSET");
138 /// <summary> Constructor used if IndexReader is not owner of its directory.
139 /// This is used for IndexReaders that are used within other IndexReaders that take care or locking directories.
142 /// <param name="directory">Directory where IndexReader files reside.
144 protected internal IndexReader(Directory directory
)
146 this.directory
= directory
;
149 /// <summary> Constructor used if IndexReader is owner of its directory.
150 /// If IndexReader is owner of its directory, it locks its directory in case of write operations.
153 /// <param name="directory">Directory where IndexReader files reside.
155 /// <param name="segmentInfos">Used for write-l
157 /// <param name="closeDirectory">
159 internal IndexReader(Directory directory
, SegmentInfos segmentInfos
, bool closeDirectory
)
161 Init(directory
, segmentInfos
, closeDirectory
, true);
164 internal virtual void Init(Directory directory
, SegmentInfos segmentInfos
, bool closeDirectory
, bool directoryOwner
)
166 this.directory
= directory
;
167 this.segmentInfos
= segmentInfos
;
168 this.directoryOwner
= directoryOwner
;
169 this.closeDirectory
= closeDirectory
;
172 private Directory directory
;
173 private bool directoryOwner
;
174 private bool closeDirectory
;
176 private SegmentInfos segmentInfos
;
177 private Lock writeLock
;
179 private bool hasChanges
;
182 /// <summary>Returns an IndexReader reading the index in an FSDirectory in the named
185 public static IndexReader
Open(System
.String path
)
187 return Open(FSDirectory
.GetDirectory(path
, false), true);
190 /// <summary>Returns an IndexReader reading the index in an FSDirectory in the named
193 public static IndexReader
Open(System
.IO
.FileInfo path
)
195 return Open(FSDirectory
.GetDirectory(path
, false), true);
198 /// <summary>Returns an IndexReader reading the index in the given Directory. </summary>
199 public static IndexReader
Open(Directory directory
)
201 return Open(directory
, false);
204 private static IndexReader
Open(Directory directory
, bool closeDirectory
)
208 // in- & inter-process sync
209 return (IndexReader
) new AnonymousClassWith(directory
, closeDirectory
, directory
.MakeLock(IndexWriter
.COMMIT_LOCK_NAME
), IndexWriter
.COMMIT_LOCK_TIMEOUT
).Run();
213 /// <summary>Returns the directory this index resides in. </summary>
214 public virtual Directory
Directory()
219 /// <summary> Returns the time the index in the named directory was last modified.
220 /// Do not use this to check whether the reader is still up-to-date, use
221 /// {@link #IsCurrent()} instead.
223 public static long LastModified(System
.String directory
)
225 return LastModified(new System
.IO
.FileInfo(directory
));
228 /// <summary> Returns the time the index in the named directory was last modified.
229 /// Do not use this to check whether the reader is still up-to-date, use
230 /// {@link #IsCurrent()} instead.
232 public static long LastModified(System
.IO
.FileInfo directory
)
234 return FSDirectory
.FileModified(directory
, IndexFileNames
.SEGMENTS
);
237 /// <summary> Returns the time the index in the named directory was last modified.
238 /// Do not use this to check whether the reader is still up-to-date, use
239 /// {@link #IsCurrent()} instead.
241 public static long LastModified(Directory directory
)
243 return directory
.FileModified(IndexFileNames
.SEGMENTS
);
246 /// <summary> Reads version number from segments files. The version number is
247 /// initialized with a timestamp and then increased by one for each change of
251 /// <param name="directory">where the index resides.
253 /// <returns> version number.
255 /// <throws> IOException if segments file cannot be read </throws>
256 public static long GetCurrentVersion(System
.String directory
)
258 return GetCurrentVersion(new System
.IO
.FileInfo(directory
));
261 /// <summary> Reads version number from segments files. The version number is
262 /// initialized with a timestamp and then increased by one for each change of
266 /// <param name="directory">where the index resides.
268 /// <returns> version number.
270 /// <throws> IOException if segments file cannot be read </throws>
271 public static long GetCurrentVersion(System
.IO
.FileInfo directory
)
273 Directory dir
= FSDirectory
.GetDirectory(directory
, false);
274 long version
= GetCurrentVersion(dir
);
279 /// <summary> Reads version number from segments files. The version number is
280 /// initialized with a timestamp and then increased by one for each change of
284 /// <param name="directory">where the index resides.
286 /// <returns> version number.
288 /// <throws> IOException if segments file cannot be read. </throws>
289 public static long GetCurrentVersion(Directory directory
)
291 return SegmentInfos
.ReadCurrentVersion(directory
);
294 /// <summary> Version number when this IndexReader was opened.</summary>
295 public virtual long GetVersion()
297 return segmentInfos
.GetVersion();
300 /// <summary> Check whether this IndexReader still works on a current version of the index.
301 /// If this is not the case you will need to re-open the IndexReader to
302 /// make sure you see the latest changes made to the index.
305 /// <throws> IOException </throws>
306 public virtual bool IsCurrent()
308 if (SegmentInfos
.ReadCurrentVersion(directory
) != segmentInfos
.GetVersion())
315 /// <summary> Return an array of term frequency vectors for the specified document.
316 /// The array contains a vector for each vectorized field in the document.
317 /// Each vector contains terms and frequencies for all terms in a given vectorized field.
318 /// If no such fields existed, the method returns null. The term vectors that are
319 /// returned my either be of type TermFreqVector or of type TermPositionsVector if
320 /// positions or offsets have been stored.
323 /// <param name="docNumber">document for which term frequency vectors are returned
325 /// <returns> array of term frequency vectors. May be null if no term vectors have been
326 /// stored for the specified document.
328 /// <throws> IOException if index cannot be accessed </throws>
329 /// <seealso cref="Lucene.Net.document.Field.TermVector">
331 abstract public TermFreqVector
[] GetTermFreqVectors(int docNumber
);
334 /// <summary> Return a term frequency vector for the specified document and field. The
335 /// returned vector contains terms and frequencies for the terms in
336 /// the specified field of this document, if the field had the storeTermVector
337 /// flag set. If termvectors had been stored with positions or offsets, a
338 /// TermPositionsVector is returned.
341 /// <param name="docNumber">document for which the term frequency vector is returned
343 /// <param name="field">field for which the term frequency vector is returned.
345 /// <returns> term frequency vector May be null if field does not exist in the specified
346 /// document or term vector was not stored.
348 /// <throws> IOException if index cannot be accessed </throws>
349 /// <seealso cref="Lucene.Net.document.Field.TermVector">
351 abstract public TermFreqVector
GetTermFreqVector(int docNumber
, System
.String field
);
353 /// <summary> Returns <code>true</code> if an index exists at the specified directory.
354 /// If the directory does not exist or if there is no index in it.
355 /// <code>false</code> is returned.
357 /// <param name="directory">the directory to check for an index
359 /// <returns> <code>true</code> if an index exists; <code>false</code> otherwise
361 public static bool IndexExists(System
.String directory
)
364 if (System
.IO
.File
.Exists((new System
.IO
.FileInfo(System
.IO
.Path
.Combine(directory
, IndexFileNames
.SEGMENTS
))).FullName
))
367 tmpBool
= System
.IO
.Directory
.Exists((new System
.IO
.FileInfo(System
.IO
.Path
.Combine(directory
, IndexFileNames
.SEGMENTS
))).FullName
);
371 /// <summary> Returns <code>true</code> if an index exists at the specified directory.
372 /// If the directory does not exist or if there is no index in it.
374 /// <param name="directory">the directory to check for an index
376 /// <returns> <code>true</code> if an index exists; <code>false</code> otherwise
378 public static bool IndexExists(System
.IO
.FileInfo directory
)
381 if (System
.IO
.File
.Exists((new System
.IO
.FileInfo(System
.IO
.Path
.Combine(directory
.FullName
, IndexFileNames
.SEGMENTS
))).FullName
))
384 tmpBool
= System
.IO
.Directory
.Exists((new System
.IO
.FileInfo(System
.IO
.Path
.Combine(directory
.FullName
, IndexFileNames
.SEGMENTS
))).FullName
);
388 /// <summary> Returns <code>true</code> if an index exists at the specified directory.
389 /// If the directory does not exist or if there is no index in it.
391 /// <param name="directory">the directory to check for an index
393 /// <returns> <code>true</code> if an index exists; <code>false</code> otherwise
395 /// <throws> IOException if there is a problem with accessing the index </throws>
396 public static bool IndexExists(Directory directory
)
398 return directory
.FileExists(IndexFileNames
.SEGMENTS
);
401 /// <summary>Returns the number of documents in this index. </summary>
402 public abstract int NumDocs();
404 /// <summary>Returns one greater than the largest possible document number.
405 /// This may be used to, e.g., determine how big to allocate an array which
406 /// will have an element for every document number in an index.
408 public abstract int MaxDoc();
410 /// <summary>Returns the stored fields of the <code>n</code><sup>th</sup>
411 /// <code>Document</code> in this index.
413 public abstract Document
Document(int n
);
415 /// <summary>Returns true if document <i>n</i> has been deleted </summary>
416 public abstract bool IsDeleted(int n
);
418 /// <summary>Returns true if any documents have been deleted </summary>
419 public abstract bool HasDeletions();
421 /// <summary>Returns true if there are norms stored for this field. </summary>
422 public virtual bool HasNorms(System
.String field
)
424 // backward compatible implementation.
425 // SegmentReader has an efficient implementation.
426 return Norms(field
) != null;
429 /// <summary>Returns the byte-encoded normalization factor for the named field of
430 /// every document. This is used by the search code to score documents.
433 /// <seealso cref="Field.SetBoost(float)">
435 public abstract byte[] Norms(System
.String field
);
437 /// <summary>Reads the byte-encoded normalization factor for the named field of every
438 /// document. This is used by the search code to score documents.
441 /// <seealso cref="Field.SetBoost(float)">
443 public abstract void Norms(System
.String field
, byte[] bytes
, int offset
);
445 /// <summary>Expert: Resets the normalization factor for the named field of the named
446 /// document. The norm represents the product of the field's {@link
447 /// Field#SetBoost(float) boost} and its {@link Similarity#LengthNorm(String,
448 /// int) length normalization}. Thus, to preserve the length normalization
449 /// values when resetting this, one should base the new value upon the old.
452 /// <seealso cref="Norms(String)">
454 /// <seealso cref="Similarity.DecodeNorm(byte)">
456 public void SetNorm(int doc
, System
.String field
, byte value_Renamed
)
462 DoSetNorm(doc
, field
, value_Renamed
);
467 /// <summary>Implements setNorm in subclass.</summary>
468 protected internal abstract void DoSetNorm(int doc
, System
.String field
, byte value_Renamed
);
470 /// <summary>Expert: Resets the normalization factor for the named field of the named
474 /// <seealso cref="Norms(String)">
476 /// <seealso cref="Similarity.DecodeNorm(byte)">
478 public virtual void SetNorm(int doc
, System
.String field
, float value_Renamed
)
480 SetNorm(doc
, field
, Similarity
.EncodeNorm(value_Renamed
));
483 /// <summary>Returns an enumeration of all the terms in the index.
484 /// The enumeration is ordered by Term.compareTo(). Each term
485 /// is greater than all that precede it in the enumeration.
487 public abstract TermEnum
Terms();
489 /// <summary>Returns an enumeration of all terms after a given term.
490 /// The enumeration is ordered by Term.compareTo(). Each term
491 /// is greater than all that precede it in the enumeration.
493 public abstract TermEnum
Terms(Term t
);
495 /// <summary>Returns the number of documents containing the term <code>t</code>. </summary>
496 public abstract int DocFreq(Term t
);
498 /// <summary>Returns an enumeration of all the documents which contain
499 /// <code>term</code>. For each document, the document number, the frequency of
500 /// the term in that document is also provided, for use in search scoring.
501 /// Thus, this method implements the mapping:
503 /// Term => <docNum, freq><sup>*</sup>
505 /// <p>The enumeration is ordered by document number. Each document number
506 /// is greater than all that precede it in the enumeration.
508 public virtual TermDocs
TermDocs(Term term
)
510 TermDocs termDocs
= TermDocs();
515 /// <summary>Returns an unpositioned {@link TermDocs} enumerator. </summary>
516 public abstract TermDocs
TermDocs();
518 /// <summary>Returns an enumeration of all the documents which contain
519 /// <code>term</code>. For each document, in addition to the document number
520 /// and frequency of the term in that document, a list of all of the ordinal
521 /// positions of the term in the document is available. Thus, this method
522 /// implements the mapping:
525 /// Term => <docNum, freq,
526 /// <pos<sub>1</sub>, pos<sub>2</sub>, ...
527 /// pos<sub>freq-1</sub>>
530 /// <p> This positional information faciliates phrase and proximity searching.
531 /// <p>The enumeration is ordered by document number. Each document number is
532 /// greater than all that precede it in the enumeration.
534 public virtual TermPositions
TermPositions(Term term
)
536 TermPositions termPositions
= TermPositions();
537 termPositions
.Seek(term
);
538 return termPositions
;
541 /// <summary>Returns an unpositioned {@link TermPositions} enumerator. </summary>
542 public abstract TermPositions
TermPositions();
544 /// <summary> Tries to acquire the WriteLock on this directory.
545 /// this method is only valid if this IndexReader is directory owner.
548 /// <throws> IOException If WriteLock cannot be acquired. </throws>
549 private void AquireWriteLock()
552 throw new System
.IO
.IOException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
554 if (this.writeLock
== null)
556 Lock writeLock
= directory
.MakeLock(IndexWriter
.WRITE_LOCK_NAME
);
557 if (!writeLock
.Obtain(IndexWriter
.WRITE_LOCK_TIMEOUT
))
560 throw new System
.IO
.IOException("Index locked for write: " + writeLock
);
562 this.writeLock
= writeLock
;
564 // we have to check whether index has changed since this reader was opened.
565 // if so, this reader is no longer valid for deletion
566 if (SegmentInfos
.ReadCurrentVersion(directory
) > segmentInfos
.GetVersion())
569 this.writeLock
.Release();
570 this.writeLock
= null;
571 throw new System
.IO
.IOException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
576 /// <summary>Deletes the document numbered <code>docNum</code>. Once a document is
577 /// deleted it will not appear in TermDocs or TermPostitions enumerations.
578 /// Attempts to read its field with the {@link #document}
579 /// method will result in an error. The presence of this document may still be
580 /// reflected in the {@link #docFreq} statistic, though
581 /// this will be corrected eventually as the index is further modified.
584 /// <deprecated> Use {@link #DeleteDocument(int docNum)} instead.
586 public void Delete(int docNum
)
590 DeleteDocument(docNum
);
594 /// <summary>Deletes the document numbered <code>docNum</code>. Once a document is
595 /// deleted it will not appear in TermDocs or TermPostitions enumerations.
596 /// Attempts to read its field with the {@link #document}
597 /// method will result in an error. The presence of this document may still be
598 /// reflected in the {@link #docFreq} statistic, though
599 /// this will be corrected eventually as the index is further modified.
601 public void DeleteDocument(int docNum
)
613 /// <summary>Implements deletion of the document numbered <code>docNum</code>.
614 /// Applications should call {@link #Delete(int)} or {@link #Delete(Term)}.
616 protected internal abstract void DoDelete(int docNum
);
618 /// <summary>Deletes all documents containing <code>term</code>.
619 /// This is useful if one uses a document field to hold a unique ID string for
620 /// the document. Then to delete such a document, one merely constructs a
621 /// term with the appropriate field and the unique ID string as its text and
622 /// passes it to this method.
623 /// See {@link #Delete(int)} for information about when this deletion will
624 /// become effective.
626 /// <returns> the number of documents deleted
629 /// <deprecated> Use {@link #DeleteDocuments(Term term)} instead.
631 public int Delete(Term term
)
633 return DeleteDocuments(term
);
636 /// <summary>Deletes all documents containing <code>term</code>.
637 /// This is useful if one uses a document field to hold a unique ID string for
638 /// the document. Then to delete such a document, one merely constructs a
639 /// term with the appropriate field and the unique ID string as its text and
640 /// passes it to this method.
641 /// See {@link #Delete(int)} for information about when this deletion will
642 /// become effective.
644 /// <returns> the number of documents deleted
646 public int DeleteDocuments(Term term
)
648 TermDocs docs
= TermDocs(term
);
656 DeleteDocument(docs
.Doc());
667 /// <summary>Undeletes all documents currently marked as deleted in this index.</summary>
668 public void UndeleteAll()
679 /// <summary>Implements actual undeleteAll() in subclass. </summary>
680 protected internal abstract void DoUndeleteAll();
682 /// <summary> Commit changes resulting from delete, undeleteAll, or setNorm operations
685 /// <throws> IOException </throws>
686 protected internal void Commit()
696 // in- & inter-process sync
697 new AnonymousClassWith1(this, directory
.MakeLock(IndexWriter
.COMMIT_LOCK_NAME
), IndexWriter
.COMMIT_LOCK_TIMEOUT
).Run();
699 if (writeLock
!= null)
701 writeLock
.Release(); // release write lock
712 /// <summary>Implements commit. </summary>
713 protected internal abstract void DoCommit();
715 /// <summary> Closes files associated with this index.
716 /// Also saves any new deletions to disk.
717 /// No other methods should be called after this has been called.
727 System
.GC
.SuppressFinalize(this);
731 /// <summary>Implements close. </summary>
732 protected internal abstract void DoClose();
734 /// <summary>Release the write lock, if needed. </summary>
737 if (writeLock
!= null)
739 writeLock
.Release(); // release write lock
744 /// <summary> Returns a list of all unique field names that exist in the index pointed
745 /// to by this IndexReader.
747 /// <returns> Collection of Strings indicating the names of the fields
749 /// <throws> IOException if there is a problem with accessing the index </throws>
752 /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
754 public abstract System
.Collections
.ICollection
GetFieldNames();
756 /// <summary> Returns a list of all unique field names that exist in the index pointed
757 /// to by this IndexReader. The boolean argument specifies whether the fields
758 /// returned are indexed or not.
760 /// <param name="indexed"><code>true</code> if only indexed fields should be returned;
761 /// <code>false</code> if only unindexed fields should be returned.
763 /// <returns> Collection of Strings indicating the names of the fields
765 /// <throws> IOException if there is a problem with accessing the index </throws>
768 /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
770 public abstract System
.Collections
.ICollection
GetFieldNames(bool indexed
);
772 /// <summary> </summary>
773 /// <param name="storedTermVector">if true, returns only Indexed fields that have term vector info,
774 /// else only indexed fields without term vector info
776 /// <returns> Collection of Strings indicating the names of the fields
779 /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
781 public virtual System
.Collections
.ICollection
GetIndexedFieldNames(bool storedTermVector
)
783 if (storedTermVector
)
785 System
.Collections
.Hashtable fieldSet
= new System
.Collections
.Hashtable();
786 foreach (object item
in GetIndexedFieldNames(Field
.TermVector
.YES
))
788 if (fieldSet
.ContainsKey(item
) == false)
790 fieldSet
.Add(item
, item
);
793 foreach (object item
in GetIndexedFieldNames(Field
.TermVector
.WITH_POSITIONS
))
795 if (fieldSet
.ContainsKey(item
) == false)
797 fieldSet
.Add(item
, item
);
800 foreach (object item
in GetIndexedFieldNames(Field
.TermVector
.WITH_OFFSETS
))
802 if (fieldSet
.ContainsKey(item
) == false)
804 fieldSet
.Add(item
, item
);
807 foreach (object item
in GetIndexedFieldNames(Field
.TermVector
.WITH_POSITIONS_OFFSETS
))
809 if (fieldSet
.ContainsKey(item
) == false)
811 fieldSet
.Add(item
, item
);
817 return GetIndexedFieldNames(Field
.TermVector
.NO
);
820 /// <summary> Get a list of unique field names that exist in this index, are indexed, and have
821 /// the specified term vector information.
824 /// <param name="tvSpec">specifies which term vector information should be available for the fields
826 /// <returns> Collection of Strings indicating the names of the fields
829 /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
831 public abstract System
.Collections
.ICollection
GetIndexedFieldNames(Field
.TermVector tvSpec
);
833 /// <summary> Get a list of unique field names that exist in this index and have the specified
834 /// field option information.
836 /// <param name="fldOption">specifies which field option should be available for the returned fields
838 /// <returns> Collection of Strings indicating the names of the fields.
840 /// <seealso cref="IndexReader.FieldOption">
842 public abstract System
.Collections
.ICollection
GetFieldNames(FieldOption fldOption
);
844 /// <summary> Returns <code>true</code> iff the index in the named directory is
845 /// currently locked.
847 /// <param name="directory">the directory to check for a lock
849 /// <throws> IOException if there is a problem with accessing the index </throws>
850 public static bool IsLocked(Directory directory
)
852 return directory
.MakeLock(IndexWriter
.WRITE_LOCK_NAME
).IsLocked() || directory
.MakeLock(IndexWriter
.COMMIT_LOCK_NAME
).IsLocked();
855 /// <summary> Returns <code>true</code> iff the index in the named directory is
856 /// currently locked.
858 /// <param name="directory">the directory to check for a lock
860 /// <throws> IOException if there is a problem with accessing the index </throws>
861 public static bool IsLocked(System
.String directory
)
863 Directory dir
= FSDirectory
.GetDirectory(directory
, false);
864 bool result
= IsLocked(dir
);
869 /// <summary> Forcibly unlocks the index in the named directory.
871 /// Caution: this should only be used by failure recovery code,
872 /// when it is known that no other process nor thread is in fact
873 /// currently accessing this index.
875 public static void Unlock(Directory directory
)
877 directory
.MakeLock(IndexWriter
.WRITE_LOCK_NAME
).Release();
878 directory
.MakeLock(IndexWriter
.COMMIT_LOCK_NAME
).Release();
881 /// <summary> Prints the filename and size of each file within a given compound file.
882 /// Add the -extract flag to extract files to the current working directory.
883 /// In order to make the extracted version of the index work, you have to copy
884 /// the segments file from the compound index into the directory where the extracted files are stored.
886 /// <param name="args">Usage: Lucene.Net.index.IndexReader [-extract] <cfsfile>
889 public static void Main(System
.String
[] args
)
891 System
.String filename
= null;
892 bool extract
= false;
894 for (int i
= 0; i
< args
.Length
; ++i
)
896 if (args
[i
].Equals("-extract"))
900 else if (filename
== null)
906 if (filename
== null)
908 System
.Console
.Out
.WriteLine("Usage: Lucene.Net.index.IndexReader [-extract] <cfsfile>");
912 Directory dir
= null;
913 CompoundFileReader cfr
= null;
917 System
.IO
.FileInfo file
= new System
.IO
.FileInfo(filename
);
918 System
.String dirname
= new System
.IO
.FileInfo(file
.FullName
).DirectoryName
;
919 filename
= file
.Name
;
920 dir
= FSDirectory
.GetDirectory(dirname
, false);
921 cfr
= new CompoundFileReader(dir
, filename
);
923 System
.String
[] files
= cfr
.List();
924 System
.Array
.Sort(files
); // sort the array of filename so that the output is more readable
926 for (int i
= 0; i
< files
.Length
; ++i
)
928 long len
= cfr
.FileLength(files
[i
]);
932 System
.Console
.Out
.WriteLine("extract " + files
[i
] + " with " + len
+ " bytes to local directory...");
933 IndexInput ii
= cfr
.OpenInput(files
[i
]);
935 System
.IO
.FileStream f
= new System
.IO
.FileStream(files
[i
], System
.IO
.FileMode
.Create
);
937 // read and write with a small buffer, which is more effectiv than reading byte by byte
938 byte[] buffer
= new byte[1024];
939 int chunk
= buffer
.Length
;
942 int bufLen
= (int) System
.Math
.Min(chunk
, len
);
943 ii
.ReadBytes(buffer
, 0, bufLen
);
945 byte[] byteArray
= new byte[buffer
.Length
];
946 for (int index
=0; index
< buffer
.Length
; index
++)
947 byteArray
[index
] = (byte) buffer
[index
];
949 f
.Write(byteArray
, 0, bufLen
);
958 System
.Console
.Out
.WriteLine(files
[i
] + ": " + len
+ " bytes");
961 catch (System
.IO
.IOException ioe
)
963 System
.Console
.Error
.WriteLine(ioe
.StackTrace
);
974 catch (System
.IO
.IOException ioe
)
976 System
.Console
.Error
.WriteLine(ioe
.StackTrace
);