/* * 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 Directory = Lucene.Net.Store.Directory; using IndexInput = Lucene.Net.Store.IndexInput; using IndexOutput = Lucene.Net.Store.IndexOutput; using Constants = Lucene.Net.Util.Constants; namespace Lucene.Net.Index { [Serializable] public sealed class SegmentInfos : System.Collections.ArrayList { /// The file format version, a negative number. /* Works since counter, the old 1st entry, is always >= 0 */ public const int FORMAT = - 1; public int counter = 0; // used to name new segments /// counts how often the index has been changed by adding or deleting docs. /// starting with the current time in milliseconds forces to create unique version numbers. /// private long version = System.DateTime.Now.Ticks; public SegmentInfo Info(int i) { return (SegmentInfo) this[i]; } public void Read(Directory directory) { IndexInput input = directory.OpenInput(IndexFileNames.SEGMENTS); try { int format = input.ReadInt(); if (format < 0) { // file contains explicit format info // check that it is a format we can understand if (format < FORMAT) throw new System.IO.IOException("Unknown format version: " + format); version = input.ReadLong(); // read version counter = input.ReadInt(); // read counter } else { // file is in old format without explicit format info counter = format; } for (int i = input.ReadInt(); i > 0; i--) { // read segmentInfos SegmentInfo si = new SegmentInfo(input.ReadString(), input.ReadInt(), directory); Add(si); } if (format >= 0) { // in old format the version number may be at the end of the file if (input.GetFilePointer() >= input.Length()) version = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; // old file format without version number else version = input.ReadLong(); // read version } } finally { input.Close(); } } public void Write(Directory directory) { IndexOutput output = directory.CreateOutput("segments.new"); try { output.WriteInt(FORMAT); // write FORMAT output.WriteLong(++version); // every write changes the index output.WriteInt(counter); // write counter output.WriteInt(Count); // write infos for (int i = 0; i < Count; i++) { SegmentInfo si = Info(i); output.WriteString(si.name); output.WriteInt(si.docCount); } } finally { output.Close(); } // install new segment info directory.RenameFile("segments.new", IndexFileNames.SEGMENTS); } /// version number when this SegmentInfos was generated. public long GetVersion() { return version; } /// Current version number from segments file. public static long ReadCurrentVersion(Directory directory) { IndexInput input = directory.OpenInput(IndexFileNames.SEGMENTS); int format = 0; long version = 0; try { format = input.ReadInt(); if (format < 0) { if (format < FORMAT) throw new System.IO.IOException("Unknown format version: " + format); version = input.ReadLong(); // read version } } finally { input.Close(); } if (format < 0) return version; // We cannot be sure about the format of the file. // Therefore we have to read the whole file and cannot simply seek to the version entry. SegmentInfos sis = new SegmentInfos(); sis.Read(directory); return sis.GetVersion(); } } }