⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 segmentreader.cs

📁 Lucene.Net 版本源码 测试通过
💻 CS
📖 第 1 页 / 共 2 页
字号:
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using Document = Lucene.Net.Documents.Document;
using FieldSelector = Lucene.Net.Documents.FieldSelector;
using DefaultSimilarity = Lucene.Net.Search.DefaultSimilarity;
using Directory = Lucene.Net.Store.Directory;
using IndexInput = Lucene.Net.Store.IndexInput;
using IndexOutput = Lucene.Net.Store.IndexOutput;
using BitVector = Lucene.Net.Util.BitVector;

namespace Lucene.Net.Index
{
	
	/// <version>  $Id: SegmentReader.java 496851 2007-01-16 20:24:52Z mikemccand $
	/// </version>
	public class SegmentReader : IndexReader
	{
		private System.String segment;
		private SegmentInfo si;
		
		internal FieldInfos fieldInfos;
		private FieldsReader fieldsReader;
		
		internal TermInfosReader tis;
		internal TermVectorsReader termVectorsReaderOrig = null;
		internal System.LocalDataStoreSlot termVectorsLocal = System.Threading.Thread.AllocateDataSlot();
		
		internal BitVector deletedDocs = null;
		private bool deletedDocsDirty = false;
		private bool normsDirty = false;
		private bool undeleteAll = false;
		
		private bool rollbackDeletedDocsDirty = false;
		private bool rollbackNormsDirty = false;
		private bool rollbackUndeleteAll = false;
		
		internal IndexInput freqStream;
		internal IndexInput proxStream;
		
		// Compound File Reader when based on a compound file segment
		internal CompoundFileReader cfsReader = null;
		
		public FieldInfos FieldInfos
		{
			get {   return fieldInfos;  }
		}

		private class Norm
		{
			private void  InitBlock(SegmentReader enclosingInstance)
			{
				this.enclosingInstance = enclosingInstance;
			}
			private SegmentReader enclosingInstance;
			public SegmentReader Enclosing_Instance
			{
				get
				{
					return enclosingInstance;
				}
				
			}
			public Norm(SegmentReader enclosingInstance, IndexInput in_Renamed, int number, long normSeek)
			{
				InitBlock(enclosingInstance);
				this.in_Renamed = in_Renamed;
				this.number = number;
				this.normSeek = normSeek;
			}
			
			internal IndexInput in_Renamed;
			internal byte[] bytes;
			internal bool dirty;
			internal int number;
			internal long normSeek;
			internal bool rollbackDirty;
			
			internal void  ReWrite(SegmentInfo si)
			{
				// NOTE: norms are re-written in regular directory, not cfs
				
				System.String oldFileName = si.GetNormFileName(this.number);
				if (oldFileName != null && !oldFileName.EndsWith("." + IndexFileNames.NORMS_EXTENSION))
				{
					// Mark this file for deletion.  Note that we don't
					// actually try to delete it until the new segments files is
					// successfully written:
					Enclosing_Instance.deleter.AddPendingFile(oldFileName);
				}
				
				si.AdvanceNormGen(this.number);
				IndexOutput out_Renamed = Enclosing_Instance.Directory().CreateOutput(si.GetNormFileName(this.number));
				try
				{
					out_Renamed.WriteBytes(bytes, Enclosing_Instance.MaxDoc());
				}
				finally
				{
					out_Renamed.Close();
				}
				this.dirty = false;
			}
		}
		
		private System.Collections.Hashtable norms = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable());
		
		/// <summary>The class which implements SegmentReader. </summary>
		private static System.Type IMPL;
		
		public SegmentReader() : base(null)
		{
		}
		
		public static SegmentReader Get(SegmentInfo si)
		{
			return Get(si.dir, si, null, false, false);
		}
		
		public static SegmentReader Get(SegmentInfos sis, SegmentInfo si, bool closeDir)
		{
			return Get(si.dir, si, sis, closeDir, true);
		}
		
		public static SegmentReader Get(Directory dir, SegmentInfo si, SegmentInfos sis, bool closeDir, bool ownDir)
		{
			SegmentReader instance;
			try
			{
				instance = (SegmentReader) System.Activator.CreateInstance(IMPL);
			}
			catch (System.Exception e)
			{
				throw new System.SystemException("cannot load SegmentReader class: " + e, e);
			}
			instance.Init(dir, sis, closeDir, ownDir);
			instance.Initialize(si);
			return instance;
		}
		
