提交 ead2f7ad authored 作者: Thomas Mueller's avatar Thomas Mueller

Improved order of file operations

上级 422c8dc8
......@@ -138,7 +138,6 @@ public class FileStore {
file = new FilePathEncrypt.FileEncrypt(fileName, key, file);
}
file = FilePathCache.wrap(file);
fileSize = file.size();
try {
if (readOnly) {
fileLock = file.tryLock(0, Long.MAX_VALUE, true);
......@@ -153,6 +152,7 @@ public class FileStore {
throw DataUtils.newIllegalStateException(
DataUtils.ERROR_FILE_LOCKED, "The file is locked: {0}", fileName);
}
fileSize = file.size();
} catch (IOException e) {
throw DataUtils.newIllegalStateException(
DataUtils.ERROR_READING_FAILED,
......
......@@ -406,6 +406,14 @@ public class MVTable extends TableBase {
}
if (index.needRebuild()) {
try {
// TODO Speed up creating an index, for example as follows: Read
// up to about 1 MB of entries in memory, sort them (detect
// duplicates here), write to a new map (in sorted order);
// repeat (using a new map for every block of 1 MB) until all
// record are read. Merge all maps to the target (using merge
// sort; duplicates are detected in the target). This is similar
// to a LSM tree. For randomly ordered data, this should use
// much less write operations than the current algorithm.
Index scan = getScanIndex(session);
long remaining = scan.getRowCount(session);
long total = remaining;
......
......@@ -245,16 +245,15 @@ public class FilePathDisk extends FilePath {
@Override
public void createDirectory() {
File f = new File(name);
if (f.exists()) {
if (f.isDirectory()) {
return;
}
throw DbException.get(ErrorCode.FILE_CREATION_FAILED_1, name + " (a file with this name already exists)");
}
File dir = new File(name);
for (int i = 0; i < SysProperties.MAX_FILE_RETRY; i++) {
if ((dir.exists() && dir.isDirectory()) || dir.mkdir()) {
if (dir.exists()) {
if (dir.isDirectory()) {
return;
}
throw DbException.get(ErrorCode.FILE_CREATION_FAILED_1,
name + " (a file with this name already exists)");
} else if (dir.mkdir()) {
return;
}
wait(i);
......
......@@ -157,8 +157,6 @@ public class FilePathEncrypt extends FilePathWrapper {
private final FileChannel base;
private final XTS xts;
/**
* The current position within the file, from a user perspective.
*/
......@@ -170,10 +168,24 @@ public class FilePathEncrypt extends FilePathWrapper {
private long size;
private final String name;
private XTS xts;
private byte[] encryptionKey;
public FileEncrypt(String name, byte[] encryptionKey, FileChannel base) throws IOException {
public FileEncrypt(String name, byte[] encryptionKey, FileChannel base) {
// don't do any read or write operations here, because they could
// fail if the file is locked, and we want to give the caller a
// chance to lock the file first
this.name = name;
this.base = base;
this.encryptionKey = encryptionKey;
}
private void init() throws IOException {
if (xts != null) {
return;
}
this.size = base.size() - HEADER_LENGTH;
boolean newFile = size < 0;
byte[] salt;
......@@ -192,6 +204,7 @@ public class FilePathEncrypt extends FilePathWrapper {
}
AES cipher = new AES();
cipher.setKey(SHA256.getPBKDF2(encryptionKey, salt, HASH_ITERATIONS, 16));
encryptionKey = null;
xts = new XTS(cipher);
}
......@@ -226,6 +239,7 @@ public class FilePathEncrypt extends FilePathWrapper {
if (len == 0) {
return 0;
}
init();
len = (int) Math.min(len, size - position);
if (position >= size) {
return -1;
......@@ -274,6 +288,7 @@ public class FilePathEncrypt extends FilePathWrapper {
@Override
public int write(ByteBuffer src, long position) throws IOException {
init();
int len = src.remaining();
if ((position & BLOCK_SIZE_MASK) != 0 ||
(len & BLOCK_SIZE_MASK) != 0) {
......@@ -343,11 +358,13 @@ public class FilePathEncrypt extends FilePathWrapper {
@Override
public long size() throws IOException {
init();
return size;
}
@Override
public FileChannel truncate(long newSize) throws IOException {
init();
if (newSize > size) {
return this;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论