| Method from org.apache.lucene.index.SegmentInfos Detail: |
public Object clone() {
SegmentInfos sis = (SegmentInfos) super.clone();
for(int i=0;i< sis.size();i++) {
sis.set(i, (SegmentInfo) sis.info(i).clone());
}
sis.userData = new HashMap< String, String >(userData);
return sis;
}
Returns a copy of this instance, also copying each
SegmentInfo. |
final void commit(Directory dir) throws IOException {
prepareCommit(dir);
finishCommit(dir);
}
Writes & syncs to the Directory dir, taking care to
remove the segments file on exception |
public Collection<String> files(Directory dir,
boolean includeSegmentsFile) throws IOException {
HashSet< String > files = new HashSet< String >();
if (includeSegmentsFile) {
files.add(getCurrentSegmentFileName());
}
final int size = size();
for(int i=0;i< size;i++) {
final SegmentInfo info = info(i);
if (info.dir == dir) {
files.addAll(info(i).files());
}
}
return files;
}
Returns all file names referenced by SegmentInfo
instances matching the provided Directory (ie files
associated with any "external" segments are skipped).
The returned collection is recomputed on each
invocation. |
final void finishCommit(Directory dir) throws IOException {
if (pendingSegnOutput == null)
throw new IllegalStateException("prepareCommit was not called");
boolean success = false;
try {
pendingSegnOutput.finishCommit();
pendingSegnOutput.close();
pendingSegnOutput = null;
success = true;
} finally {
if (!success)
rollbackCommit(dir);
}
// NOTE: if we crash here, we have left a segments_N
// file in the directory in a possibly corrupt state (if
// some bytes made it to stable storage and others
// didn't). But, the segments_N file includes checksum
// at the end, which should catch this case. So when a
// reader tries to read it, it will throw a
// CorruptIndexException, which should cause the retry
// logic in SegmentInfos to kick in and load the last
// good (previous) segments_N-1 file.
final String fileName = IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
"",
generation);
success = false;
try {
dir.sync(fileName);
success = true;
} finally {
if (!success) {
try {
dir.deleteFile(fileName);
} catch (Throwable t) {
// Suppress so we keep throwing the original exception
}
}
}
lastGeneration = generation;
try {
IndexOutput genOutput = dir.createOutput(IndexFileNames.SEGMENTS_GEN);
try {
genOutput.writeInt(FORMAT_LOCKLESS);
genOutput.writeLong(generation);
genOutput.writeLong(generation);
} finally {
genOutput.close();
}
} catch (Throwable t) {
// It's OK if we fail to write this file since it's
// used only as one of the retry fallbacks.
}
}
|
public static long generationFromSegmentsFileName(String fileName) {
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");
}
}
Parse the generation off the segments file name and
return it. |
public String getCurrentSegmentFileName() {
return IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
"",
lastGeneration);
}
Get the segments_N filename in use by this segment infos. |
public static String getCurrentSegmentFileName(String[] files) throws IOException {
return IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
"",
getCurrentSegmentGeneration(files));
}
Get the filename of the current segments_N file
from a list of files. |
public static String getCurrentSegmentFileName(Directory directory) throws IOException {
return IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
"",
getCurrentSegmentGeneration(directory));
}
Get the filename of the current segments_N file
in the directory. |
public static long getCurrentSegmentGeneration(String[] files) {
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;
}
Get the generation (N) of the current segments_N file
from a list of files. |
public static long getCurrentSegmentGeneration(Directory directory) throws IOException {
try {
return getCurrentSegmentGeneration(directory.listAll());
} catch (NoSuchDirectoryException nsde) {
return -1;
}
}
Get the generation (N) of the current segments_N file
in the directory. |
public static int getDefaultGenFileRetryCount() {
return defaultGenFileRetryCount;
}
|
public static int getDefaultGenFileRetryPauseMsec() {
return defaultGenFileRetryPauseMsec;
}
|
public static int getDefaultGenLookahedCount() {
return defaultGenLookaheadCount;
}
|
public long getGeneration() {
return generation;
}
|
public static PrintStream getInfoStream() {
return infoStream;
}
|
public long getLastGeneration() {
return lastGeneration;
}
|
public String getNextSegmentFileName() {
long nextGeneration;
if (generation == -1) {
nextGeneration = 1;
} else {
nextGeneration = generation+1;
}
return IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
"",
nextGeneration);
}
Get the next segments_N filename that will be written. |
public Map<String, String> getUserData() {
return userData;
}
|
public long getVersion() {
return version;
}
version number when this SegmentInfos was generated. |
public boolean hasExternalSegments(Directory dir) {
final int numSegments = size();
for(int i=0;i< numSegments;i++)
if (info(i).dir != dir)
return true;
return false;
}
|
public final SegmentInfo info(int i) {
return get(i);
}
|
final void prepareCommit(Directory dir) throws IOException {
if (pendingSegnOutput != null)
throw new IllegalStateException("prepareCommit was already called");
write(dir);
}
Call this to start a commit. This writes the new
segments file, but writes an invalid checksum at the
end, so that it is not visible to readers. Once this
is called you must call #finishCommit to complete
the commit or #rollbackCommit to abort it. |
public SegmentInfos range(int first,
int last) {
SegmentInfos infos = new SegmentInfos();
infos.addAll(super.subList(first, last));
return infos;
}
Returns a new SegmentInfos containing the SegmentInfo
instances in the specified range first (inclusive) to
last (exclusive), so total number of segments returned
is last-first. |
public final void read(Directory directory) throws CorruptIndexException, IOException {
generation = lastGeneration = -1;
new FindSegmentsFile(directory) {
@Override
protected Object doBody(String segmentFileName) throws CorruptIndexException, IOException {
read(directory, segmentFileName);
return null;
}
}.run();
}
This version of read uses the retry logic (for lock-less
commits) to find the right segments file to load. |
public final void read(Directory directory,
String segmentFileName) throws CorruptIndexException, IOException {
boolean success = false;
// Clear any previous segments:
clear();
ChecksumIndexInput input = new ChecksumIndexInput(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
add(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
}
if (format < = FORMAT_USER_DATA) {
if (format < = FORMAT_DIAGNOSTICS) {
userData = input.readStringStringMap();
} else if (0 != input.readByte()) {
userData = Collections.singletonMap("userData", input.readString());
} else {
userData = Collections.< String,String >emptyMap();
}
} else {
userData = Collections.< String,String >emptyMap();
}
if (format < = FORMAT_CHECKSUM) {
final long checksumNow = input.getChecksum();
final long checksumThen = input.readLong();
if (checksumNow != checksumThen)
throw new CorruptIndexException("checksum mismatch in segments file");
}
success = true;
}
finally {
input.close();
if (!success) {
// Clear any segment infos we had loaded so we
// have a clean slate on retry:
clear();
}
}
}
Read a particular segmentFileName. Note that this may
throw an IOException if a commit is in process. |
public static Map<String, String> readCurrentUserData(Directory directory) throws CorruptIndexException, IOException {
SegmentInfos sis = new SegmentInfos();
sis.read(directory);
return sis.getUserData();
}
Returns userData from latest segments file |
public static long readCurrentVersion(Directory directory) throws CorruptIndexException, IOException {
// Fully read the segments file: this ensures that it's
// completely written so that if
// IndexWriter.prepareCommit has been called (but not
// yet commit), then the reader will still see itself as
// current:
SegmentInfos sis = new SegmentInfos();
sis.read(directory);
return sis.version;
}
Current version number from segments file. |
void replace(SegmentInfos other) {
clear();
addAll(other);
lastGeneration = other.lastGeneration;
}
Replaces all segments in this instance, but keeps
generation, version, counter so that future commits
remain write once. |
final void rollbackCommit(Directory dir) throws IOException {
if (pendingSegnOutput != null) {
try {
pendingSegnOutput.close();
} catch (Throwable t) {
// Suppress so we keep throwing the original exception
// in our caller
}
// Must carefully compute fileName from "generation"
// since lastGeneration isn't incremented:
try {
final String segmentFileName = IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
"",
generation);
dir.deleteFile(segmentFileName);
} catch (Throwable t) {
// Suppress so we keep throwing the original exception
// in our caller
}
pendingSegnOutput = null;
}
}
|
public synchronized String segString(Directory directory) {
StringBuilder buffer = new StringBuilder();
final int count = size();
for(int i = 0; i < count; i++) {
if (i > 0) {
buffer.append(' ');
}
final SegmentInfo info = info(i);
buffer.append(info.segString(directory));
if (info.dir != directory)
buffer.append("**");
}
return buffer.toString();
}
|
public static void setDefaultGenFileRetryCount(int count) {
defaultGenFileRetryCount = 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. |
public static void setDefaultGenFileRetryPauseMsec(int msec) {
defaultGenFileRetryPauseMsec = msec;
}
Advanced: set how many milliseconds to pause in between
attempts to load the segments.gen file. |
public static void setDefaultGenLookaheadCount(int count) {
defaultGenLookaheadCount = 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. |
public static void setInfoStream(PrintStream infoStream) {
SegmentInfos.infoStream = infoStream;
}
If non-null, information about retries when loading
the segments file will be printed to this. |
void setUserData(Map<String, String> data) {
if (data == null) {
userData = Collections.< String,String >emptyMap();
} else {
userData = data;
}
}
|
void updateGeneration(SegmentInfos other) {
lastGeneration = other.lastGeneration;
generation = other.generation;
version = other.version;
}
|