提交 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 { ...@@ -90,6 +90,13 @@ public class Chunk {
*/ */
public long time; 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. * The last used map id.
*/ */
...@@ -179,6 +186,7 @@ public class Chunk { ...@@ -179,6 +186,7 @@ public class Chunk {
c.maxLenLive = DataUtils.readHexLong(map, "liveMax", c.maxLen); c.maxLenLive = DataUtils.readHexLong(map, "liveMax", c.maxLen);
c.metaRootPos = DataUtils.readHexLong(map, "root", 0); c.metaRootPos = DataUtils.readHexLong(map, "root", 0);
c.time = DataUtils.readHexLong(map, "time", 0); c.time = DataUtils.readHexLong(map, "time", 0);
c.unused = DataUtils.readHexLong(map, "unused", 0);
c.version = DataUtils.readHexLong(map, "version", id); c.version = DataUtils.readHexLong(map, "version", id);
c.next = DataUtils.readHexLong(map, "next", 0); c.next = DataUtils.readHexLong(map, "next", 0);
return c; return c;
...@@ -232,6 +240,9 @@ public class Chunk { ...@@ -232,6 +240,9 @@ public class Chunk {
DataUtils.appendMap(buff, "pages", pageCount); DataUtils.appendMap(buff, "pages", pageCount);
DataUtils.appendMap(buff, "root", metaRootPos); DataUtils.appendMap(buff, "root", metaRootPos);
DataUtils.appendMap(buff, "time", time); DataUtils.appendMap(buff, "time", time);
if (unused != 0) {
DataUtils.appendMap(buff, "unused", unused);
}
DataUtils.appendMap(buff, "version", version); DataUtils.appendMap(buff, "version", version);
return buff.toString(); return buff.toString();
} }
......
...@@ -955,9 +955,9 @@ public class MVStore { ...@@ -955,9 +955,9 @@ public class MVStore {
lastCommitTime = time; lastCommitTime = time;
retainChunk = null; retainChunk = null;
// the last chunk was not stored before and needs to be set now (it's // the metadata of the last chunk was not stored so far, and needs to be
// better not to update right after storing, because that would modify // set now (it's better not to update right after storing, because that
// the meta map again) // would modify the meta map again)
int lastChunkId; int lastChunkId;
if (lastChunk == null) { if (lastChunk == null) {
lastChunkId = 0; lastChunkId = 0;
...@@ -1194,6 +1194,9 @@ public class MVStore { ...@@ -1194,6 +1194,9 @@ public class MVStore {
if (c.time + retentionTime > time) { if (c.time + retentionTime > time) {
return false; return false;
} }
if (c.unused != 0 && c.unused + retentionTime / 2 > time) {
return false;
}
Chunk r = retainChunk; Chunk r = retainChunk;
if (r != null && c.version > r.version) { if (r != null && c.version > r.version) {
return false; return false;
...@@ -1256,13 +1259,16 @@ public class MVStore { ...@@ -1256,13 +1259,16 @@ public class MVStore {
} }
for (Chunk c : modified) { for (Chunk c : modified) {
if (c.maxLenLive == 0) { if (c.maxLenLive == 0) {
if (c.unused == 0) {
c.unused = getTime();
}
if (canOverwriteChunk(c, time)) { if (canOverwriteChunk(c, time)) {
removedChunks.add(c); removedChunks.add(c);
chunks.remove(c.id); chunks.remove(c.id);
meta.remove(Chunk.getMetaKey(c.id)); meta.remove(Chunk.getMetaKey(c.id));
} else { } else {
meta.put(Chunk.getMetaKey(c.id), c.asString()); 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); registerFreePage(storeVersion + 1, c.id, 0, 0);
} }
} else { } else {
...@@ -1611,6 +1617,9 @@ public class MVStore { ...@@ -1611,6 +1617,9 @@ public class MVStore {
ArrayList<Chunk> old = New.arrayList(); ArrayList<Chunk> old = New.arrayList();
Chunk last = chunks.get(lastChunk.id); Chunk last = chunks.get(lastChunk.id);
for (Chunk c : chunks.values()) { 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)) { if (canOverwriteChunk(c, time)) {
long age = last.version - c.version + 1; long age = last.version - c.version + 1;
c.collectPriority = (int) (c.getFillRate() * 1000 / age); c.collectPriority = (int) (c.getFillRate() * 1000 / age);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论