20 using Lucene.Net.Support;
21 using Lucene.Net.Util;
22 using Document = Lucene.Net.Documents.Document;
31 namespace Lucene.Net.Index
45 private void InitBlock()
47 fieldsReaderLocal =
new FieldsReaderLocal(
this);
49 protected internal bool readOnly;
51 private SegmentInfo si;
52 private int readBufferSize;
58 internal Ref deletedDocsRef = null;
59 private bool deletedDocsDirty =
false;
60 private bool normsDirty =
false;
61 private int pendingDeleteCount;
63 private bool rollbackHasChanges =
false;
64 private bool rollbackDeletedDocsDirty =
false;
65 private bool rollbackNormsDirty =
false;
66 private SegmentInfo rollbackSegmentInfo;
67 private int rollbackPendingDeleteCount;
71 private Ref singleNormRef;
73 internal CoreReaders core;
86 private readonly
Ref ref_Renamed =
new Ref();
88 internal System.String segment;
96 internal int readBufferSize;
97 internal int termsIndexDivisor;
110 this.readBufferSize = readBufferSize;
113 bool success =
false;
127 this.termsIndexDivisor = termsIndexDivisor;
128 var reader =
new TermInfosReader(cfsDir, segment, fieldInfos, readBufferSize, termsIndexDivisor);
129 if (termsIndexDivisor == - 1)
159 this.origInstance = origInstance;
166 return termVectorsReaderOrig;
174 return fieldsReaderOrig;
178 internal void IncRef()
182 ref_Renamed.IncRef();
209 internal bool TermsIndexIsLoaded()
222 internal void LoadTermsIndex(
SegmentInfo si,
int termsIndexDivisor)
235 if (cfsReader == null)
246 tis =
new TermInfosReader(dir0, segment, fieldInfos, readBufferSize, termsIndexDivisor);
251 internal void DecRef()
256 if (ref_Renamed.DecRef() == 0)
267 if (tisNoIndex != null)
269 tisNoIndex.Dispose();
272 if (freqStream != null)
277 if (proxStream != null)
282 if (termVectorsReaderOrig != null)
284 termVectorsReaderOrig.Dispose();
287 if (fieldsReaderOrig != null)
289 fieldsReaderOrig.Dispose();
292 if (cfsReader != null)
297 if (storeCFSReader != null)
299 storeCFSReader.Close();
303 if (origInstance != null)
305 Lucene.Net.Search.FieldCache_Fields.DEFAULT.Purge(origInstance);
316 System.Diagnostics.Debug.Assert(si.
name.Equals(segment));
318 if (fieldsReaderOrig == null)
325 System.Diagnostics.Debug.Assert(storeCFSReader == null);
327 storeDir = storeCFSReader;
328 System.Diagnostics.Debug.Assert(storeDir != null);
333 System.Diagnostics.Debug.Assert(storeDir != null);
341 if (cfsReader == null)
345 storeDir = cfsReader;
346 System.Diagnostics.Debug.Assert(storeDir != null);
351 System.Diagnostics.Debug.Assert(storeDir != null);
361 throw new CorruptIndexException(
"doc counts differ for segment " + segment +
": fieldsReader shows " + fieldsReaderOrig.Size() +
" but segmentInfo shows " + si.
docCount);
364 if (fieldInfos.HasVectors())
375 get {
return fieldInfos; }
384 InitBlock(enclosingInstance);
386 private void InitBlock(SegmentReader enclosingInstance)
388 this.enclosingInstance = enclosingInstance;
390 private SegmentReader enclosingInstance;
391 public SegmentReader Enclosing_Instance
395 return enclosingInstance;
399 public override FieldsReader InitialValue()
401 return (FieldsReader) Enclosing_Instance.core.GetFieldsReaderOrig().Clone();
407 private int refCount = 1;
409 public override System.String ToString()
411 return "refcount: " + refCount;
414 public virtual int RefCount()
422 public virtual int IncRef()
426 System.Diagnostics.Debug.Assert(refCount > 0);
432 public virtual int DecRef()
436 System.Diagnostics.Debug.Assert(refCount > 0);
451 public sealed
class Norm : System.ICloneable
455 this.enclosingInstance = enclosingInstance;
462 return enclosingInstance;
466 internal int refCount = 1;
470 private Norm origNorm;
473 private readonly
long normSeek;
476 private Ref bytesRef;
477 internal byte[] bytes;
480 internal bool rollbackDirty;
484 InitBlock(enclosingInstance);
485 this.in_Renamed = in_Renamed;
486 this.number = number;
487 this.normSeek = normSeek;
494 System.Diagnostics.Debug.Assert(refCount > 0 &&(origNorm == null || origNorm.refCount > 0));
499 private void CloseInput()
501 if (in_Renamed != null)
503 if (in_Renamed != Enclosing_Instance.singleNormStream)
506 in_Renamed.Dispose();
512 if (Enclosing_Instance.singleNormRef.DecRef() == 0)
514 Enclosing_Instance.singleNormStream.Dispose();
515 Enclosing_Instance.singleNormStream = null;
527 System.Diagnostics.Debug.Assert(refCount > 0 &&(origNorm == null || origNorm.refCount > 0));
531 if (origNorm != null)
543 System.Diagnostics.Debug.Assert(bytesRef != null);
550 System.Diagnostics.Debug.Assert(bytesRef == null);
558 public void Bytes(byte[] bytesOut,
int offset,
int len)
562 System.Diagnostics.Debug.Assert(refCount > 0 &&(origNorm == null || origNorm.refCount > 0));
566 System.Diagnostics.Debug.Assert(len <= Enclosing_Instance.MaxDoc);
567 Array.Copy(bytes, 0, bytesOut, offset, len);
572 if (origNorm != null)
575 origNorm.Bytes(bytesOut, offset, len);
582 in_Renamed.Seek(normSeek);
583 in_Renamed.ReadBytes(bytesOut, offset, len,
false);
591 public byte[] Bytes()
595 System.Diagnostics.Debug.Assert(refCount > 0 &&(origNorm == null || origNorm.refCount > 0));
599 System.Diagnostics.Debug.Assert(bytesRef == null);
600 if (origNorm != null)
605 bytes = origNorm.Bytes();
606 bytesRef = origNorm.bytesRef;
618 int count = Enclosing_Instance.MaxDoc;
619 bytes =
new byte[count];
622 System.Diagnostics.Debug.Assert(in_Renamed != null);
627 in_Renamed.Seek(normSeek);
628 in_Renamed.ReadBytes(bytes, 0, count,
false);
631 bytesRef =
new Ref();
648 public byte[] CopyOnWrite()
652 System.Diagnostics.Debug.Assert(refCount > 0 &&(origNorm == null || origNorm.refCount > 0));
654 System.Diagnostics.Debug.Assert(bytes != null);
655 System.Diagnostics.Debug.Assert(bytesRef != null);
656 if (bytesRef.RefCount() > 1)
661 System.Diagnostics.Debug.Assert(refCount == 1);
662 Ref oldRef = bytesRef;
663 bytes = Enclosing_Instance.CloneNormBytes(bytes);
664 bytesRef =
new Ref();
674 public System.Object Clone()
678 System.Diagnostics.Debug.Assert(refCount > 0 && (origNorm == null || origNorm.refCount > 0));
683 clone = (
Norm)base.MemberwiseClone();
685 catch (System.Exception cnse)
688 throw new System.SystemException(
"unexpected CloneNotSupportedException", cnse);
694 System.Diagnostics.Debug.Assert(bytesRef != null);
695 System.Diagnostics.Debug.Assert(origNorm == null);
702 System.Diagnostics.Debug.Assert(bytesRef == null);
703 if (origNorm == null)
706 clone.origNorm =
this;
712 clone.in_Renamed = null;
722 System.Diagnostics.Debug.Assert(refCount > 0 && (origNorm == null || origNorm.refCount > 0),
"refCount=" + refCount +
" origNorm=" + origNorm);
725 si.AdvanceNormGen(this.number);
728 bool success =
false;
732 @out.WriteBytes(bytes, enclosingInstance.
MaxDoc);
744 enclosingInstance.
Directory().DeleteFile(normFileName);
757 internal System.Collections.Generic.IDictionary<string, Norm> norms =
new HashMap<string, Norm>();
771 instance.readOnly = readOnly;
773 instance.readBufferSize = readBufferSize;
775 bool success =
false;
779 instance.core =
new CoreReaders(instance, dir, si, readBufferSize, termInfosIndexDivisor);
782 instance.core.OpenDocStores(si);
784 instance.LoadDeletedDocs();
785 instance.OpenNorms(instance.core.cfsDir, readBufferSize);
804 internal virtual void OpenDocStores()
806 core.OpenDocStores(si);
809 private bool CheckDeletedCounts()
811 int recomputedCount = deletedDocs.GetRecomputedCount();
813 System.Diagnostics.Debug.Assert(deletedDocs.Count() == recomputedCount,
"deleted count=" + deletedDocs.Count() +
" vs recomputed count=" + recomputedCount);
815 System.Diagnostics.Debug.Assert(si.GetDelCount() == recomputedCount,
"delete count mismatch: info=" + si.GetDelCount() +
" vs BitVector=" + recomputedCount);
819 System.Diagnostics.Debug.Assert(si.GetDelCount() <= MaxDoc,
"delete count mismatch: " + recomputedCount +
") exceeds max doc (" + MaxDoc +
") for segment " + si.name);
824 private void LoadDeletedDocs()
828 if (si.HasDeletions())
831 deletedDocsRef =
new Ref();
833 System.Diagnostics.Debug.Assert(CheckDeletedCounts());
836 System.Diagnostics.Debug.Assert(si.GetDelCount() == 0);
844 protected internal virtual byte[] CloneNormBytes(byte[] bytes)
846 var cloneBytes =
new byte[bytes.Length];
847 Array.Copy(bytes, 0, cloneBytes, 0, bytes.Length);
861 public override System.Object Clone()
867 return Clone(readOnly);
869 catch (System.Exception ex)
871 throw new System.SystemException(ex.Message, ex);
880 return ReopenSegment(si,
true, openReadOnly);
889 bool normsUpToDate =
true;
891 bool[] fieldNormsChanged =
new bool[core.fieldInfos.Size()];
892 int fieldCount = core.fieldInfos.Size();
893 for (
int i = 0; i < fieldCount; i++)
897 normsUpToDate =
false;
898 fieldNormsChanged[i] =
true;
904 if (normsUpToDate && deletionsUpToDate && !doClone && openReadOnly && readOnly)
911 System.Diagnostics.Debug.Assert(!doClone ||(normsUpToDate && deletionsUpToDate));
914 SegmentReader clone = openReadOnly ?
new ReadOnlySegmentReader() : new SegmentReader();
916 bool success =
false;
921 clone.readOnly = openReadOnly;
923 clone.readBufferSize = readBufferSize;
925 if (!openReadOnly && hasChanges)
928 clone.pendingDeleteCount = pendingDeleteCount;
929 clone.deletedDocsDirty = deletedDocsDirty;
930 clone.normsDirty = normsDirty;
931 clone.hasChanges = hasChanges;
937 if (deletedDocs != null)
939 deletedDocsRef.IncRef();
940 clone.deletedDocs = deletedDocs;
941 clone.deletedDocsRef = deletedDocsRef;
946 if (!deletionsUpToDate)
949 System.Diagnostics.Debug.Assert(clone.deletedDocs == null);
950 clone.LoadDeletedDocs();
952 else if (deletedDocs != null)
954 deletedDocsRef.IncRef();
955 clone.deletedDocs = deletedDocs;
956 clone.deletedDocsRef = deletedDocsRef;
960 clone.norms =
new HashMap<string, Norm>();
963 for (
int i = 0; i < fieldNormsChanged.Length; i++)
967 if (doClone || !fieldNormsChanged[i])
969 System.String curField = core.fieldInfos.FieldInfo(i).name;
970 Norm norm = this.norms[curField];
972 clone.norms[curField] = (Norm)norm.
Clone();
996 protected internal override void DoCommit(System.Collections.Generic.IDictionary<
string,
string> commitUserData)
1001 bool success =
false;
1004 CommitChanges(commitUserData);
1017 private void CommitChanges(System.Collections.Generic.IDictionary<
string,
string> commitUserData)
1019 if (deletedDocsDirty)
1027 bool success =
false;
1030 deletedDocs.Write(
Directory(), delFileName);
1049 si.SetDelCount(si.
GetDelCount() + pendingDeleteCount);
1050 pendingDeleteCount = 0;
1051 System.Diagnostics.Debug.Assert(deletedDocs.Count() == si.
GetDelCount(),
"delete count mismatch during commit: info=" + si.
GetDelCount() +
" vs BitVector=" + deletedDocs.Count());
1055 System.Diagnostics.Debug.Assert(pendingDeleteCount == 0);
1060 si.SetNumFields(core.fieldInfos.Size());
1061 foreach (Norm norm
in norms.Values)
1069 deletedDocsDirty =
false;
1074 internal virtual FieldsReader GetFieldsReader()
1076 return fieldsReaderLocal.Get();
1079 protected internal override void DoClose()
1081 termVectorsLocal.Close();
1082 fieldsReaderLocal.Close();
1084 if (deletedDocs != null)
1086 deletedDocsRef.DecRef();
1091 foreach(Norm norm
in norms.Values)
1107 public override bool HasDeletions
1112 return deletedDocs != null;
1116 internal static bool UsesCompoundFile(
SegmentInfo si)
1121 internal static bool HasSeparateNorms(SegmentInfo si)
1123 return si.HasSeparateNorms();
1126 protected internal override void DoDelete(
int docNum)
1128 if (deletedDocs == null)
1131 deletedDocsRef =
new Ref();
1136 if (deletedDocsRef.RefCount() > 1)
1138 Ref oldRef = deletedDocsRef;
1139 deletedDocs = CloneDeletedDocs(deletedDocs);
1140 deletedDocsRef =
new Ref();
1143 deletedDocsDirty =
true;
1144 if (!deletedDocs.GetAndSet(docNum))
1145 pendingDeleteCount++;
1148 protected internal override void DoUndeleteAll()
1150 deletedDocsDirty =
false;
1151 if (deletedDocs != null)
1153 System.Diagnostics.Debug.Assert(deletedDocsRef != null);
1154 deletedDocsRef.DecRef();
1156 deletedDocsRef = null;
1157 pendingDeleteCount = 0;
1163 System.Diagnostics.Debug.Assert(deletedDocsRef == null);
1164 System.Diagnostics.Debug.Assert(pendingDeleteCount == 0);
1168 internal virtual System.Collections.Generic.IList<
string> Files()
1176 return core.GetTermsReader().Terms();
1182 return core.GetTermsReader().Terms(t);
1187 return core.fieldInfos;
1193 return GetFieldsReader().Doc(n, fieldSelector);
1196 public override bool IsDeleted(
int n)
1200 return (deletedDocs != null && deletedDocs.Get(n));
1212 return base.TermDocs(term);
1219 return new SegmentTermDocs(
this);
1225 return new SegmentTermPositions(
this);
1228 public override int DocFreq(
Term t)
1231 TermInfo ti = core.GetTermsReader().Get(t);
1238 public override int NumDocs()
1242 if (deletedDocs != null)
1243 n -= deletedDocs.Count();
1247 public override int MaxDoc
1258 public override System.Collections.Generic.ICollection<
string> GetFieldNames(
IndexReader.FieldOption fieldOption)
1262 System.Collections.Generic.ISet<
string> fieldSet = Lucene.Net.Support.Compatibility.SetFactory.CreateHashSet<
string>();
1263 for (
int i = 0; i < core.fieldInfos.Size(); i++)
1265 FieldInfo fi = core.fieldInfos.FieldInfo(i);
1268 fieldSet.Add(fi.name);
1270 else if (!fi.isIndexed && fieldOption ==
IndexReader.FieldOption.UNINDEXED)
1272 fieldSet.Add(fi.name);
1274 else if (fi.omitTermFreqAndPositions && fieldOption ==
IndexReader.FieldOption.OMIT_TERM_FREQ_AND_POSITIONS)
1276 fieldSet.Add(fi.name);
1278 else if (fi.storePayloads && fieldOption ==
IndexReader.FieldOption.STORES_PAYLOADS)
1280 fieldSet.Add(fi.name);
1282 else if (fi.isIndexed && fieldOption ==
IndexReader.FieldOption.INDEXED)
1284 fieldSet.Add(fi.name);
1286 else if (fi.isIndexed && fi.storeTermVector ==
false && fieldOption ==
IndexReader.FieldOption.INDEXED_NO_TERMVECTOR)
1288 fieldSet.Add(fi.name);
1290 else if (fi.storeTermVector ==
true && fi.storePositionWithTermVector ==
false && fi.storeOffsetWithTermVector ==
false && fieldOption ==
IndexReader.FieldOption.TERMVECTOR)
1292 fieldSet.Add(fi.name);
1294 else if (fi.isIndexed && fi.storeTermVector && fieldOption ==
IndexReader.FieldOption.INDEXED_WITH_TERMVECTOR)
1296 fieldSet.Add(fi.name);
1298 else if (fi.storePositionWithTermVector && fi.storeOffsetWithTermVector ==
false && fieldOption ==
IndexReader.FieldOption.TERMVECTOR_WITH_POSITION)
1300 fieldSet.Add(fi.name);
1302 else if (fi.storeOffsetWithTermVector && fi.storePositionWithTermVector ==
false && fieldOption ==
IndexReader.FieldOption.TERMVECTOR_WITH_OFFSET)
1304 fieldSet.Add(fi.name);
1306 else if ((fi.storeOffsetWithTermVector && fi.storePositionWithTermVector) && fieldOption ==
IndexReader.FieldOption.TERMVECTOR_WITH_POSITION_OFFSET)
1308 fieldSet.Add(fi.name);
1315 public override bool HasNorms(System.String field)
1320 return norms.ContainsKey(field);
1325 protected internal virtual byte[] GetNorms(System.String field)
1329 Norm norm = norms[field];
1332 return norm.Bytes();
1337 public override byte[] Norms(System.String field)
1342 byte[] bytes = GetNorms(field);
1347 protected internal override void DoSetNorm(
int doc, System.String field, byte value_Renamed)
1349 Norm norm = norms[field];
1355 norm.CopyOnWrite()[doc] = value_Renamed;
1359 public override void Norms(System.String field, byte[] bytes,
int offset)
1365 Norm norm = norms[field];
1368 for (
int i = offset; i < bytes.Length; i++)
1375 norm.
Bytes(bytes, offset, MaxDoc);
1380 private void OpenNorms(
Directory cfsDir,
int readBufferSize)
1383 int maxDoc = MaxDoc;
1384 for (
int i = 0; i < core.fieldInfos.Size(); i++)
1386 FieldInfo fi = core.fieldInfos.FieldInfo(i);
1387 if (norms.ContainsKey(fi.name))
1393 if (fi.isIndexed && !fi.omitNorms)
1396 System.String fileName = si.GetNormFileName(fi.number);
1397 if (!si.HasSeparateNorms(fi.number))
1403 bool singleNormFile = fileName.EndsWith(
"." + IndexFileNames.NORMS_EXTENSION);
1409 normSeek = nextNormSeek;
1410 if (singleNormStream == null)
1412 singleNormStream = d.OpenInput(fileName, readBufferSize);
1413 singleNormRef =
new Ref();
1417 singleNormRef.IncRef();
1422 normInput = singleNormStream;
1427 normInput = d.OpenInput(fileName);
1430 norms[fi.name] =
new Norm(
this, normInput, fi.number, normSeek);
1431 nextNormSeek += maxDoc;
1436 public virtual bool TermsIndexLoaded()
1438 return core.TermsIndexIsLoaded();
1446 internal virtual void LoadTermsIndex(
int termsIndexDivisor)
1448 core.LoadTermsIndex(si, termsIndexDivisor);
1452 public virtual bool NormsClosed()
1454 if (singleNormStream != null)
1458 return norms.Values.All(norm => norm.refCount <= 0);
1462 public virtual bool NormsClosed(System.String field)
1464 return norms[field].refCount == 0;
1473 if (tvReader == null)
1484 tvReader = (TermVectorsReader) orig.
Clone();
1486 catch (System.Exception)
1491 termVectorsLocal.Set(tvReader);
1496 internal virtual TermVectorsReader GetTermVectorsReaderOrig()
1498 return core.GetTermVectorsReaderOrig();
1511 FieldInfo fi = core.fieldInfos.FieldInfo(field);
1512 if (fi == null || !fi.storeTermVector)
1516 if (termVectorsReader == null)
1519 return termVectorsReader.
Get(docNumber, field);
1523 public override void GetTermFreqVector(
int docNumber, System.String field,
TermVectorMapper mapper)
1526 FieldInfo fi = core.fieldInfos.FieldInfo(field);
1527 if (fi == null || !fi.storeTermVector)
1531 if (termVectorsReader == null)
1535 termVectorsReader.
Get(docNumber, field, mapper);
1544 if (termVectorsReader == null)
1547 termVectorsReader.
Get(docNumber, mapper);
1562 if (termVectorsReader == null)
1565 return termVectorsReader.
Get(docNumber);
1569 public virtual string SegmentName
1571 get {
return core.segment; }
1581 internal virtual void StartCommit()
1583 rollbackSegmentInfo = (SegmentInfo)si.
Clone();
1584 rollbackHasChanges = hasChanges;
1585 rollbackDeletedDocsDirty = deletedDocsDirty;
1586 rollbackNormsDirty = normsDirty;
1587 rollbackPendingDeleteCount = pendingDeleteCount;
1588 foreach(Norm norm
in norms.Values)
1590 norm.rollbackDirty = norm.dirty;
1594 internal virtual void RollbackCommit()
1596 si.Reset(rollbackSegmentInfo);
1597 hasChanges = rollbackHasChanges;
1598 deletedDocsDirty = rollbackDeletedDocsDirty;
1599 normsDirty = rollbackNormsDirty;
1600 pendingDeleteCount = rollbackPendingDeleteCount;
1601 foreach(Norm norm
in norms.Values)
1603 norm.dirty = norm.rollbackDirty;
1620 public override object FieldCacheKey
1622 get {
return core.freqStream; }
1625 public override object DeletesCacheKey
1627 get {
return deletedDocs; }
1631 public override long UniqueTermCount
1633 get {
return core.GetTermsReader().Size(); }
1641 [Obsolete(
"Remove this when tests are fixed!")]
1650 if (onlySegmentReader != null)
1651 return onlySegmentReader;
1656 if (subReaders.Length != 1)
1658 throw new System.ArgumentException(reader +
" has " + subReaders.Length +
" segments instead of exactly one");
1661 return (SegmentReader) subReaders[0];
1664 throw new System.ArgumentException(reader +
" is not a SegmentReader or a single-segment DirectoryReader");
1667 public override int TermInfosIndexDivisor
1669 get {
return core.termsIndexDivisor; }
1672 public System.Collections.Generic.IDictionary<string, Norm> norms_ForNUnit
1674 get {
return norms; }
1679 get {
return deletedDocs; }
1682 public CoreReaders core_ForNUnit
1684 get {
return core; }
1687 public Ref deletedDocsRef_ForNUnit
1689 get {
return deletedDocsRef; }