Add --enable-deletion option to buildindex. If used, buildindex will remove deleted...
[beagle.git] / beagled / Lucene.Net / Index / IndexReader.cs
blob910b10c11777a3fff08e45133ea0988e681244c2
1 /*
2 * Copyright 2004 The Apache Software Foundation
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
16 using System;
17 using Document = Lucene.Net.Documents.Document;
18 using Field = Lucene.Net.Documents.Field;
19 using Similarity = Lucene.Net.Search.Similarity;
20 using Directory = Lucene.Net.Store.Directory;
21 using FSDirectory = Lucene.Net.Store.FSDirectory;
22 using IndexInput = Lucene.Net.Store.IndexInput;
23 using Lock = Lucene.Net.Store.Lock;
24 namespace Lucene.Net.Index
27 /// <summary>IndexReader is an abstract class, providing an interface for accessing an
28 /// index. Search of an index is done entirely through this abstract interface,
29 /// so that any subclass which implements it is searchable.
30 /// <p> Concrete subclasses of IndexReader are usually constructed with a call to
31 /// one of the static <code>open()</code> methods, e.g. {@link #Open(String)}.
32 /// <p> For efficiency, in this API documents are often referred to via
33 /// <i>document numbers</i>, non-negative integers which each name a unique
34 /// document in the index. These document numbers are ephemeral--they may change
35 /// as documents are added to and deleted from an index. Clients should thus not
36 /// rely on a given document having the same number between sessions.
37 /// </summary>
38 /// <author> Doug Cutting
39 /// </author>
40 /// <version> $Id: IndexReader.cs,v 1.3 2005/10/06 19:29:55 dsd Exp $
41 /// </version>
42 public abstract class IndexReader
44 private class AnonymousClassWith : Lock.With
46 private void InitBlock(Lucene.Net.Store.Directory directory, bool closeDirectory)
48 this.directory = directory;
49 this.closeDirectory = closeDirectory;
51 private Lucene.Net.Store.Directory directory;
52 private bool closeDirectory;
53 internal AnonymousClassWith(Lucene.Net.Store.Directory directory, bool closeDirectory, Lucene.Net.Store.Lock Param1, long Param2) : base(Param1, Param2)
55 InitBlock(directory, closeDirectory);
57 public override System.Object DoBody()
59 SegmentInfos infos = new SegmentInfos();
60 infos.Read(directory);
61 if (infos.Count == 1)
63 // index is optimized
64 return SegmentReader.Get(infos, infos.Info(0), closeDirectory);
66 IndexReader[] readers = new IndexReader[infos.Count];
67 for (int i = 0; i < infos.Count; i++)
68 readers[i] = SegmentReader.Get(infos.Info(i));
69 return new MultiReader(directory, infos, closeDirectory, readers);
72 private class AnonymousClassWith1 : Lock.With
74 private void InitBlock(IndexReader enclosingInstance)
76 this.enclosingInstance = enclosingInstance;
78 private IndexReader enclosingInstance;
79 public IndexReader Enclosing_Instance
81 get
83 return enclosingInstance;
87 internal AnonymousClassWith1(IndexReader enclosingInstance, Lucene.Net.Store.Lock Param1, long Param2) : base(Param1, Param2)
89 InitBlock(enclosingInstance);
91 public override System.Object DoBody()
93 Enclosing_Instance.DoCommit();
94 Enclosing_Instance.segmentInfos.Write(Enclosing_Instance.directory);
95 return null;
99 public sealed class FieldOption
101 private System.String option;
102 internal FieldOption()
105 internal FieldOption(System.String option)
107 this.option = option;
109 public override System.String ToString()
111 return this.option;
113 // all fields
114 public static readonly FieldOption ALL = new FieldOption("ALL");
115 // all indexed fields
116 public static readonly FieldOption INDEXED = new FieldOption("INDEXED");
117 // all fields which are not indexed
118 public static readonly FieldOption UNINDEXED = new FieldOption("UNINDEXED");
119 // all fields which are indexed with termvectors enables
120 public static readonly FieldOption INDEXED_WITH_TERMVECTOR = new FieldOption("INDEXED_WITH_TERMVECTOR");
121 // all fields which are indexed but don't have termvectors enabled
122 public static readonly FieldOption INDEXED_NO_TERMVECTOR = new FieldOption("INDEXED_NO_TERMVECTOR");
123 // all fields where termvectors are enabled. Please note that only standard termvector fields are returned
124 public static readonly FieldOption TERMVECTOR = new FieldOption("TERMVECTOR");
125 // all field with termvectors wiht positions enabled
126 public static readonly FieldOption TERMVECTOR_WITH_POSITION = new FieldOption("TERMVECTOR_WITH_POSITION");
127 // all fields where termvectors with offset position are set
128 public static readonly FieldOption TERMVECTOR_WITH_OFFSET = new FieldOption("TERMVECTOR_WITH_OFFSET");
129 // all fields where termvectors with offset and position values set
130 public static readonly FieldOption TERMVECTOR_WITH_POSITION_OFFSET = new FieldOption("TERMVECTOR_WITH_POSITION_OFFSET");
133 /// <summary> Constructor used if IndexReader is not owner of its directory.
134 /// This is used for IndexReaders that are used within other IndexReaders that take care or locking directories.
135 ///
136 /// </summary>
137 /// <param name="directory">Directory where IndexReader files reside.
138 /// </param>
139 protected internal IndexReader(Directory directory)
141 this.directory = directory;
144 /// <summary> Constructor used if IndexReader is owner of its directory.
145 /// If IndexReader is owner of its directory, it locks its directory in case of write operations.
146 ///
147 /// </summary>
148 /// <param name="directory">Directory where IndexReader files reside.
149 /// </param>
150 /// <param name="segmentInfos">Used for write-l
151 /// </param>
152 /// <param name="">closeDirectory
153 /// </param>
154 internal IndexReader(Directory directory, SegmentInfos segmentInfos, bool closeDirectory)
156 Init(directory, segmentInfos, closeDirectory, true);
159 internal virtual void Init(Directory directory, SegmentInfos segmentInfos, bool closeDirectory, bool directoryOwner)
161 this.directory = directory;
162 this.segmentInfos = segmentInfos;
163 this.directoryOwner = directoryOwner;
164 this.closeDirectory = closeDirectory;
167 private Directory directory;
168 private bool directoryOwner;
169 private bool closeDirectory;
171 private SegmentInfos segmentInfos;
172 private Lock writeLock;
173 private bool stale;
174 private bool hasChanges;
177 /// <summary>Returns an IndexReader reading the index in an FSDirectory in the named
178 /// path.
179 /// </summary>
180 public static IndexReader Open(System.String path)
182 return Open(FSDirectory.GetDirectory(path, false), true);
185 /// <summary>Returns an IndexReader reading the index in an FSDirectory in the named
186 /// path.
187 /// </summary>
188 public static IndexReader Open(System.IO.FileInfo path)
190 return Open(FSDirectory.GetDirectory(path, false), true);
193 /// <summary>Returns an IndexReader reading the index in the given Directory. </summary>
194 public static IndexReader Open(Directory directory)
196 return Open(directory, false);
199 private static IndexReader Open(Directory directory, bool closeDirectory)
201 lock (directory)
203 // in- & inter-process sync
204 return (IndexReader) new AnonymousClassWith(directory, closeDirectory, directory.MakeLock(IndexWriter.COMMIT_LOCK_NAME), IndexWriter.COMMIT_LOCK_TIMEOUT).Run();
208 /// <summary>Returns the directory this index resides in. </summary>
209 public virtual Directory Directory()
211 return directory;
214 /// <summary> Returns the time the index in the named directory was last modified.
215 ///
216 /// <p>Synchronization of IndexReader and IndexWriter instances is
217 /// no longer done via time stamps of the segments file since the time resolution
218 /// depends on the hardware platform. Instead, a version number is maintained
219 /// within the segments file, which is incremented everytime when the index is
220 /// changed.</p>
221 ///
222 /// </summary>
223 /// <deprecated> Replaced by {@link #GetCurrentVersion(String)}
224 ///
225 /// </deprecated>
226 public static long LastModified(System.String directory)
228 return LastModified(new System.IO.FileInfo(directory));
231 /// <summary> Returns the time the index in the named directory was last modified.
232 ///
233 /// <p>Synchronization of IndexReader and IndexWriter instances is
234 /// no longer done via time stamps of the segments file since the time resolution
235 /// depends on the hardware platform. Instead, a version number is maintained
236 /// within the segments file, which is incremented everytime when the index is
237 /// changed.</p>
238 ///
239 /// </summary>
240 /// <deprecated> Replaced by {@link #GetCurrentVersion(File)}
241 ///
242 /// </deprecated>
243 public static long LastModified(System.IO.FileInfo directory)
245 return FSDirectory.FileModified(directory, "segments");
248 /// <summary> Returns the time the index in the named directory was last modified.
249 ///
250 /// <p>Synchronization of IndexReader and IndexWriter instances is
251 /// no longer done via time stamps of the segments file since the time resolution
252 /// depends on the hardware platform. Instead, a version number is maintained
253 /// within the segments file, which is incremented everytime when the index is
254 /// changed.</p>
255 ///
256 /// </summary>
257 /// <deprecated> Replaced by {@link #GetCurrentVersion(Directory)}
258 ///
259 /// </deprecated>
260 public static long LastModified(Directory directory)
262 return directory.FileModified("segments");
265 /// <summary> Reads version number from segments files. The version number counts the
266 /// number of changes of the index.
267 ///
268 /// </summary>
269 /// <param name="directory">where the index resides.
270 /// </param>
271 /// <returns> version number.
272 /// </returns>
273 /// <throws> IOException if segments file cannot be read </throws>
274 public static long GetCurrentVersion(System.String directory)
276 return GetCurrentVersion(new System.IO.FileInfo(directory));
279 /// <summary> Reads version number from segments files. The version number counts the
280 /// number of changes of the index.
281 ///
282 /// </summary>
283 /// <param name="directory">where the index resides.
284 /// </param>
285 /// <returns> version number.
286 /// </returns>
287 /// <throws> IOException if segments file cannot be read </throws>
288 public static long GetCurrentVersion(System.IO.FileInfo directory)
290 Directory dir = FSDirectory.GetDirectory(directory, false);
291 long version = GetCurrentVersion(dir);
292 dir.Close();
293 return version;
296 /// <summary> Reads version number from segments files. The version number counts the
297 /// number of changes of the index.
298 ///
299 /// </summary>
300 /// <param name="directory">where the index resides.
301 /// </param>
302 /// <returns> version number.
303 /// </returns>
304 /// <throws> IOException if segments file cannot be read. </throws>
305 public static long GetCurrentVersion(Directory directory)
307 return SegmentInfos.ReadCurrentVersion(directory);
310 /// <summary> Return an array of term frequency vectors for the specified document.
311 /// The array contains a vector for each vectorized field in the document.
312 /// Each vector contains terms and frequencies for all terms in a given vectorized field.
313 /// If no such fields existed, the method returns null. The term vectors that are
314 /// returned my either be of type TermFreqVector or of type TermPositionsVector if
315 /// positions or offsets have been stored.
316 ///
317 /// </summary>
318 /// <param name="docNumber">document for which term frequency vectors are returned
319 /// </param>
320 /// <returns> array of term frequency vectors. May be null if no term vectors have been
321 /// stored for the specified document.
322 /// </returns>
323 /// <throws> IOException if index cannot be accessed </throws>
324 /// <seealso cref="Lucene.Net.document.Field.TermVector">
325 /// </seealso>
326 abstract public TermFreqVector[] GetTermFreqVectors(int docNumber);
329 /// <summary> Return a term frequency vector for the specified document and field. The
330 /// returned vector contains terms and frequencies for the terms in
331 /// the specified field of this document, if the field had the storeTermVector
332 /// flag set. If termvectors had been stored with positions or offsets, a
333 /// TermPositionsVector is returned.
334 ///
335 /// </summary>
336 /// <param name="docNumber">document for which the term frequency vector is returned
337 /// </param>
338 /// <param name="field">field for which the term frequency vector is returned.
339 /// </param>
340 /// <returns> term frequency vector May be null if field does not exist in the specified
341 /// document or term vector was not stored.
342 /// </returns>
343 /// <throws> IOException if index cannot be accessed </throws>
344 /// <seealso cref="Lucene.Net.document.Field.TermVector">
345 /// </seealso>
346 abstract public TermFreqVector GetTermFreqVector(int docNumber, System.String field);
348 /// <summary> Returns <code>true</code> if an index exists at the specified directory.
349 /// If the directory does not exist or if there is no index in it.
350 /// <code>false</code> is returned.
351 /// </summary>
352 /// <param name="directory">the directory to check for an index
353 /// </param>
354 /// <returns> <code>true</code> if an index exists; <code>false</code> otherwise
355 /// </returns>
356 public static bool IndexExists(System.String directory)
358 bool tmpBool;
359 if (System.IO.File.Exists((new System.IO.FileInfo(System.IO.Path.Combine(directory, "segments"))).FullName))
360 tmpBool = true;
361 else
362 tmpBool = System.IO.Directory.Exists((new System.IO.FileInfo(System.IO.Path.Combine(directory, "segments"))).FullName);
363 return tmpBool;
366 /// <summary> Returns <code>true</code> if an index exists at the specified directory.
367 /// If the directory does not exist or if there is no index in it.
368 /// </summary>
369 /// <param name="directory">the directory to check for an index
370 /// </param>
371 /// <returns> <code>true</code> if an index exists; <code>false</code> otherwise
372 /// </returns>
373 public static bool IndexExists(System.IO.FileInfo directory)
375 bool tmpBool;
376 if (System.IO.File.Exists((new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, "segments"))).FullName))
377 tmpBool = true;
378 else
379 tmpBool = System.IO.Directory.Exists((new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, "segments"))).FullName);
380 return tmpBool;
383 /// <summary> Returns <code>true</code> if an index exists at the specified directory.
384 /// If the directory does not exist or if there is no index in it.
385 /// </summary>
386 /// <param name="directory">the directory to check for an index
387 /// </param>
388 /// <returns> <code>true</code> if an index exists; <code>false</code> otherwise
389 /// </returns>
390 /// <throws> IOException if there is a problem with accessing the index </throws>
391 public static bool IndexExists(Directory directory)
393 return directory.FileExists("segments");
396 /// <summary>Returns the number of documents in this index. </summary>
397 public abstract int NumDocs();
399 /// <summary>Returns one greater than the largest possible document number.
400 /// This may be used to, e.g., determine how big to allocate an array which
401 /// will have an element for every document number in an index.
402 /// </summary>
403 public abstract int MaxDoc();
405 /// <summary>Returns the stored fields of the <code>n</code><sup>th</sup>
406 /// <code>Document</code> in this index.
407 /// </summary>
408 public abstract Document Document(int n);
410 /// <summary>Returns true if document <i>n</i> has been deleted </summary>
411 public abstract bool IsDeleted(int n);
413 /// <summary>Returns true if any documents have been deleted </summary>
414 public abstract bool HasDeletions();
416 /// <summary>Returns the byte-encoded normalization factor for the named Field of
417 /// every document. This is used by the search code to score documents.
418 ///
419 /// </summary>
420 /// <seealso cref="Field#SetBoost(float)">
421 /// </seealso>
422 public abstract byte[] Norms(System.String field);
424 /// <summary>Reads the byte-encoded normalization factor for the named Field of every
425 /// document. This is used by the search code to score documents.
426 ///
427 /// </summary>
428 /// <seealso cref="Field#SetBoost(float)">
429 /// </seealso>
430 public abstract void Norms(System.String field, byte[] bytes, int offset);
432 /// <summary>Expert: Resets the normalization factor for the named Field of the named
433 /// document. The norm represents the product of the Field's {@link
434 /// Field#SetBoost(float) boost} and its {@link Similarity#LengthNorm(String,
435 /// int) length normalization}. Thus, to preserve the length normalization
436 /// values when resetting this, one should base the new value upon the old.
437 ///
438 /// </summary>
439 /// <seealso cref="#Norms(String)">
440 /// </seealso>
441 /// <seealso cref="Similarity#DecodeNorm(byte)">
442 /// </seealso>
443 public void SetNorm(int doc, System.String field, byte value_Renamed)
445 lock (this)
447 if (directoryOwner)
448 AquireWriteLock();
449 DoSetNorm(doc, field, value_Renamed);
450 hasChanges = true;
454 /// <summary>Implements setNorm in subclass.</summary>
455 protected internal abstract void DoSetNorm(int doc, System.String field, byte value_Renamed);
457 /// <summary>Expert: Resets the normalization factor for the named Field of the named
458 /// document.
459 ///
460 /// </summary>
461 /// <seealso cref="#Norms(String)">
462 /// </seealso>
463 /// <seealso cref="Similarity#DecodeNorm(byte)">
464 /// </seealso>
465 public virtual void SetNorm(int doc, System.String field, float value_Renamed)
467 SetNorm(doc, field, Similarity.EncodeNorm(value_Renamed));
471 /// <summary>Returns an enumeration of all the terms in the index.
472 /// The enumeration is ordered by Term.compareTo(). Each term
473 /// is greater than all that precede it in the enumeration.
474 /// </summary>
475 public abstract TermEnum Terms();
477 /// <summary>Returns an enumeration of all terms after a given term.
478 /// The enumeration is ordered by Term.compareTo(). Each term
479 /// is greater than all that precede it in the enumeration.
480 /// </summary>
481 public abstract TermEnum Terms(Term t);
483 /// <summary>Returns the number of documents containing the term <code>t</code>. </summary>
484 public abstract int DocFreq(Term t);
486 /// <summary>Returns an enumeration of all the documents which contain
487 /// <code>term</code>. For each document, the document number, the frequency of
488 /// the term in that document is also provided, for use in search scoring.
489 /// Thus, this method implements the mapping:
490 /// <p><ul>
491 /// Term &nbsp;&nbsp; =&gt; &nbsp;&nbsp; &lt;docNum, freq&gt;<sup>*</sup>
492 /// </ul>
493 /// <p>The enumeration is ordered by document number. Each document number
494 /// is greater than all that precede it in the enumeration.
495 /// </summary>
496 public virtual TermDocs TermDocs(Term term)
498 TermDocs termDocs = TermDocs();
499 termDocs.Seek(term);
500 return termDocs;
503 /// <summary>Returns an unpositioned {@link TermDocs} enumerator. </summary>
504 public abstract TermDocs TermDocs();
506 /// <summary>Returns an enumeration of all the documents which contain
507 /// <code>term</code>. For each document, in addition to the document number
508 /// and frequency of the term in that document, a list of all of the ordinal
509 /// positions of the term in the document is available. Thus, this method
510 /// implements the mapping:
511 /// <p><ul>
512 /// Term &nbsp;&nbsp; =&gt; &nbsp;&nbsp; &lt;docNum, freq,
513 /// &lt;pos<sub>1</sub>, pos<sub>2</sub>, ...
514 /// pos<sub>freq-1</sub>&gt;
515 /// &gt;<sup>*</sup>
516 /// </ul>
517 /// <p> This positional information faciliates phrase and proximity searching.
518 /// <p>The enumeration is ordered by document number. Each document number is
519 /// greater than all that precede it in the enumeration.
520 /// </summary>
521 public virtual TermPositions TermPositions(Term term)
523 TermPositions termPositions = TermPositions();
524 termPositions.Seek(term);
525 return termPositions;
528 /// <summary>Returns an unpositioned {@link TermPositions} enumerator. </summary>
529 public abstract TermPositions TermPositions();
531 /// <summary> Tries to acquire the WriteLock on this directory.
532 /// this method is only valid if this IndexReader is directory owner.
533 ///
534 /// </summary>
535 /// <throws> IOException If WriteLock cannot be acquired. </throws>
536 private void AquireWriteLock()
538 if (stale)
539 throw new System.IO.IOException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
541 if (this.writeLock == null)
543 Lock writeLock = directory.MakeLock(IndexWriter.WRITE_LOCK_NAME);
544 if (!writeLock.Obtain(IndexWriter.WRITE_LOCK_TIMEOUT))
545 // obtain write lock
547 throw new System.IO.IOException("Index locked for write: " + writeLock);
549 this.writeLock = writeLock;
551 // we have to check whether index has changed since this reader was opened.
552 // if so, this reader is no longer valid for deletion
553 if (SegmentInfos.ReadCurrentVersion(directory) > segmentInfos.GetVersion())
555 stale = true;
556 this.writeLock.Release();
557 this.writeLock = null;
558 throw new System.IO.IOException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
563 /// <summary>Deletes the document numbered <code>docNum</code>. Once a document is
564 /// deleted it will not appear in TermDocs or TermPostitions enumerations.
565 /// Attempts to read its Field with the {@link #document}
566 /// method will result in an error. The presence of this document may still be
567 /// reflected in the {@link #docFreq} statistic, though
568 /// this will be corrected eventually as the index is further modified.
569 /// </summary>
570 public void Delete(int docNum)
572 lock (this)
574 if (directoryOwner)
575 AquireWriteLock();
576 DoDelete(docNum);
577 hasChanges = true;
581 /// <summary>Implements deletion of the document numbered <code>docNum</code>.
582 /// Applications should call {@link #Delete(int)} or {@link #Delete(Term)}.
583 /// </summary>
584 protected internal abstract void DoDelete(int docNum);
586 /// <summary>Deletes all documents containing <code>term</code>.
587 /// This is useful if one uses a document Field to hold a unique ID string for
588 /// the document. Then to delete such a document, one merely constructs a
589 /// term with the appropriate Field and the unique ID string as its text and
590 /// passes it to this method. Returns the number of documents deleted.
591 /// See {@link #Delete(int)} for information about when this deletion will
592 /// become effective.
593 /// </summary>
594 public int Delete(Term term)
596 TermDocs docs = TermDocs(term);
597 if (docs == null)
598 return 0;
599 int n = 0;
602 while (docs.Next())
604 Delete(docs.Doc());
605 n++;
608 finally
610 docs.Close();
612 return n;
615 /// <summary>Undeletes all documents currently marked as deleted in this index.</summary>
616 public void UndeleteAll()
618 lock (this)
620 if (directoryOwner)
621 AquireWriteLock();
622 DoUndeleteAll();
623 hasChanges = true;
627 /// <summary>Implements actual undeleteAll() in subclass. </summary>
628 protected internal abstract void DoUndeleteAll();
630 /// <summary> Commit changes resulting from delete, undeleteAll, or setNorm operations
631 ///
632 /// </summary>
633 /// <throws> IOException </throws>
634 protected internal void Commit()
636 lock (this)
638 if (hasChanges)
640 if (directoryOwner)
642 lock (directory)
644 // in- & inter-process sync
645 new AnonymousClassWith1(this, directory.MakeLock(IndexWriter.COMMIT_LOCK_NAME), IndexWriter.COMMIT_LOCK_TIMEOUT).Run();
647 if (writeLock != null)
649 writeLock.Release(); // release write lock
650 writeLock = null;
653 else
654 DoCommit();
656 hasChanges = false;
660 /// <summary>Implements commit. </summary>
661 protected internal abstract void DoCommit();
663 /// <summary> Closes files associated with this index.
664 /// Also saves any new deletions to disk.
665 /// No other methods should be called after this has been called.
666 /// </summary>
667 public void Close()
669 lock (this)
671 Commit();
672 DoClose();
673 if (closeDirectory)
674 directory.Close();
675 System.GC.SuppressFinalize(this);
679 /// <summary>Implements close. </summary>
680 protected internal abstract void DoClose();
682 /// <summary>Release the write lock, if needed. </summary>
683 ~IndexReader()
685 if (writeLock != null)
687 writeLock.Release(); // release write lock
688 writeLock = null;
692 /// <summary> Returns a list of all unique field names that exist in the index pointed
693 /// to by this IndexReader.
694 /// </summary>
695 /// <returns> Collection of Strings indicating the names of the fields
696 /// </returns>
697 /// <throws> IOException if there is a problem with accessing the index </throws>
698 /// <summary>
699 /// </summary>
700 /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
701 /// </deprecated>
702 public abstract System.Collections.ICollection GetFieldNames();
704 /// <summary> Returns a list of all unique Field names that exist in the index pointed
705 /// to by this IndexReader. The boolean argument specifies whether the fields
706 /// returned are indexed or not.
707 /// </summary>
708 /// <param name="indexed"><code>true</code> if only indexed fields should be returned;
709 /// <code>false</code> if only unindexed fields should be returned.
710 /// </param>
711 /// <returns> Collection of Strings indicating the names of the fields
712 /// </returns>
713 /// <throws> IOException if there is a problem with accessing the index </throws>
714 /// <summary>
715 /// </summary>
716 /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
717 /// </deprecated>
718 public abstract System.Collections.ICollection GetFieldNames(bool indexed);
720 /// <summary> </summary>
721 /// <param name="storedTermVector">if true, returns only Indexed fields that have term vector info,
722 /// else only indexed fields without term vector info
723 /// </param>
724 /// <returns> Collection of Strings indicating the names of the fields
725 ///
726 /// </returns>
727 /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
728 /// </deprecated>
729 public virtual System.Collections.ICollection GetIndexedFieldNames(bool storedTermVector)
731 if (storedTermVector)
733 System.Collections.Hashtable fieldSet = new System.Collections.Hashtable();
734 foreach (object item in GetIndexedFieldNames(Field.TermVector.YES))
736 if (fieldSet.ContainsKey(item) == false)
738 fieldSet.Add(item, item);
741 foreach (object item in GetIndexedFieldNames(Field.TermVector.WITH_POSITIONS))
743 if (fieldSet.ContainsKey(item) == false)
745 fieldSet.Add(item, item);
748 foreach (object item in GetIndexedFieldNames(Field.TermVector.WITH_OFFSETS))
750 if (fieldSet.ContainsKey(item) == false)
752 fieldSet.Add(item, item);
755 foreach (object item in GetIndexedFieldNames(Field.TermVector.WITH_POSITIONS_OFFSETS))
757 if (fieldSet.ContainsKey(item) == false)
759 fieldSet.Add(item, item);
762 return fieldSet;
764 else
765 return GetIndexedFieldNames(Field.TermVector.NO);
768 /// <summary> Get a list of unique field names that exist in this index, are indexed, and have
769 /// the specified term vector information.
770 ///
771 /// </summary>
772 /// <param name="tvSpec">specifies which term vector information should be available for the fields
773 /// </param>
774 /// <returns> Collection of Strings indicating the names of the fields
775 ///
776 /// </returns>
777 /// <deprecated> Replaced by {@link #GetFieldNames(IndexReader.FieldOption)}
778 /// </deprecated>
779 public abstract System.Collections.ICollection GetIndexedFieldNames(Field.TermVector tvSpec);
781 /// <summary> Get a list of unique field names that exist in this index and have the specified
782 /// field option information.
783 /// </summary>
784 /// <param name="fldOption">specifies which field option should be available for the returned fields
785 /// </param>
786 /// <returns> Collection of Strings indicating the names of the fields.
787 /// </returns>
788 /// <seealso cref="IndexReader.FieldOption">
789 /// </seealso>
790 public abstract System.Collections.ICollection GetFieldNames(FieldOption fldOption);
792 /// <summary> Returns <code>true</code> iff the index in the named directory is
793 /// currently locked.
794 /// </summary>
795 /// <param name="directory">the directory to check for a lock
796 /// </param>
797 /// <throws> IOException if there is a problem with accessing the index </throws>
798 public static bool IsLocked(Directory directory)
800 return directory.MakeLock(IndexWriter.WRITE_LOCK_NAME).IsLocked() || directory.MakeLock(IndexWriter.COMMIT_LOCK_NAME).IsLocked();
803 /// <summary> Returns <code>true</code> iff the index in the named directory is
804 /// currently locked.
805 /// </summary>
806 /// <param name="directory">the directory to check for a lock
807 /// </param>
808 /// <throws> IOException if there is a problem with accessing the index </throws>
809 public static bool IsLocked(System.String directory)
811 Directory dir = FSDirectory.GetDirectory(directory, false);
812 bool result = IsLocked(dir);
813 dir.Close();
814 return result;
817 /// <summary> Forcibly unlocks the index in the named directory.
818 /// <P>
819 /// Caution: this should only be used by failure recovery code,
820 /// when it is known that no other process nor thread is in fact
821 /// currently accessing this index.
822 /// </summary>
823 public static void Unlock(Directory directory)
825 directory.MakeLock(IndexWriter.WRITE_LOCK_NAME).Release();
826 directory.MakeLock(IndexWriter.COMMIT_LOCK_NAME).Release();
829 /// <summary> Prints the filename and size of each file within a given compound file.
830 /// Add the -extract flag to extract files to the current working directory.
831 /// In order to make the extracted version of the index work, you have to copy
832 /// the segments file from the compound index into the directory where the extracted files are stored.
833 /// </summary>
834 /// <param name="">args
835 /// </param>
836 [STAThread]
837 public static void Main(System.String[] args)
839 System.String dirname = null, filename = null;
840 bool extract = false;
842 for (int i = 0; i < args.Length; ++i)
844 if (args[i].Equals("-extract"))
846 extract = true;
848 else if (dirname == null)
850 dirname = args[i];
852 else if (filename == null)
854 filename = args[i];
858 if (dirname == null || filename == null)
860 System.Console.Out.WriteLine("Usage: Lucene.Net.index.IndexReader [-extract] <directory> <cfsfile>");
861 return ;
864 Directory dir = null;
865 CompoundFileReader cfr = null;
869 dir = FSDirectory.GetDirectory(dirname, false);
871 cfr = new CompoundFileReader(dir, filename);
873 System.String[] files = cfr.List();
874 System.Array.Sort(files); // sort the array of filename so that the output is more readable
876 for (int i = 0; i < files.Length; ++i)
878 long len = cfr.FileLength(files[i]);
880 if (extract)
882 System.Console.Out.WriteLine("extract " + files[i] + " with " + len + " bytes to local directory...");
883 IndexInput ii = cfr.OpenInput(files[i]);
885 System.IO.FileStream f = new System.IO.FileStream(files[i], System.IO.FileMode.Create);
887 // read and write with a small buffer, which is more effectiv than reading byte by byte
888 byte[] buffer = new byte[1024];
889 int chunk = buffer.Length;
890 while (len > 0)
892 int bufLen = (int) System.Math.Min(chunk, len);
893 ii.ReadBytes(buffer, 0, bufLen);
895 byte[] byteArray = new byte[buffer.Length];
896 for (int index=0; index < buffer.Length; index++)
897 byteArray[index] = (byte) buffer[index];
899 f.Write(byteArray, 0, bufLen);
901 len -= bufLen;
904 f.Close();
905 ii.Close();
907 else
908 System.Console.Out.WriteLine(files[i] + ": " + len + " bytes");
911 catch (System.IO.IOException ioe)
913 System.Console.Error.WriteLine(ioe.StackTrace);
915 finally
919 if (dir != null)
920 dir.Close();
921 if (cfr != null)
922 cfr.Close();
924 catch (System.IO.IOException ioe)
926 System.Console.Error.WriteLine(ioe.StackTrace);