mirror of https://github.com/apache/lucene.git
LUCENE-705: pre-set the CFS file length before building it
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@615160 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f99e4e7260
commit
674eae39ec
|
@ -20,6 +20,13 @@ New features
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
|
|
||||||
|
1. LUCENE-705: When building a compound file, use
|
||||||
|
RandomAccessFile.setLength() to tell the OS/filesystem to
|
||||||
|
pre-allocate space for the file. This may improve fragmentation
|
||||||
|
in how the CFS file is stored, and allows us to detect an upcoming
|
||||||
|
disk full situation before actually filling up the disk. (Mike
|
||||||
|
McCandless)
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
|
|
||||||
Build
|
Build
|
||||||
|
|
|
@ -156,13 +156,24 @@ final class CompoundFileWriter {
|
||||||
// Remember the positions of directory entries so that we can
|
// Remember the positions of directory entries so that we can
|
||||||
// adjust the offsets later
|
// adjust the offsets later
|
||||||
Iterator it = entries.iterator();
|
Iterator it = entries.iterator();
|
||||||
|
long totalSize = 0;
|
||||||
while(it.hasNext()) {
|
while(it.hasNext()) {
|
||||||
FileEntry fe = (FileEntry) it.next();
|
FileEntry fe = (FileEntry) it.next();
|
||||||
fe.directoryOffset = os.getFilePointer();
|
fe.directoryOffset = os.getFilePointer();
|
||||||
os.writeLong(0); // for now
|
os.writeLong(0); // for now
|
||||||
os.writeString(fe.file);
|
os.writeString(fe.file);
|
||||||
|
totalSize += directory.fileLength(fe.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pre-allocate size of file as optimization --
|
||||||
|
// this can potentially help IO performance as
|
||||||
|
// we write the file and also later during
|
||||||
|
// searching. It also uncovers a disk-full
|
||||||
|
// situation earlier and hopefully without
|
||||||
|
// actually filling disk to 100%:
|
||||||
|
final long finalLength = totalSize+os.getFilePointer();
|
||||||
|
os.setLength(finalLength);
|
||||||
|
|
||||||
// Open the files and copy their data into the stream.
|
// Open the files and copy their data into the stream.
|
||||||
// Remember the locations of each file's data section.
|
// Remember the locations of each file's data section.
|
||||||
byte buffer[] = new byte[16384];
|
byte buffer[] = new byte[16384];
|
||||||
|
@ -181,6 +192,8 @@ final class CompoundFileWriter {
|
||||||
os.writeLong(fe.dataOffset);
|
os.writeLong(fe.dataOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert finalLength == os.length();
|
||||||
|
|
||||||
// Close the output stream. Set the os to null before trying to
|
// Close the output stream. Set the os to null before trying to
|
||||||
// close so that if an exception occurs during the close, the
|
// close so that if an exception occurs during the close, the
|
||||||
// finally clause below will not attempt to close the stream
|
// finally clause below will not attempt to close the stream
|
||||||
|
|
|
@ -615,6 +615,8 @@ public class FSDirectory extends Directory {
|
||||||
public long length() throws IOException {
|
public long length() throws IOException {
|
||||||
return file.length();
|
return file.length();
|
||||||
}
|
}
|
||||||
|
public void setLength(long length) throws IOException {
|
||||||
|
file.setLength(length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,5 +189,15 @@ public abstract class IndexOutput {
|
||||||
/** The number of bytes in the file. */
|
/** The number of bytes in the file. */
|
||||||
public abstract long length() throws IOException;
|
public abstract long length() throws IOException;
|
||||||
|
|
||||||
|
/** Set the file length. By default, this method does
|
||||||
|
* nothing (it's optional for a Directory to implement
|
||||||
|
* it). But, certain Directory implementations (for
|
||||||
|
* example @see FSDirectory) can use this to inform the
|
||||||
|
* underlying IO system to pre-allocate the file to the
|
||||||
|
* specified size. If the length is longer than the
|
||||||
|
* current file length, the bytes added to the file are
|
||||||
|
* undefined. Otherwise the file is truncated.
|
||||||
|
* @param length file length
|
||||||
|
*/
|
||||||
|
public void setLength(long length) throws IOException {};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue