/// <summary> /// Expert: create a ParallelAtomicReader based on the provided /// readers and storedFieldReaders; when a document is /// loaded, only storedFieldsReaders will be used. /// </summary> public ParallelAtomicReader(bool closeSubReaders, AtomicReader[] readers, AtomicReader[] storedFieldsReaders) { if (!InstanceFieldsInitialized) { InitializeInstanceFields(); InstanceFieldsInitialized = true; } this.CloseSubReaders = closeSubReaders; if (readers.Length == 0 && storedFieldsReaders.Length > 0) { throw new System.ArgumentException("There must be at least one main reader if storedFieldsReaders are used."); } this.ParallelReaders = (AtomicReader[])readers.Clone(); this.StoredFieldsReaders = (AtomicReader[])storedFieldsReaders.Clone(); if (ParallelReaders.Length > 0) { AtomicReader first = ParallelReaders[0]; this.maxDoc = first.MaxDoc; this.numDocs = first.NumDocs; this.hasDeletions = first.HasDeletions; } else { this.maxDoc = this.numDocs = 0; this.hasDeletions = false; } CollectionsHelper.AddAll(CompleteReaderSet, this.ParallelReaders); CollectionsHelper.AddAll(CompleteReaderSet, this.StoredFieldsReaders); // check compatibility: foreach (AtomicReader reader in CompleteReaderSet) { if (reader.MaxDoc != maxDoc) { throw new System.ArgumentException("All readers must have same maxDoc: " + maxDoc + "!=" + reader.MaxDoc); } } // TODO: make this read-only in a cleaner way? FieldInfos.Builder builder = new FieldInfos.Builder(); // build FieldInfos and fieldToReader map: foreach (AtomicReader reader in this.ParallelReaders) { FieldInfos readerFieldInfos = reader.FieldInfos; foreach (FieldInfo fieldInfo in readerFieldInfos) { // NOTE: first reader having a given field "wins": if (!FieldToReader.ContainsKey(fieldInfo.Name)) { builder.Add(fieldInfo); FieldToReader[fieldInfo.Name] = reader; if (fieldInfo.HasVectors()) { TvFieldToReader[fieldInfo.Name] = reader; } } } } FieldInfos_Renamed = builder.Finish(); // build Fields instance foreach (AtomicReader reader in this.ParallelReaders) { Fields readerFields = reader.Fields; if (readerFields != null) { foreach (string field in readerFields) { // only add if the reader responsible for that field name is the current: if (FieldToReader[field].Equals(reader)) { this.Fields_Renamed.AddField(field, readerFields.Terms(field)); } } } } // do this finally so any Exceptions occurred before don't affect refcounts: foreach (AtomicReader reader in CompleteReaderSet) { if (!closeSubReaders) { reader.IncRef(); } reader.RegisterParentReader(this); } }