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

now some efficiencies in free space accounting

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