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

📄 segmentinfos.cs

📁 Lucene.Net 版本源码 测试通过
💻 CS
📖 第 1 页 / 共 2 页
字号:
			}
			
			lastGeneration = generation;
		}
		
		/// <summary> Returns a copy of this instance, also copying each
		/// SegmentInfo.
		/// </summary>
		
		public override System.Object Clone()
		{
			SegmentInfos sis = new SegmentInfos();
			for (int i = 0; i < sis.Count; i++)
			{
				sis.Add(((SegmentInfo) this[i]).Clone());
			}
			return sis;
		}
		
		/// <summary> version number when this SegmentInfos was generated.</summary>
		public long GetVersion()
		{
			return version;
		}
		
		/// <summary> Current version number from segments file.</summary>
		public static long ReadCurrentVersion(Directory directory)
		{
			
			return (long) ((System.Int64) new AnonymousClassFindSegmentsFile1(directory).run());
		}
		
		/// <summary>If non-null, information about retries when loading
		/// the segments file will be printed to this.
		/// </summary>
		public static void  SetInfoStream(System.IO.TextWriter infoStream)
		{
			SegmentInfos.infoStream = infoStream;
		}
		
		/* Advanced configuration of retry logic in loading
		segments_N file */
		private static int defaultGenFileRetryCount = 10;
		private static int defaultGenFileRetryPauseMsec = 50;
		private static int defaultGenLookaheadCount = 10;
		
		/// <summary> Advanced: set how many times to try loading the
		/// segments.gen file contents to determine current segment
		/// generation.  This file is only referenced when the
		/// primary method (listing the directory) fails.
		/// </summary>
		public static void  SetDefaultGenFileRetryCount(int count)
		{
			defaultGenFileRetryCount = count;
		}
		
		/// <seealso cref="#setDefaultGenFileRetryCount">
		/// </seealso>
		public static int GetDefaultGenFileRetryCount()
		{
			return defaultGenFileRetryCount;
		}
		
		/// <summary> Advanced: set how many milliseconds to pause in between
		/// attempts to load the segments.gen file.
		/// </summary>
		public static void  SetDefaultGenFileRetryPauseMsec(int msec)
		{
			defaultGenFileRetryPauseMsec = msec;
		}
		
		/// <seealso cref="#setDefaultGenFileRetryPauseMsec">
		/// </seealso>
		public static int GetDefaultGenFileRetryPauseMsec()
		{
			return defaultGenFileRetryPauseMsec;
		}
		
		/// <summary> Advanced: set how many times to try incrementing the
		/// gen when loading the segments file.  This only runs if
		/// the primary (listing directory) and secondary (opening
		/// segments.gen file) methods fail to find the segments
		/// file.
		/// </summary>
		public static void  SetDefaultGenLookaheadCount(int count)
		{
			defaultGenLookaheadCount = count;
		}
		/// <seealso cref="#setDefaultGenLookaheadCount">
		/// </seealso>
		public static int GetDefaultGenLookahedCount()
		{
			return defaultGenLookaheadCount;
		}
		
		/// <seealso cref="#setInfoStream">
		/// </seealso>
		public static System.IO.TextWriter GetInfoStream()
		{
			return infoStream;
		}
		
		private static void  Message(System.String message)
		{
			if (infoStream != null)
			{
				infoStream.WriteLine(SupportClass.ThreadClass.Current().Name + ": " + message);
			}
		}
		
		/// <summary> Utility class for executing code that needs to do
		/// something with the current segments file.  This is
		/// necessary with lock-less commits because from the time
		/// you locate the current segments file name, until you
		/// actually open it, read its contents, or check modified
		/// time, etc., it could have been deleted due to a writer
		/// commit finishing.
		/// </summary>
		public abstract class FindSegmentsFile
		{
			
			internal System.IO.FileInfo fileDirectory;
			internal Directory directory;
			
			public FindSegmentsFile(System.IO.FileInfo directory)
			{
				this.fileDirectory = directory;
			}
			
			public FindSegmentsFile(Directory directory)
			{
				this.directory = directory;
			}
			
			public System.Object run()
			{
				System.String segmentFileName = null;
				long lastGen = - 1;
				long gen = 0;
				int genLookaheadCount = 0;
				System.IO.IOException exc = null;
				bool retry = false;
				
				int method = 0;
				
				// Loop until we succeed in calling doBody() without
				// hitting an IOException.  An IOException most likely
				// means a commit was in process and has finished, in
				// the time it took us to load the now-old infos files
				// (and segments files).  It's also possible it's a
				// true error (corrupt index).  To distinguish these,
				// on each retry we must see "forward progress" on
				// which generation we are trying to load.  If we
				// don't, then the original error is real and we throw
				// it.
				
				// We have three methods for determining the current
				// generation.  We try each in sequence.
				
				while (true)
				{
					
					// Method 1: list the directory and use the highest
					// segments_N file.  This method works well as long
					// as there is no stale caching on the directory
					// contents:
					System.String[] files = null;
					
					if (0 == method)
					{
						if (directory != null)
						{
							files = directory.List();
						}
						else
						{
							files = System.IO.Directory.GetFileSystemEntries(fileDirectory.FullName);
                            for (int i = 0; i < files.Length; i++)
                            {
                                System.IO.FileInfo fi = new System.IO.FileInfo(files[i]);
                                files[i] = fi.Name;
                            }
                        }
						
						gen = Lucene.Net.Index.SegmentInfos.GetCurrentSegmentGeneration(files);
						
						if (gen == - 1)
						{
							System.String s = "";
							for (int i = 0; i < files.Length; i++)
							{
								s += (" " + files[i]);
							}
							throw new System.IO.FileNotFoundException("no segments* file found: files:" + s);
						}
					}
					
					// Method 2 (fallback if Method 1 isn't reliable):
					// if the directory listing seems to be stale, then
					// try loading the "segments.gen" file.
					if (1 == method || (0 == method && lastGen == gen && retry))
					{
						
						method = 1;
						
						for (int i = 0; i < Lucene.Net.Index.SegmentInfos.defaultGenFileRetryCount; i++)
						{
							IndexInput genInput = null;
							try
							{
								genInput = directory.OpenInput(IndexFileNames.SEGMENTS_GEN);
							}
							catch (System.IO.IOException e)
							{
								Lucene.Net.Index.SegmentInfos.Message("segments.gen open: IOException " + e);
							}
							if (genInput != null)
							{
								
								try
								{
									int version = genInput.ReadInt();
									if (version == Lucene.Net.Index.SegmentInfos.FORMAT_LOCKLESS)
									{
										long gen0 = genInput.ReadLong();
										long gen1 = genInput.ReadLong();
										Lucene.Net.Index.SegmentInfos.Message("fallback check: " + gen0 + "; " + gen1);
										if (gen0 == gen1)
										{
											// The file is consistent.
											if (gen0 > gen)
											{
												Lucene.Net.Index.SegmentInfos.Message("fallback to '" + IndexFileNames.SEGMENTS_GEN + "' check: now try generation " + gen0 + " > " + gen);
												gen = gen0;
											}
											break;
										}
									}
								}
								catch (System.IO.IOException err2)
								{
									// will retry
								}
								finally
								{
									genInput.Close();
								}
							}
							try
							{
								System.Threading.Thread.Sleep(new System.TimeSpan((System.Int64) 10000 * Lucene.Net.Index.SegmentInfos.defaultGenFileRetryPauseMsec));
							}
							catch (System.Threading.ThreadInterruptedException e)
							{
								// will retry
							}
						}
					}
					
					// Method 3 (fallback if Methods 2 & 3 are not
					// reliable): since both directory cache and file
					// contents cache seem to be stale, just advance the
					// generation.
					if (2 == method || (1 == method && lastGen == gen && retry))
					{
						
						method = 2;
						
						if (genLookaheadCount < Lucene.Net.Index.SegmentInfos.defaultGenLookaheadCount)
						{
							gen++;
							genLookaheadCount++;
							Lucene.Net.Index.SegmentInfos.Message("look ahead increment gen to " + gen);
						}
					}
					
					if (lastGen == gen)
					{
						
						// This means we're about to try the same
						// segments_N last tried.  This is allowed,
						// exactly once, because writer could have been in
						// the process of writing segments_N last time.
						
						if (retry)
						{
							// OK, we've tried the same segments_N file
							// twice in a row, so this must be a real
							// error.  We throw the original exception we
							// got.
							throw exc;
						}
						else
						{
							retry = true;
						}
					}
					else
					{
						// Segment file has advanced since our last loop, so
						// reset retry:
						retry = false;
					}
					
					lastGen = gen;
					
					segmentFileName = IndexFileNames.FileNameFromGeneration(IndexFileNames.SEGMENTS, "", gen);
					
					try
					{
						System.Object v = DoBody(segmentFileName);
						if (exc != null)
						{
							Lucene.Net.Index.SegmentInfos.Message("success on " + segmentFileName);
						}
						return v;
					}
					catch (System.IO.IOException err)
					{
						
						// Save the original root cause:
						if (exc == null)
						{
							exc = err;
						}
						
						Lucene.Net.Index.SegmentInfos.Message("primary Exception on '" + segmentFileName + "': " + err + "'; will retry: retry=" + retry + "; gen = " + gen);
						
						if (!retry && gen > 1)
						{
							
							// This is our first time trying this segments
							// file (because retry is false), and, there is
							// possibly a segments_(N-1) (because gen > 1).
							// So, check if the segments_(N-1) exists and
							// try it if so:
							System.String prevSegmentFileName = IndexFileNames.FileNameFromGeneration(IndexFileNames.SEGMENTS, "", gen - 1);
							
							if (directory.FileExists(prevSegmentFileName))
							{
								Lucene.Net.Index.SegmentInfos.Message("fallback to prior segment file '" + prevSegmentFileName + "'");
								try
								{
									System.Object v = DoBody(prevSegmentFileName);
									if (exc != null)
									{
										Lucene.Net.Index.SegmentInfos.Message("success on fallback " + prevSegmentFileName);
									}
									return v;
								}
								catch (System.IO.IOException err2)
								{
									Lucene.Net.Index.SegmentInfos.Message("secondary Exception on '" + prevSegmentFileName + "': " + err2 + "'; will retry");
								}
							}
						}
					}
				}
			}
			
			/// <summary> Subclass must implement this.  The assumption is an
			/// IOException will be thrown if something goes wrong
			/// during the processing that could have been caused by
			/// a writer committing.
			/// </summary>
			public abstract System.Object DoBody(System.String segmentFileName);
		}
	}
}

⌨️ 快捷键说明

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