FileDocCategorySizeDatePackage
SegmentInfos.javaAPI DocApache Lucene 2.2.021908Sat Jun 16 22:20:36 BST 2007org.apache.lucene.index

SegmentInfos

public final class SegmentInfos extends Vector
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.

Fields Summary
public static final int
FORMAT
The file format version, a negative number.
public static final int
FORMAT_LOCKLESS
This format adds details used for lockless commits. It differs slightly from the previous format in that file names are never re-used (write once). Instead, each file is written to the next generation. For example, segments_1, segments_2, etc. This allows us to not use a commit lock. See file formats for details.
public static final int
FORMAT_SINGLE_NORM_FILE
This format adds a "hasSingleNormFile" flag into each segment info. See LUCENE-756 for details.
private static final int
CURRENT_FORMAT
public int
counter
private long
version
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
generation
private long
lastGeneration
private static PrintStream
infoStream
If non-null, information about loading segments_N files will be printed here. @see #setInfoStream.
private static int
defaultGenFileRetryCount
private static int
defaultGenFileRetryPauseMsec
private static int
defaultGenLookaheadCount
Constructors Summary
Methods Summary
public java.lang.Objectclone()
Returns a copy of this instance, also copying each SegmentInfo.

    SegmentInfos sis = (SegmentInfos) super.clone();
    for(int i=0;i<sis.size();i++) {
      sis.setElementAt(((SegmentInfo) sis.elementAt(i)).clone(), i);
    }
    return sis;
  
public static longgenerationFromSegmentsFileName(java.lang.String fileName)
Parse the generation off the segments file name and return it.

    if (fileName.equals(IndexFileNames.SEGMENTS)) {
      return 0;
    } else if (fileName.startsWith(IndexFileNames.SEGMENTS)) {
      return Long.parseLong(fileName.substring(1+IndexFileNames.SEGMENTS.length()),
                            Character.MAX_RADIX);
    } else {
      throw new IllegalArgumentException("fileName \"" + fileName + "\" is not a segments file");
    }
  
public static java.lang.StringgetCurrentSegmentFileName(java.lang.String[] files)
Get the filename of the current segments_N file from a list of files.

param
files -- array of file names to check

    return IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
                                                 "",
                                                 getCurrentSegmentGeneration(files));
  
public static java.lang.StringgetCurrentSegmentFileName(org.apache.lucene.store.Directory directory)
Get the filename of the current segments_N file in the directory.

param
directory -- directory to search for the latest segments_N file

    return IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
                                                 "",
                                                 getCurrentSegmentGeneration(directory));
  
public java.lang.StringgetCurrentSegmentFileName()
Get the segments_N filename in use by this segment infos.

    return IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
                                                 "",
                                                 lastGeneration);
  
public static longgetCurrentSegmentGeneration(java.lang.String[] files)
Get the generation (N) of the current segments_N file from a list of files.

param
files -- array of file names to check

    if (files == null) {
      return -1;
    }
    long max = -1;
    for (int i = 0; i < files.length; i++) {
      String file = files[i];
      if (file.startsWith(IndexFileNames.SEGMENTS) && !file.equals(IndexFileNames.SEGMENTS_GEN)) {
        long gen = generationFromSegmentsFileName(file);
        if (gen > max) {
          max = gen;
        }
      }
    }
    return max;
  
public static longgetCurrentSegmentGeneration(org.apache.lucene.store.Directory directory)
Get the generation (N) of the current segments_N file in the directory.

param
directory -- directory to search for the latest segments_N file

    String[] files = directory.list();
    if (files == null)
      throw new IOException("cannot read directory " + directory + ": list() returned null");
    return getCurrentSegmentGeneration(files);
  
public static intgetDefaultGenFileRetryCount()

see
#setDefaultGenFileRetryCount

    return defaultGenFileRetryCount;
  
public static intgetDefaultGenFileRetryPauseMsec()

see
#setDefaultGenFileRetryPauseMsec

    return defaultGenFileRetryPauseMsec;
  
public static intgetDefaultGenLookahedCount()

see
#setDefaultGenLookaheadCount

    return defaultGenLookaheadCount;
  
public longgetGeneration()

    return generation;
  
public static java.io.PrintStreamgetInfoStream()

see
#setInfoStream

    return infoStream;
  
public java.lang.StringgetNextSegmentFileName()
Get the next segments_N filename that will be written.

    long nextGeneration;

    if (generation == -1) {
      nextGeneration = 1;
    } else {
      nextGeneration = generation+1;
    }
    return IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
                                                 "",
                                                 nextGeneration);
  
public longgetVersion()
version number when this SegmentInfos was generated.

    return version;
  
