提交 5175b741 authored 作者: Thomas Mueller's avatar Thomas Mueller

MVStore: deal with the case that data was moved to a new chunk (work in progress)

上级 55510da7
......@@ -90,6 +90,13 @@ public class Chunk {
*/
public long time;
/**
* When this chunk was no longer needed, in milliseconds after the store was
* created. After this, the chunk is kept alive for at least half the
* retention time (in case it is referenced in older versions).
*/
public long unused;
/**
* The last used map id.
*/
......@@ -179,6 +186,7 @@ public class Chunk {
c.maxLenLive = DataUtils.readHexLong(map, "liveMax", c.maxLen);
c.metaRootPos = DataUtils.readHexLong(map, "root", 0);
c.time = DataUtils.readHexLong(map, "time", 0);
c.unused = DataUtils.readHexLong(map, "unused", 0);
c.version = DataUtils.readHexLong(map, "version", id);
c.next = DataUtils.readHexLong(map, "next", 0);
return c;
......@@ -232,6 +240,9 @@ public class Chunk {
DataUtils.appendMap(buff, "pages", pageCount);
DataUtils.appendMap(buff, "root", metaRootPos);
DataUtils.appendMap(buff, "time", time);
if (unused != 0) {
DataUtils.appendMap(buff, "unused", unused);
}
DataUtils.appendMap(buff, "version", version);
return buff.toString();
}
......
......@@ -955,9 +955,9 @@ public class MVStore {
lastCommitTime = time;
retainChunk = null;
// the last chunk was not stored before and needs to be set now (it's
// better not to update right after storing, because that would modify
// the meta map again)
// the metadata of the last chunk was not stored so far, and needs to be
// set now (it's better not to update right after storing, because that
// would modify the meta map again)
int lastChunkId;
if (lastChunk == null) {
lastChunkId = 0;
......@@ -1194,6 +1194,9 @@ public class MVStore {
if (c.time + retentionTime > time) {
return false;
}
if (c.unused != 0 && c.unused + retentionTime / 2 > time) {
return false;
}
Chunk r = retainChunk;
if (r != null && c.version > r.version) {
return false;
......@@ -1256,13 +1259,16 @@ public class MVStore {
}
for (Chunk c : modified) {
if (c.maxLenLive == 0) {
if (c.unused == 0) {
c.unused = getTime();
}
if (canOverwriteChunk(c, time)) {
removedChunks.add(c);
chunks.remove(c.id);
meta.remove(Chunk.getMetaKey(c.id));
} else {
meta.put(Chunk.getMetaKey(c.id), c.asString());
// remove this chunk in the next save operation
// possibly remove this chunk in the next save operation
registerFreePage(storeVersion + 1, c.id, 0, 0);
}
} else {
......@@ -1611,6 +1617,9 @@ public class MVStore {
ArrayList<Chunk> old = New.arrayList();
Chunk last = chunks.get(lastChunk.id);
for (Chunk c : chunks.values()) {
// only look at chunk older than the retention time
// (it's possible to compact chunks earlier, but right
// now we don't do that)
if (canOverwriteChunk(c, time)) {
long age = last.version - c.version + 1;
c.collectPriority = (int) (c.getFillRate() * 1000 / age);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论