mirror of https://github.com/apache/lucene.git
file timestamp of segments file substituted by version
number in segments file git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@150135 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
dfaa46dd93
commit
e535a52af6
|
@ -114,6 +114,7 @@ public class FilterIndexReader extends IndexReader {
|
|||
|
||||
public FilterIndexReader(IndexReader in) {
|
||||
super(in.directory());
|
||||
segmentInfos = in.segmentInfos;
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,14 +83,14 @@ import org.apache.lucene.document.Field; // for javadoc
|
|||
public abstract class IndexReader {
|
||||
protected IndexReader(Directory directory) {
|
||||
this.directory = directory;
|
||||
segmentInfosAge = Long.MAX_VALUE;
|
||||
stale = false;
|
||||
segmentInfos = null;
|
||||
}
|
||||
|
||||
private Directory directory;
|
||||
private Lock writeLock;
|
||||
|
||||
//used to determine whether index has chaged since reader was opened
|
||||
private long segmentInfosAge;
|
||||
SegmentInfos segmentInfos = null;
|
||||
private boolean stale = false;
|
||||
|
||||
/** Returns an IndexReader reading the index in an FSDirectory in the named
|
||||
path. */
|
||||
|
@ -111,21 +111,16 @@ public abstract class IndexReader {
|
|||
directory.makeLock(IndexWriter.COMMIT_LOCK_NAME),
|
||||
IndexWriter.COMMIT_LOCK_TIMEOUT) {
|
||||
public Object doBody() throws IOException {
|
||||
IndexReader result = null;
|
||||
|
||||
SegmentInfos infos = new SegmentInfos();
|
||||
infos.read(directory);
|
||||
if (infos.size() == 1) { // index is optimized
|
||||
result = new SegmentReader(infos.info(0), true);
|
||||
return new SegmentReader(infos, infos.info(0), true);
|
||||
} else {
|
||||
SegmentReader[] readers = new SegmentReader[infos.size()];
|
||||
for (int i = 0; i < infos.size(); i++)
|
||||
readers[i] = new SegmentReader(infos.info(i), i==infos.size()-1);
|
||||
result = new SegmentsReader(directory, readers);
|
||||
readers[i] = new SegmentReader(infos, infos.info(i), i==infos.size()-1);
|
||||
return new SegmentsReader(infos, directory, readers);
|
||||
}
|
||||
|
||||
result.segmentInfosAge = lastModified(directory);
|
||||
return result;
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
|
@ -134,20 +129,89 @@ public abstract class IndexReader {
|
|||
/** Returns the directory this index resides in. */
|
||||
public Directory directory() { return directory; }
|
||||
|
||||
/** Returns the time the index in the named directory was last modified. */
|
||||
/**
|
||||
* Returns the time the index in the named directory was last modified.
|
||||
*
|
||||
* <p>Synchronization of IndexReader and IndexWriter instances is
|
||||
* no longer done via time stamps of the segments file since the time resolution
|
||||
* depends on the hardware platform. Instead, a version number is maintained
|
||||
* within the segments file, which is incremented everytime when the index is
|
||||
* changed.</p>
|
||||
*
|
||||
* @deprecated Replaced by {@link #getCurrentVersion(String)}
|
||||
* */
|
||||
public static long lastModified(String directory) throws IOException {
|
||||
return lastModified(new File(directory));
|
||||
}
|
||||
|
||||
/** Returns the time the index in the named directory was last modified. */
|
||||
/**
|
||||
* Returns the time the index in the named directory was last modified.
|
||||
*
|
||||
* <p>Synchronization of IndexReader and IndexWriter instances is
|
||||
* no longer done via time stamps of the segments file since the time resolution
|
||||
* depends on the hardware platform. Instead, a version number is maintained
|
||||
* within the segments file, which is incremented everytime when the index is
|
||||
* changed.</p>
|
||||
*
|
||||
* @deprecated Replaced by {@link #getCurrentVersion(File)}
|
||||
* */
|
||||
public static long lastModified(File directory) throws IOException {
|
||||
return FSDirectory.fileModified(directory, "segments");
|
||||
}
|
||||
|
||||
/** Returns the time the index in this directory was last modified. */
|
||||
/**
|
||||
* Returns the time the index in the named directory was last modified.
|
||||
*
|
||||
* <p>Synchronization of IndexReader and IndexWriter instances is
|
||||
* no longer done via time stamps of the segments file since the time resolution
|
||||
* depends on the hardware platform. Instead, a version number is maintained
|
||||
* within the segments file, which is incremented everytime when the index is
|
||||
* changed.</p>
|
||||
*
|
||||
* @deprecated Replaced by {@link #getCurrentVersion(Directory)}
|
||||
* */
|
||||
public static long lastModified(Directory directory) throws IOException {
|
||||
return directory.fileModified("segments");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads version number from segments files. The version number counts the
|
||||
* number of changes of the index.
|
||||
*
|
||||
* @param directory where the index resides.
|
||||
* @return version number.
|
||||
* @throws IOException if segments file cannot be read
|
||||
*/
|
||||
public static long getCurrentVersion(String directory) throws IOException {
|
||||
return getCurrentVersion(new File(directory));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads version number from segments files. The version number counts the
|
||||
* number of changes of the index.
|
||||
*
|
||||
* @param directory where the index resides.
|
||||
* @return version number.
|
||||
* @throws IOException if segments file cannot be read
|
||||
*/
|
||||
public static long getCurrentVersion(File directory) throws IOException {
|
||||
Directory dir = FSDirectory.getDirectory(directory, false);
|
||||
long version = getCurrentVersion(dir);
|
||||
dir.close();
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads version number from segments files. The version number counts the
|
||||
* number of changes of the index.
|
||||
*
|
||||
* @param directory where the index resides.
|
||||
* @return version number.
|
||||
* @throws IOException if segments file cannot be read.
|
||||
*/
|
||||
public static long getCurrentVersion(Directory directory) throws IOException {
|
||||
return SegmentInfos.readCurrentVersion(directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if an index exists at the specified directory.
|
||||
|
@ -274,6 +338,9 @@ public abstract class IndexReader {
|
|||
this will be corrected eventually as the index is further modified.
|
||||
*/
|
||||
public final synchronized void delete(int docNum) throws IOException {
|
||||
if(stale)
|
||||
throw new IOException("IndexReader out of date and no longer valid for deletion");
|
||||
|
||||
if (writeLock == null) {
|
||||
Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME);
|
||||
if (!writeLock.obtain(IndexWriter.WRITE_LOCK_TIMEOUT)) // obtain write lock
|
||||
|
@ -282,11 +349,11 @@ public abstract class IndexReader {
|
|||
|
||||
// we have to check whether index has changed since this reader was opened.
|
||||
// if so, this reader is no longer valid for deletion
|
||||
if(lastModified(directory) > segmentInfosAge){
|
||||
if(segmentInfos != null && SegmentInfos.readCurrentVersion(directory) > segmentInfos.getVersion()){
|
||||
stale = true;
|
||||
this.writeLock.release();
|
||||
this.writeLock = null;
|
||||
throw new IOException(
|
||||
"IndexReader out of date and no longer valid for deletion");
|
||||
throw new IOException("IndexReader out of date and no longer valid for deletion");
|
||||
}
|
||||
}
|
||||
doDelete(docNum);
|
||||
|
|
|
@ -61,22 +61,28 @@ import org.apache.lucene.store.InputStream;
|
|||
import org.apache.lucene.store.OutputStream;
|
||||
|
||||
final class SegmentInfos extends Vector {
|
||||
public int counter = 0; // used to name new segments
|
||||
public int counter = 0; // used to name new segments
|
||||
private long version = 0; //counts how often the index has been changed by adding or deleting docs
|
||||
|
||||
public final SegmentInfo info(int i) {
|
||||
return (SegmentInfo)elementAt(i);
|
||||
return (SegmentInfo) elementAt(i);
|
||||
}
|
||||
|
||||
public final void read(Directory directory) throws IOException {
|
||||
InputStream input = directory.openFile("segments");
|
||||
try {
|
||||
counter = input.readInt(); // read counter
|
||||
counter = input.readInt(); // read counter
|
||||
for (int i = input.readInt(); i > 0; i--) { // read segmentInfos
|
||||
SegmentInfo si = new SegmentInfo(input.readString(), input.readInt(),
|
||||
directory);
|
||||
SegmentInfo si =
|
||||
new SegmentInfo(input.readString(), input.readInt(), directory);
|
||||
addElement(si);
|
||||
}
|
||||
} finally {
|
||||
if (input.getFilePointer() >= input.length())
|
||||
version = 0; // old file format without version number
|
||||
else
|
||||
version = input.readLong(); // read version
|
||||
}
|
||||
finally {
|
||||
input.close();
|
||||
}
|
||||
}
|
||||
|
@ -84,18 +90,41 @@ final class SegmentInfos extends Vector {
|
|||
public final void write(Directory directory) throws IOException {
|
||||
OutputStream output = directory.createFile("segments.new");
|
||||
try {
|
||||
output.writeInt(counter); // write counter
|
||||
output.writeInt(size()); // write infos
|
||||
output.writeInt(counter); // write counter
|
||||
output.writeInt(size()); // write infos
|
||||
for (int i = 0; i < size(); i++) {
|
||||
SegmentInfo si = info(i);
|
||||
output.writeString(si.name);
|
||||
output.writeInt(si.docCount);
|
||||
}
|
||||
} finally {
|
||||
output.writeLong(++version); // every write changes the index
|
||||
}
|
||||
finally {
|
||||
output.close();
|
||||
}
|
||||
|
||||
// install new segment info
|
||||
directory.renameFile("segments.new", "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)
|
||||
throws IOException {
|
||||
|
||||
// We cannot be sure whether the segments file is in the old format or the new one.
|
||||
// Therefore we have to read the whole file and cannot simple seek to the version entry.
|
||||
|
||||
SegmentInfos sis = new SegmentInfos();
|
||||
sis.read(directory);
|
||||
return sis.getVersion();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,10 +98,11 @@ final class SegmentReader extends IndexReader {
|
|||
}
|
||||
private Hashtable norms = new Hashtable();
|
||||
|
||||
SegmentReader(SegmentInfo si, boolean closeDir)
|
||||
SegmentReader(SegmentInfos sis, SegmentInfo si, boolean closeDir)
|
||||
throws IOException {
|
||||
this(si);
|
||||
closeDirectory = closeDir;
|
||||
segmentInfos = sis;
|
||||
}
|
||||
|
||||
SegmentReader(SegmentInfo si)
|
||||
|
@ -141,7 +142,10 @@ final class SegmentReader extends IndexReader {
|
|||
public Object doBody() throws IOException {
|
||||
deletedDocs.write(directory(), segment + ".tmp");
|
||||
directory().renameFile(segment + ".tmp", segment + ".del");
|
||||
directory().touchFile("segments");
|
||||
if(segmentInfos != null)
|
||||
segmentInfos.write(directory());
|
||||
else
|
||||
directory().touchFile("segments");
|
||||
return null;
|
||||
}
|
||||
}.run();
|
||||
|
|
|
@ -77,9 +77,10 @@ final class SegmentsReader extends IndexReader
|
|||
private int maxDoc = 0;
|
||||
private int numDocs = -1;
|
||||
private boolean hasDeletions = false;
|
||||
|
||||
SegmentsReader(Directory directory, SegmentReader[] r) throws IOException {
|
||||
|
||||
SegmentsReader(SegmentInfos sis, Directory directory, SegmentReader[] r) throws IOException {
|
||||
super(directory);
|
||||
segmentInfos = sis;
|
||||
readers = r;
|
||||
starts = new int[readers.length + 1]; // build starts array
|
||||
for (int i = 0; i < readers.length; i++) {
|
||||
|
|
Loading…
Reference in New Issue