19 using System.Collections.Generic;
21 using Lucene.Net.Support;
29 namespace Lucene.Net.Index
45 this.enclosingInstance = enclosingInstance;
52 return enclosingInstance;
56 internal AnonymousClassFindSegmentsFile(
SegmentInfos enclosingInstance, Lucene.Net.Store.Directory Param1):base(Param1)
58 InitBlock(enclosingInstance);
61 public override System.Object DoBody(System.String segmentFileName)
63 Enclosing_Instance.Read(directory, segmentFileName);
69 public const int FORMAT = - 1;
80 public const int FORMAT_LOCKLESS = - 2;
86 public const int FORMAT_SINGLE_NORM_FILE = - 3;
91 public const int FORMAT_SHARED_DOC_STORE = - 4;
96 public const int FORMAT_CHECKSUM = - 5;
101 public const int FORMAT_DEL_COUNT = - 6;
107 public const int FORMAT_HAS_PROX = - 7;
110 public const int FORMAT_USER_DATA = - 8;
115 public const int FORMAT_DIAGNOSTICS = - 9;
118 internal static readonly
int CURRENT_FORMAT = FORMAT_DIAGNOSTICS;
120 public int counter = 0;
124 private long version = (DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond);
126 private long generation = 0;
127 private long lastGeneration = 0;
131 private IDictionary<string, string> userData =
new HashMap<string, string>();
136 private static System.IO.StreamWriter infoStream;
149 public static long GetCurrentSegmentGeneration(System.String[] files)
156 for (
int i = 0; i < files.Length; i++)
158 System.String file = files[i];
161 long gen = GenerationFromSegmentsFileName(file);
177 public static long GetCurrentSegmentGeneration(
Directory directory)
181 return GetCurrentSegmentGeneration(directory.ListAll());
196 public static System.String GetCurrentSegmentFileName(System.String[] files)
207 public static System.String GetCurrentSegmentFileName(
Directory directory)
213 public System.String GetCurrentSegmentFileName()
221 public static long GenerationFromSegmentsFileName(System.String fileName)
233 throw new System.ArgumentException(
"fileName \"" + fileName +
"\" is not a segments file");
239 [System.Diagnostics.CodeAnalysis.SuppressMessage(
"Microsoft.Design",
"CA1024:UsePropertiesWhereAppropriate")]
240 public System.String GetNextSegmentFileName()
244 if (generation == - 1)
250 nextGeneration = generation + 1;
265 public void Read(
Directory directory, System.String segmentFileName)
267 bool success =
false;
274 generation = GenerationFromSegmentsFileName(segmentFileName);
276 lastGeneration = generation;
280 int format = input.ReadInt();
285 if (format < CURRENT_FORMAT)
287 version = input.ReadLong();
288 counter = input.ReadInt();
296 for (
int i = input.ReadInt(); i > 0; i--)
305 if (input.FilePointer >= input.Length())
306 version = (DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond);
309 version = input.ReadLong();
312 if (format <= FORMAT_USER_DATA)
314 if (format <= FORMAT_DIAGNOSTICS)
316 userData = input.ReadStringStringMap();
318 else if (0 != input.ReadByte())
321 userData =
new HashMap<string,string> {{
"userData", input.ReadString()}};
326 userData =
new HashMap<string, string>();
332 userData =
new HashMap<string, string>();
335 if (format <= FORMAT_CHECKSUM)
337 long checksumNow = input.Checksum;
338 long checksumThen = input.ReadLong();
339 if (checksumNow != checksumThen)
364 generation = lastGeneration = - 1;
366 new AnonymousClassFindSegmentsFile(
this, directory).Run();
376 System.String segmentFileName = GetNextSegmentFileName();
379 if (generation == - 1)
390 bool success =
false;
394 segnOutput.WriteInt(CURRENT_FORMAT);
395 segnOutput.WriteLong(++version);
397 segnOutput.WriteInt(counter);
398 segnOutput.WriteInt(Count);
399 for (
int i = 0; i < Count; i++)
401 Info(i).Write(segnOutput);
403 segnOutput.WriteStringStringMap(userData);
404 segnOutput.PrepareCommit();
406 pendingSegnOutput = segnOutput;
418 catch (System.Exception)
426 directory.DeleteFile(segmentFileName);
428 catch (System.Exception)
440 public System.Object Clone()
443 for (
int i = 0; i < this.Count; i++)
448 sis.generation = this.generation;
449 sis.lastGeneration = this.lastGeneration;
451 sis.userData =
new HashMap<string, string>(userData);
452 sis.version = this.version;
459 get {
return version; }
462 public long Generation
464 get {
return generation; }
467 public long LastGeneration
469 get {
return lastGeneration; }
475 public static long ReadCurrentVersion(
Directory directory)
492 public static System.Collections.Generic.IDictionary<string,
string> ReadCurrentUserData(
Directory directory)
502 public static void SetInfoStream(System.IO.StreamWriter infoStream)
509 private static int defaultGenFileRetryCount = 10;
510 private static int defaultGenFileRetryPauseMsec = 50;
511 private static int defaultGenLookaheadCount = 10;
518 public static int DefaultGenFileRetryCount
520 get {
return defaultGenFileRetryCount; }
521 set { defaultGenFileRetryCount = value; }
524 public static int DefaultGenFileRetryPauseMsec
526 set { defaultGenFileRetryPauseMsec = value; }
527 get {
return defaultGenFileRetryPauseMsec; }
536 public static int DefaultGenLookaheadCount
538 set { defaultGenLookaheadCount = value; }
539 get {
return defaultGenLookaheadCount; }
544 public static StreamWriter InfoStream
546 get {
return infoStream; }
549 private static void Message(System.String message)
551 if (infoStream != null)
572 this.directory = directory;
575 public System.Object Run()
585 throw new System.IO.IOException(
"the specified commit does not match the specified Directory");
589 System.String segmentFileName = null;
592 int genLookaheadCount = 0;
593 System.IO.IOException exc = null;
624 System.String[] files = null;
628 files = directory.ListAll();
631 genA = Lucene.Net.Index.SegmentInfos.GetCurrentSegmentGeneration(files);
633 Lucene.Net.Index.SegmentInfos.Message(
"directory listing genA=" + genA);
641 for (
int i = 0; i < Lucene.Net.Index.SegmentInfos.defaultGenFileRetryCount; i++)
648 catch (System.IO.FileNotFoundException e)
650 Lucene.Net.Index.SegmentInfos.Message(
"segments.gen open: FileNotFoundException " + e);
653 catch (System.IO.IOException e)
655 Lucene.Net.Index.SegmentInfos.Message(
"segments.gen open: IOException " + e);
658 if (genInput != null)
662 int version = genInput.ReadInt();
663 if (version == Lucene.Net.Index.SegmentInfos.FORMAT_LOCKLESS)
665 long gen0 = genInput.ReadLong();
666 long gen1 = genInput.ReadLong();
667 Lucene.Net.Index.SegmentInfos.Message(
"fallback check: " + gen0 +
"; " + gen1);
676 catch (System.IO.IOException)
686 System.Threading.Thread.Sleep(
new TimeSpan((System.Int64) 10000 * Lucene.Net.Index.SegmentInfos.defaultGenFileRetryPauseMsec));
701 throw new System.IO.FileNotFoundException(
"no segments* file found in " + directory +
": files:" +
string.Join(
" ", files));
709 if (1 == method || (0 == method && lastGen == gen && retry))
714 if (genLookaheadCount < Lucene.Net.Index.SegmentInfos.defaultGenLookaheadCount)
718 Lucene.Net.Index.SegmentInfos.Message(
"look ahead increment gen to " + gen);
741 else if (0 == method)
754 System.Object v = DoBody(segmentFileName);
755 Lucene.Net.Index.SegmentInfos.Message(
"success on " + segmentFileName);
759 catch (System.IO.IOException err)
768 Lucene.Net.Index.SegmentInfos.Message(
"primary Exception on '" + segmentFileName +
"': " + err +
"'; will retry: retry=" + retry +
"; gen = " + gen);
770 if (!retry && gen > 1)
781 prevExists = directory.FileExists(prevSegmentFileName);
785 Lucene.Net.Index.SegmentInfos.Message(
"fallback to prior segment file '" + prevSegmentFileName +
"'");
788 System.Object v = DoBody(prevSegmentFileName);
791 Lucene.Net.Index.SegmentInfos.Message(
"success on fallback " + prevSegmentFileName);
795 catch (System.IO.IOException err2)
797 Lucene.Net.Index.SegmentInfos.Message(
"secondary Exception on '" + prevSegmentFileName +
"': " + err2 +
"'; will retry");
810 public abstract System.Object DoBody(System.String segmentFileName);
821 infos.AddRange(this.GetRange(first, last - first));
828 lastGeneration = other.lastGeneration;
829 generation = other.generation;
830 version = other.version;
833 internal void RollbackCommit(
Directory dir)
835 if (pendingSegnOutput != null)
839 pendingSegnOutput.Close();
841 catch (System.Exception)
851 System.String segmentFileName = IndexFileNames.FileNameFromGeneration(IndexFileNames.SEGMENTS,
"", generation);
852 dir.DeleteFile(segmentFileName);
854 catch (System.Exception)
859 pendingSegnOutput = null;
869 internal void PrepareCommit(
Directory dir)
871 if (pendingSegnOutput != null)
872 throw new System.SystemException(
"prepareCommit was already called");
882 public System.Collections.Generic.ICollection<
string> Files(
Directory dir,
bool includeSegmentsFile)
884 System.Collections.Generic.HashSet<
string> files =
new System.Collections.Generic.HashSet<
string>();
885 if (includeSegmentsFile)
887 files.Add(GetCurrentSegmentFileName());
890 for (
int i = 0; i < size; i++)
895 files.UnionWith(Info(i).Files());
901 internal void FinishCommit(
Directory dir)
903 if (pendingSegnOutput == null)
904 throw new System.SystemException(
"prepareCommit was not called");
905 bool success =
false;
908 pendingSegnOutput.FinishCommit();
909 pendingSegnOutput.Close();
910 pendingSegnOutput = null;
929 System.String fileName = IndexFileNames.FileNameFromGeneration(IndexFileNames.SEGMENTS,
"", generation);
942 dir.DeleteFile(fileName);
944 catch (System.Exception)
951 lastGeneration = generation;
955 IndexOutput genOutput = dir.CreateOutput(IndexFileNames.SEGMENTS_GEN);
958 genOutput.WriteInt(FORMAT_LOCKLESS);
959 genOutput.WriteLong(generation);
960 genOutput.WriteLong(generation);
967 catch (System.Exception)
987 var buffer =
new System.Text.StringBuilder();
989 for (
int i = 0; i < count; i++)
996 buffer.Append(info.
SegString(directory));
997 if (info.
dir != directory)
1000 return buffer.ToString();
1004 public IDictionary<string, string> UserData
1006 get {
return userData; }
1008 userData = value ??
new HashMap<string, string>();
1020 lastGeneration = other.lastGeneration;
1026 int numSegments = Count;
1027 for (
int i = 0; i < numSegments; i++)
1028 if (Info(i).dir != dir)
1033 #region Lucene.NET (Equals & GetHashCode )
1040 public override bool Equals(
object obj)
1042 if (obj == null)
return false;
1045 if (objToCompare == null)
return false;
1047 if (this.Count != objToCompare.Count)
return false;
1049 for (
int idx = 0; idx < this.Count; idx++)
1051 if (!
this[idx].Equals(objToCompare[idx]))
return false;
1061 public override int GetHashCode()
1064 for (
int i = 0; i < this.Count; i++)