提交 26984fbb authored 作者: andrei's avatar andrei

now some efficiencies in free space accounting

上级 8e520ee6
......@@ -54,12 +54,12 @@ public class FileStore {
/**
* The file name.
*/
protected String fileName;
private String fileName;
/**
* Whether this store is read-only.
*/
protected boolean readOnly;
private boolean readOnly;
/**
* The file size (cached).
......@@ -69,17 +69,17 @@ public class FileStore {
/**
* The file.
*/
protected FileChannel file;
private FileChannel file;
/**
* The encrypted file (if encryption is used).
*/
protected FileChannel encryptedFile;
private FileChannel encryptedFile;
/**
* The file lock.
*/
protected FileLock fileLock;
private FileLock fileLock;
@Override
public String toString() {
......@@ -337,6 +337,16 @@ public class FileStore {
return freeSpace.allocate(length);
}
/**
* Calculate starting position of the prospective allocation.
*
* @param length the number of bytes to allocate
* @return the start position in bytes
*/
public long predictAllocation(int length) {
return freeSpace.predictAllocation(length);
}
/**
* Mark the space as free.
*
......
......@@ -94,6 +94,20 @@ public class FreeSpaceBitSet {
* @return the start position in bytes
*/
public long allocate(int length) {
return allocate(length, true);
}
/**
* Calculate starting position of the prospective allocation.
*
* @param length the number of bytes to allocate
* @return the start position in bytes
*/
public long predictAllocation(int length) {
return allocate(length, false);
}
private long allocate(int length, boolean allocate) {
int blocks = getBlockCount(length);
for (int i = 0;;) {
int start = set.nextClearBit(i);
......@@ -101,7 +115,9 @@ public class FreeSpaceBitSet {
if (end < 0 || end - start >= blocks) {
assert set.nextSetBit(start) == -1 || set.nextSetBit(start) >= start + blocks :
"Double alloc: " + Integer.toHexString(start) + "/" + Integer.toHexString(blocks) + " " + this;
if (allocate) {
set.set(start, start + blocks);
}
return getPos(start);
}
i = end;
......@@ -155,16 +171,11 @@ public class FreeSpaceBitSet {
* @return the fill rate (0 - 100)
*/
public int getFillRate() {
int total = set.length(), count = 0;
for (int i = 0; i < total; i++) {
if (set.get(i)) {
count++;
}
}
if (count == 0) {
int cardinality = set.cardinality();
if (cardinality == 0) {
return 0;
}
return Math.max(1, (int) (100L * count / total));
return Math.max(1, (int)(100L * cardinality / set.length()));
}
/**
......
......@@ -1151,11 +1151,7 @@ public final class MVStore {
c.metaRootPos = metaRoot.getPos();
// calculate and set the likely next position
if (reuseSpace) {
int predictBlocks = c.len;
long predictedNextStart = fileStore.allocate(
predictBlocks * BLOCK_SIZE);
fileStore.free(predictedNextStart, predictBlocks * BLOCK_SIZE);
c.next = predictedNextStart / BLOCK_SIZE;
c.next = fileStore.predictAllocation(c.len * BLOCK_SIZE) / BLOCK_SIZE;
} else {
// just after this chunk
c.next = 0;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论