public final org.apache.lucene.index.SegmentInfoinfo(int i)


       
    return (SegmentInfo) elementAt(i);
  
private static voidmessage(java.lang.String message)

    if (infoStream != null) {
      infoStream.println(Thread.currentThread().getName() + ": " + message);
    }
  
public final voidread(org.apache.lucene.store.Directory directory)
This version of read uses the retry logic (for lock-less commits) to find the right segments file to load.

throws
CorruptIndexException if the index is corrupt
throws
IOException if there is a low-level IO error


    generation = lastGeneration = -1;

    new FindSegmentsFile(directory) {

      protected Object doBody(String segmentFileName) throws CorruptIndexException, IOException {
        read(directory, segmentFileName);
        return null;
      }
    }.run();
  
public final voidread(org.apache.lucene.store.Directory directory, java.lang.String segmentFileName)
Read a particular segmentFileName. Note that this may throw an IOException if a commit is in process.

param
directory -- directory containing the segments file
param
segmentFileName -- segment file to load
throws
CorruptIndexException if the index is corrupt
throws
IOException if there is a low-level IO error

    boolean success = false;

    IndexInput input = directory.openInput(segmentFileName);

    generation = generationFromSegmentsFileName(segmentFileName);

    lastGeneration = generation;

    try {
      int format = input.readInt();
      if(format < 0){     // file contains explicit format info
        // check that it is a format we can understand
        if (format < CURRENT_FORMAT)
          throw new CorruptIndexException("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
        addElement(new SegmentInfo(directory, format, input));
      }
      
      if(format >= 0){    // in old format the version number may be at the end of the file
        if (input.getFilePointer() >= input.length())
          version = System.currentTimeMillis(); // old file format without version number
        else
          version = input.readLong(); // read version
      }
      success = true;
    }
    finally {
      input.close();
      if (!success) {
        // Clear any segment infos we had loaded so we
        // have a clean slate on retry:
        clear();
      }
    }
  
public static longreadCurrentVersion(org.apache.lucene.store.Directory directory)
Current version number from segments file.

throws
CorruptIndexException if the index is corrupt
throws
IOException if there is a low-level IO error


    return ((Long) new FindSegmentsFile(directory) {
        protected Object doBody(String segmentFileName) throws CorruptIndexException, IOException {

          IndexInput input = directory.openInput(segmentFileName);

          int format = 0;
          long version = 0;
          try {
            format = input.readInt();
            if(format < 0){
              if (format < CURRENT_FORMAT)
                throw new CorruptIndexException("Unknown format version: " + format);
              version = input.readLong(); // read version
            }
          }
          finally {
            input.close();
          }
     
          if(format < 0)
            return new Long(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, segmentFileName);
          return new Long(sis.getVersion());
        }
      }.run()).longValue();
  
public static voidsetDefaultGenFileRetryCount(int count)
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.


                                    
       
    defaultGenFileRetryCount = count;
  
public static voidsetDefaultGenFileRetryPauseMsec(int msec)
Advanced: set how many milliseconds to pause in between attempts to load the segments.gen file.

    defaultGenFileRetryPauseMsec = msec;
  
public static voidsetDefaultGenLookaheadCount(int count)
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.

    defaultGenLookaheadCount = count;
  
public static voidsetInfoStream(java.io.PrintStream infoStream)
If non-null, information about retries when loading the segments file will be printed to this.

    SegmentInfos.infoStream = infoStream;
  
public final voidwrite(org.apache.lucene.store.Directory directory)


    String segmentFileName = getNextSegmentFileName();

    // Always advance the generation on write:
    if (generation == -1) {
      generation = 1;
    } else {
      generation++;
    }

    IndexOutput output = directory.createOutput(segmentFileName);

    boolean success = false;

    try {
      output.writeInt(CURRENT_FORMAT); // write FORMAT
      output.writeLong(++version); // every write changes
                                   // the index
      output.writeInt(counter); // write counter
      output.writeInt(size()); // write infos
      for (int i = 0; i < size(); i++) {
        info(i).write(output);
      }         
    }
    finally {
      try {
        output.close();
        success = true;
      } finally {
        if (!success) {
          // Try not to leave a truncated segments_N file in
          // the index:
          directory.deleteFile(segmentFileName);
        }
      }
    }

    try {
      output = directory.createOutput(IndexFileNames.SEGMENTS_GEN);
      try {
        output.writeInt(FORMAT_LOCKLESS);
        output.writeLong(generation);
        output.writeLong(generation);
      } finally {
        output.close();
      }
    } catch (IOException e) {
      // It's OK if we fail to write this file since it's
      // used only as one of the retry fallbacks.
    }
    
    lastGeneration = generation;