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

MVStore: tool to quickly compact a store.

上级 5da4e45c
...@@ -13,7 +13,7 @@ public class CursorPos { ...@@ -13,7 +13,7 @@ public class CursorPos {
/** /**
* The current page. * The current page.
*/ */
public final Page page; public Page page;
/** /**
* The current index. * The current index.
......
...@@ -995,7 +995,7 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -995,7 +995,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
return; return;
} }
Page last = oldRoots.peekLast(); Page last = oldRoots.peekLast();
// TODO why is this? // TODO why is this? (maybe not needed)
; ;
oldest--; oldest--;
while (true) { while (true) {
...@@ -1257,23 +1257,32 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -1257,23 +1257,32 @@ public class MVMap<K, V> extends AbstractMap<K, V>
* @param sourceMap the source map * @param sourceMap the source map
*/ */
void copyFrom(MVMap<K, V> sourceMap) { void copyFrom(MVMap<K, V> sourceMap) {
; // TODO work in progress beforeWrite();
root = copy(sourceMap.root, null); newRoot(copy(sourceMap.root, null));
afterWrite();
} }
private Page copy(Page source, CursorPos parent) { private Page copy(Page source, CursorPos parent) {
Page target = Page.create(this, writeVersion, source); Page target = Page.create(this, writeVersion, source);
for (CursorPos p = parent; p != null; p = p.parent) { if (target.isLeaf()) {
p.page.setChild(p.index, target); Page child = target;
} for (CursorPos p = parent; p != null; p = p.parent) {
if (!target.isLeaf()) { p.page.setChild(p.index, child);
p.page = copyOnWrite(p.page, writeVersion);
child = p.page;
if (p.parent == null) {
newRoot(p.page);
afterWrite();
beforeWrite();
}
}
} else {
CursorPos pos = new CursorPos(target, 0, parent); CursorPos pos = new CursorPos(target, 0, parent);
target = copyOnWrite(target, writeVersion);
for (int i = 0; i < target.getChildPageCount(); i++) { for (int i = 0; i < target.getChildPageCount(); i++) {
Page sourceChild = source.getChildPage(i);
pos.index = i; pos.index = i;
copy(sourceChild, pos); copy(source.getChildPage(i), pos);
} }
target = pos.page;
} }
return target; return target;
} }
......
...@@ -45,6 +45,12 @@ public class MVStoreTool { ...@@ -45,6 +45,12 @@ public class MVStoreTool {
} else if ("-info".equals(args[i])) { } else if ("-info".equals(args[i])) {
String fileName = args[++i]; String fileName = args[++i];
info(fileName, new PrintWriter(System.out)); info(fileName, new PrintWriter(System.out));
} else if ("-compact".equals(args[i])) {
String fileName = args[++i];
compact(fileName, false);
} else if ("-compress".equals(args[i])) {
String fileName = args[++i];
compact(fileName, true);
} }
} }
} }
...@@ -301,9 +307,10 @@ public class MVStoreTool { ...@@ -301,9 +307,10 @@ public class MVStoreTool {
* there. * there.
* *
* @param fileName the file name * @param fileName the file name
* @param compress whether to compress the data
*/ */
public static void compress(String fileName) { public static void compact(String fileName, boolean compress) {
compress(fileName, fileName + ".new"); compact(fileName, fileName + ".new", compress);
FileUtils.moveTo(fileName, fileName + ".old"); FileUtils.moveTo(fileName, fileName + ".old");
FileUtils.moveTo(fileName, fileName); FileUtils.moveTo(fileName, fileName);
FileUtils.delete(fileName + ".old"); FileUtils.delete(fileName + ".old");
...@@ -315,12 +322,18 @@ public class MVStoreTool { ...@@ -315,12 +322,18 @@ public class MVStoreTool {
* @param sourceFileName the name of the source store * @param sourceFileName the name of the source store
* @param targetFileName the name of the target store * @param targetFileName the name of the target store
*/ */
public static void compress(String sourceFileName, String targetFileName) { public static void compact(String sourceFileName, String targetFileName, boolean compress) {
MVStore source = new MVStore.Builder(). MVStore source = new MVStore.Builder().
fileName(sourceFileName).readOnly().open(); fileName(sourceFileName).
readOnly().
open();
FileUtils.delete(targetFileName); FileUtils.delete(targetFileName);
MVStore target = new MVStore.Builder(). MVStore.Builder b = new MVStore.Builder().
fileName(targetFileName).open(); fileName(targetFileName);
if (compress) {
b.compress();
}
MVStore target = b.open();
MVMap<String, String> sourceMeta = source.getMetaMap(); MVMap<String, String> sourceMeta = source.getMetaMap();
MVMap<String, String> targetMeta = target.getMetaMap(); MVMap<String, String> targetMeta = target.getMetaMap();
for (Entry<String, String> m : sourceMeta.entrySet()) { for (Entry<String, String> m : sourceMeta.entrySet()) {
...@@ -345,7 +358,6 @@ public class MVStoreTool { ...@@ -345,7 +358,6 @@ public class MVStoreTool {
MVMap<Object, Object> sourceMap = source.openMap(mapName, mp); MVMap<Object, Object> sourceMap = source.openMap(mapName, mp);
MVMap<Object, Object> targetMap = target.openMap(mapName, mp); MVMap<Object, Object> targetMap = target.openMap(mapName, mp);
targetMap.copyFrom(sourceMap); targetMap.copyFrom(sourceMap);
target.commit();
} }
target.close(); target.close();
source.close(); source.close();
...@@ -364,7 +376,7 @@ public class MVStoreTool { ...@@ -364,7 +376,7 @@ public class MVStoreTool {
@Override @Override
public int getMemory(Object obj) { public int getMemory(Object obj) {
return obj == null ? 0 : ((byte[]) obj).length; return obj == null ? 0 : ((byte[]) obj).length * 8;
} }
@Override @Override
......
...@@ -304,7 +304,11 @@ public class WriteBuffer { ...@@ -304,7 +304,11 @@ public class WriteBuffer {
// grow at least 50% of the current size // grow at least 50% of the current size
grow = Math.max(temp.capacity() / 2, grow); grow = Math.max(temp.capacity() / 2, grow);
int newCapacity = temp.capacity() + grow; int newCapacity = temp.capacity() + grow;
buff = ByteBuffer.allocate(newCapacity); try {
buff = ByteBuffer.allocate(newCapacity);
} catch (OutOfMemoryError e) {
throw new OutOfMemoryError("Capacity: " + newCapacity);
}
temp.flip(); temp.flip();
buff.put(temp); buff.put(temp);
if (newCapacity <= MAX_REUSE_CAPACITY) { if (newCapacity <= MAX_REUSE_CAPACITY) {
......
...@@ -317,9 +317,9 @@ public class MVTableEngine implements TableEngine { ...@@ -317,9 +317,9 @@ public class MVTableEngine implements TableEngine {
store.compactMoveChunks(); store.compactMoveChunks();
} else { } else {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
while (store.compact(99, 16 * 1024 * 1024)) { while (store.compact(95, 16 * 1024 * 1024)) {
store.sync(); store.sync();
store.compactMoveChunks(16 * 1024 * 1024); store.compactMoveChunks(95, 16 * 1024 * 1024);
long time = System.currentTimeMillis() - start; long time = System.currentTimeMillis() - start;
if (time > maxCompactTime) { if (time > maxCompactTime) {
break; break;
...@@ -341,8 +341,8 @@ public class MVTableEngine implements TableEngine { ...@@ -341,8 +341,8 @@ public class MVTableEngine implements TableEngine {
if (!store.getFileStore().isReadOnly()) { if (!store.getFileStore().isReadOnly()) {
transactionStore.close(); transactionStore.close();
if (maxCompactTime > 0) { if (maxCompactTime > 0) {
store.compact(99, 1 * 1024 * 1024); store.compact(95, 1024 * 1024);
store.compactMoveChunks(1 * 1024 * 1024); store.compactMoveChunks(95, 1024 * 1024);
} }
} }
store.close(); store.close();
......
...@@ -32,12 +32,12 @@ public class TestMVStoreTool extends TestBase { ...@@ -32,12 +32,12 @@ public class TestMVStoreTool extends TestBase {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
; // TODO work in progress testCompress();
// testCompress();
} }
private void testCompress() { private void testCompress() {
String fileName = getBaseDir() + "/testCompress.h3"; String fileName = getBaseDir() + "/testCompress.h3";
FileUtils.createDirectory(getBaseDir());
FileUtils.delete(fileName); FileUtils.delete(fileName);
// store with a very small page size, to make sure // store with a very small page size, to make sure
// there are many leaf pages // there are many leaf pages
...@@ -51,15 +51,26 @@ public class TestMVStoreTool extends TestBase { ...@@ -51,15 +51,26 @@ public class TestMVStoreTool extends TestBase {
s.commit(); s.commit();
} }
} }
for (int i = 0; i < 10; i++) {
map = s.openMap("data" + i);
for (int j = 0; j < i * i; j++) {
map.put(j, j * 10);
}
s.commit();
}
s.close(); s.close();
// MVStoreTool.dump(fileName); MVStoreTool.compact(fileName, fileName + ".new", false);
// MVStoreTool.dump(fileName + ".new"); MVStoreTool.compact(fileName, fileName + ".new.compress", true);
MVStoreTool.compress(fileName, fileName + ".new");
MVStore s1 = new MVStore.Builder(). MVStore s1 = new MVStore.Builder().
fileName(fileName).readOnly().open(); fileName(fileName).readOnly().open();
MVStore s2 = new MVStore.Builder(). MVStore s2 = new MVStore.Builder().
fileName(fileName + ".new").readOnly().open(); fileName(fileName + ".new").readOnly().open();
MVStore s3 = new MVStore.Builder().
fileName(fileName + ".new.compress").readOnly().open();
assertEquals(s1, s2); assertEquals(s1, s2);
assertEquals(s1, s3);
assertTrue(FileUtils.size(fileName + ".new") < FileUtils.size(fileName));
assertTrue(FileUtils.size(fileName + ".new.compress") < FileUtils.size(fileName + ".new"));
} }
private void assertEquals(MVStore a, MVStore b) { private void assertEquals(MVStore a, MVStore b) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论