19 using System.Collections.Generic;
21 using Lucene.Net.Support;
22 using Document = Lucene.Net.Documents.Document;
26 namespace Lucene.Net.Index
47 private List<IndexReader> readers =
new List<IndexReader>();
48 private List<bool> decrefOnClose =
new List<bool>();
49 internal bool incRefReaders =
false;
50 private SortedDictionary<string, IndexReader> fieldToReader =
new SortedDictionary<string, IndexReader>();
51 private IDictionary<IndexReader, ICollection<string>> readerToFields =
new HashMap<IndexReader, ICollection<string>>();
52 private List<IndexReader> storedFieldReaders =
new List<IndexReader>();
56 private bool hasDeletions;
71 this.incRefReaders = !closeSubReaders;
94 public virtual void Add(
IndexReader reader,
bool ignoreStoredFields)
98 if (readers.Count == 0)
100 this.maxDoc = reader.
MaxDoc;
101 this.numDocs = reader.
NumDocs();
105 if (reader.
MaxDoc != maxDoc)
107 throw new System.ArgumentException(
"All readers must have same maxDoc: " + maxDoc +
"!=" + reader.
MaxDoc);
108 if (reader.
NumDocs() != numDocs)
109 throw new System.ArgumentException(
"All readers must have same numDocs: " + numDocs +
"!=" + reader.
NumDocs());
112 readerToFields[reader] = fields;
113 foreach(var field
in fields)
117 if (!fieldToReader.ContainsKey(field) || fieldToReader[field] == null)
118 fieldToReader[field] = reader;
121 if (!ignoreStoredFields)
122 storedFieldReaders.Add(reader);
129 decrefOnClose.Add(incRefReaders);
132 public override System.Object Clone()
136 return DoReopen(
true);
138 catch (System.Exception ex)
140 throw new System.SystemException(ex.Message, ex);
166 return DoReopen(
false);
170 protected internal virtual IndexReader DoReopen(
bool doClone)
174 bool reopened =
false;
175 IList<IndexReader> newReaders =
new List<IndexReader>();
177 bool success =
false;
181 foreach(var oldReader
in readers)
190 newReader = oldReader.
Reopen();
192 newReaders.Add(newReader);
195 if (newReader != oldReader)
204 if (!success && reopened)
206 for (
int i = 0; i < newReaders.Count; i++)
215 catch (System.IO.IOException)
226 List<bool> newDecrefOnClose =
new List<bool>();
227 ParallelReader pr =
new ParallelReader();
228 for (
int i = 0; i < readers.Count; i++)
232 if (newReader == oldReader)
234 newDecrefOnClose.Add(
true);
241 newDecrefOnClose.Add(
false);
243 pr.Add(newReader, !storedFieldReaders.Contains(oldReader));
245 pr.decrefOnClose = newDecrefOnClose;
246 pr.incRefReaders = incRefReaders;
257 public override int NumDocs()
263 public override int MaxDoc
272 public override bool HasDeletions
282 public override bool IsDeleted(
int n)
285 if (readers.Count > 0)
286 return readers[0].IsDeleted(n);
291 protected internal override void DoDelete(
int n)
293 foreach(var reader
in readers)
295 reader.DeleteDocument(n);
301 protected internal override void DoUndeleteAll()
303 foreach(var reader
in readers)
305 reader.UndeleteAll();
307 hasDeletions =
false;
317 bool include = (fieldSelector == null);
320 var fields = readerToFields[reader];
321 foreach(var field
in fields)
332 var fields = reader.
Document(n, fieldSelector).GetFields();
333 foreach(var field
in fields)
346 IList<ITermFreqVector> results =
new List<ITermFreqVector>();
347 foreach(var e
in fieldToReader)
349 System.String field = e.Key;
356 return results.ToArray();
367 public override void GetTermFreqVector(
int docNumber, System.String field,
TermVectorMapper mapper)
381 foreach(var e
in fieldToReader)
383 System.String field = e.Key;
389 public override bool HasNorms(System.String field)
393 return reader != null && reader.
HasNorms(field);
396 public override byte[] Norms(System.String field)
400 return reader == null?null:reader.
Norms(field);
403 public override void Norms(System.String field, byte[] result,
int offset)
408 reader.
Norms(field, result, offset);
411 protected internal override void DoSetNorm(
int n, System.String field, byte value_Renamed)
415 reader.DoSetNorm(n, field, value_Renamed);
421 return new ParallelTermEnum(
this);
427 return new ParallelTermEnum(
this, term);
430 public override int DocFreq(
Term term)
434 return reader == null?0:reader.
DocFreq(term);
440 return new ParallelTermDocs(
this, term);
446 return new ParallelTermDocs(
this);
452 return new ParallelTermPositions(
this, term);
458 return new ParallelTermPositions(
this);
462 public override bool IsCurrent()
464 foreach (var reader
in readers)
466 if (!reader.IsCurrent())
477 public override bool IsOptimized()
479 foreach (var reader
in readers)
481 if (!reader.IsOptimized())
496 get {
throw new System.NotSupportedException(
"ParallelReader does not support this method."); }
502 return readers.ToArray();
505 protected internal override void DoCommit(IDictionary<string, string> commitUserData)
507 foreach(var reader
in readers)
508 reader.
Commit(commitUserData);
511 protected internal override void DoClose()
515 for (
int i = 0; i < readers.Count; i++)
517 if (decrefOnClose[i])
528 Lucene.Net.Search.FieldCache_Fields.DEFAULT.Purge(
this);
531 public override System.Collections.Generic.ICollection<
string> GetFieldNames(
IndexReader.FieldOption fieldNames)
534 ISet<string> fieldSet = Lucene.Net.Support.Compatibility.SetFactory.CreateHashSet<
string>();
535 foreach(var reader
in readers)
537 ICollection<string> names = reader.GetFieldNames(fieldNames);
538 fieldSet.UnionWith(names);
543 private class ParallelTermEnum :
TermEnum
547 this.enclosingInstance = enclosingInstance;
549 private ParallelReader enclosingInstance;
550 public ParallelReader Enclosing_Instance
554 return enclosingInstance;
558 private System.String field;
559 private IEnumerator<string> fieldIterator;
562 private bool isDisposed;
564 public ParallelTermEnum(ParallelReader enclosingInstance)
566 InitBlock(enclosingInstance);
569 field = Enclosing_Instance.fieldToReader.Keys.First();
571 catch (ArgumentOutOfRangeException)
577 termEnum = Enclosing_Instance.fieldToReader[field].Terms();
580 public ParallelTermEnum(ParallelReader enclosingInstance,
Term term)
582 InitBlock(enclosingInstance);
584 IndexReader reader = Enclosing_Instance.fieldToReader[field];
586 termEnum = reader.Terms(term);
589 public override bool Next()
591 if (termEnum == null)
595 if (termEnum.Next() && (System.Object) termEnum.Term.Field == (System.Object) field)
601 if (fieldIterator == null)
603 var newList =
new List<string>();
604 if (Enclosing_Instance.fieldToReader != null && Enclosing_Instance.fieldToReader.Count > 0)
606 var comparer = Enclosing_Instance.fieldToReader.Comparer;
607 foreach(var entry
in Enclosing_Instance.fieldToReader.Keys.Where(x => comparer.Compare(x, field) >= 0))
611 fieldIterator = newList.Skip(1).GetEnumerator();
613 while (fieldIterator.MoveNext())
615 field = fieldIterator.Current;
616 termEnum = Enclosing_Instance.fieldToReader[field].Terms(
new Term(field));
617 Term term = termEnum.Term;
618 if (term != null && (System.Object) term.Field == (System.Object) field)
631 if (termEnum == null)
634 return termEnum.Term;
638 public override int DocFreq()
640 if (termEnum == null)
643 return termEnum.DocFreq();
646 protected override void Dispose(
bool disposing)
648 if (isDisposed)
return;
652 if (termEnum != null)
661 private class ParallelTermDocs :
TermDocs
663 private void InitBlock(ParallelReader enclosingInstance)
665 this.enclosingInstance = enclosingInstance;
667 private ParallelReader enclosingInstance;
668 public ParallelReader Enclosing_Instance
672 return enclosingInstance;
676 protected internal TermDocs termDocs;
678 private bool isDisposed;
680 public ParallelTermDocs(ParallelReader enclosingInstance)
682 InitBlock(enclosingInstance);
684 public ParallelTermDocs(ParallelReader enclosingInstance,
Term term)
686 InitBlock(enclosingInstance);
688 termDocs = (Enclosing_Instance.readers.Count == 0)
690 : Enclosing_Instance.readers[0].TermDocs(null);
695 public virtual int Doc
697 get {
return termDocs.Doc; }
700 public virtual int Freq
702 get {
return termDocs.Freq; }
705 public virtual void Seek(
Term term)
707 IndexReader reader = Enclosing_Instance.fieldToReader[term.Field];
708 termDocs = reader != null?reader.TermDocs(term):null;
711 public virtual void Seek(
TermEnum termEnum)
716 public virtual bool Next()
718 if (termDocs == null)
721 return termDocs.Next();
724 public virtual int Read(
int[] docs,
int[] freqs)
726 if (termDocs == null)
729 return termDocs.Read(docs, freqs);
732 public virtual bool SkipTo(
int target)
734 if (termDocs == null)
737 return termDocs.SkipTo(target);
740 [Obsolete(
"Use Dispose() instead")]
741 public virtual void Close()
746 public void Dispose()
751 protected virtual void Dispose(
bool disposing)
753 if (isDisposed)
return;
757 if (termDocs != null)
765 private class ParallelTermPositions:ParallelTermDocs,
TermPositions
767 private void InitBlock(ParallelReader enclosingInstance)
769 this.enclosingInstance = enclosingInstance;
771 private ParallelReader enclosingInstance;
772 public new ParallelReader Enclosing_Instance
776 return enclosingInstance;
781 public ParallelTermPositions(ParallelReader enclosingInstance):base(enclosingInstance)
783 InitBlock(enclosingInstance);
785 public ParallelTermPositions(ParallelReader enclosingInstance,
Term term):base(enclosingInstance)
787 InitBlock(enclosingInstance);
791 public override void Seek(
Term term)
793 IndexReader reader = Enclosing_Instance.fieldToReader[term.Field];
794 termDocs = reader != null?reader.TermPositions(term):null;
797 public virtual int NextPosition()
803 public virtual int PayloadLength
808 public virtual byte[] GetPayload(byte[] data,
int offset)
816 public virtual bool IsPayloadAvailable
818 get {
return ((
TermPositions) termDocs).IsPayloadAvailable; }