		private void  Initialize(SegmentInfo si)
		{
			segment = si.name;
			this.si = si;
			
			bool success = false;
			
			try
			{
				// Use compound file directory for some files, if it exists
				Directory cfsDir = Directory();
				if (si.GetUseCompoundFile())
				{
					cfsReader = new CompoundFileReader(Directory(), segment + ".cfs");
					cfsDir = cfsReader;
				}
				
				// No compound file exists - use the multi-file format
				fieldInfos = new FieldInfos(cfsDir, segment + ".fnm");
				fieldsReader = new FieldsReader(cfsDir, segment, fieldInfos);
				
				// Verify two sources of "maxDoc" agree:
				if (fieldsReader.Size() != si.docCount)
				{
					throw new System.SystemException("doc counts differ for segment " + si.name + ": fieldsReader shows " + fieldsReader.Size() + " but segmentInfo shows " + si.docCount);
				}
				
				tis = new TermInfosReader(cfsDir, segment, fieldInfos);
				
				// NOTE: the bitvector is stored using the regular directory, not cfs
				if (HasDeletions(si))
				{
					deletedDocs = new BitVector(Directory(), si.GetDelFileName());
					
					// Verify # deletes does not exceed maxDoc for this segment:
					if (deletedDocs.Count() > MaxDoc())
					{
						throw new System.SystemException("number of deletes (" + deletedDocs.Count() + ") exceeds max doc (" + MaxDoc() + ") for segment " + si.name);
					}
				}
				
				// make sure that all index files have been read or are kept open
				// so that if an index update removes them we'll still have them
				freqStream = cfsDir.OpenInput(segment + ".frq");
				proxStream = cfsDir.OpenInput(segment + ".prx");
				OpenNorms(cfsDir);
				
				if (fieldInfos.HasVectors())
				{
					// open term vector files only as needed
					termVectorsReaderOrig = new TermVectorsReader(cfsDir, segment, fieldInfos);
				}
				success = true;
			}
			finally
			{
				
				// With lock-less commits, it's entirely possible (and
				// fine) to hit a FileNotFound exception above.  In
				// this case, we want to explicitly close any subset
				// of things that were opened so that we don't have to
				// wait for a GC to do so.
				if (!success)
				{
					DoClose();
				}
			}
		}
		
		protected internal override void  DoCommit()
		{
			if (deletedDocsDirty)
			{
				// re-write deleted
				System.String oldDelFileName = si.GetDelFileName();
				if (oldDelFileName != null)
				{
					// Mark this file for deletion.  Note that we don't
					// actually try to delete it until the new segments files is
					// successfully written:
					deleter.AddPendingFile(oldDelFileName);
				}
				
				si.AdvanceDelGen();
				
				// We can write directly to the actual name (vs to a
				// .tmp & renaming it) because the file is not live
				// until segments file is written:
				deletedDocs.Write(Directory(), si.GetDelFileName());
			}
			if (undeleteAll && si.HasDeletions())
			{
				System.String oldDelFileName = si.GetDelFileName();
				if (oldDelFileName != null)
				{
					// Mark this file for deletion.  Note that we don't
					// actually try to delete it until the new segments files is
					// successfully written:
					deleter.AddPendingFile(oldDelFileName);
				}
				si.ClearDelGen();
			}
			if (normsDirty)
			{
				// re-write norms
				si.SetNumFields(fieldInfos.Size());
				System.Collections.IEnumerator values = norms.Values.GetEnumerator();
				while (values.MoveNext())
				{
					Norm norm = (Norm) values.Current;
					if (norm.dirty)
					{
						norm.ReWrite(si);
					}
				}
			}
			deletedDocsDirty = false;
			normsDirty = false;
			undeleteAll = false;
		}
		
		protected internal override void  DoClose()
		{
			if (fieldsReader != null)
			{
				fieldsReader.Close();
			}
			if (tis != null)
			{
				tis.Close();
			}
			
			if (freqStream != null)
				freqStream.Close();
			if (proxStream != null)
				proxStream.Close();
			
			CloseNorms();
			
			if (termVectorsReaderOrig != null)
				termVectorsReaderOrig.Close();
			
			if (cfsReader != null)
				cfsReader.Close();
		}
		
		internal static bool HasDeletions(SegmentInfo si)
		{
			return si.HasDeletions();
		}
		
		public override bool HasDeletions()
		{
			return deletedDocs != null;
		}
		
		internal static bool UsesCompoundFile(SegmentInfo si)
		{
			return si.GetUseCompoundFile();
		}
		
		internal static bool HasSeparateNorms(SegmentInfo si)
		{
			return si.HasSeparateNorms();
		}
		
		protected internal override void  DoDelete(int docNum)
		{
			if (deletedDocs == null)
				deletedDocs = new BitVector(MaxDoc());
			deletedDocsDirty = true;
			undeleteAll = false;
			deletedDocs.Set(docNum);
		}
		
		protected internal override void  DoUndeleteAll()
		{
			deletedDocs = null;
			deletedDocsDirty = false;
			undeleteAll = true;
		}
		
		internal virtual System.Collections.ArrayList Files()
		{
			System.Collections.ArrayList files = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(16));
			
			if (si.GetUseCompoundFile())
			{
				System.String name = segment + ".cfs";
				if (Directory().FileExists(name))
				{
					files.Add(name);
				}
			}
			else
			{
				for (int i = 0; i < IndexFileNames.INDEX_EXTENSIONS.Length; i++)
				{
					System.String name = segment + "." + IndexFileNames.INDEX_EXTENSIONS[i];
					if (Directory().FileExists(name))
						files.Add(name);
				}
			}
			
			if (si.HasDeletions())
			{
				files.Add(si.GetDelFileName());
			}
			
			bool addedNrm = false;
			for (int i = 0; i < fieldInfos.Size(); i++)
			{
				System.String name = si.GetNormFileName(i);
				if (name != null && Directory().FileExists(name))
				{
					if (name.EndsWith("." + IndexFileNames.NORMS_EXTENSION))
					{
						if (addedNrm)
							continue; // add .nrm just once
						addedNrm = true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -