提交 76f8ac82 authored 作者: noelgrandin's avatar noelgrandin

avoid copying data from ByteBuffer to another ByteBuffer if possible, specially…

avoid copying data from ByteBuffer to another ByteBuffer if possible,  specially for the OffHeapStore
上级 7974fd2a
...@@ -46,9 +46,11 @@ public class FileStore { ...@@ -46,9 +46,11 @@ public class FileStore {
return fileName; return fileName;
} }
public void readFully(long pos, ByteBuffer dst) { public ByteBuffer readFully(long pos, int len) {
readCount++; readCount++;
ByteBuffer dst = ByteBuffer.allocate(len);
DataUtils.readFully(file, pos, dst); DataUtils.readFully(file, pos, dst);
return dst;
} }
public void writeFully(long pos, ByteBuffer src) { public void writeFully(long pos, ByteBuffer src) {
......
...@@ -112,8 +112,6 @@ MVStore: ...@@ -112,8 +112,6 @@ MVStore:
- simple rollback method (rollback to last committed version) - simple rollback method (rollback to last committed version)
- MVMap to implement SortedMap, then NavigableMap - MVMap to implement SortedMap, then NavigableMap
- Test with OSGi - Test with OSGi
- avoid copying data from ByteBuffer to another ByteBuffer if possible,
specially for the OffHeapStore
- storage that splits database into multiple files, - storage that splits database into multiple files,
to speed up compact and allow using trim to speed up compact and allow using trim
(by truncating / deleting empty files) (by truncating / deleting empty files)
...@@ -555,12 +553,11 @@ public class MVStore { ...@@ -555,12 +553,11 @@ public class MVStore {
// we don't know which chunk is the newest // we don't know which chunk is the newest
long newestChunk = -1; long newestChunk = -1;
// read the last block of the file, and then the two first blocks // read the last block of the file, and then the two first blocks
ByteBuffer buffLastBlock = fileStore.readFully(fileStore.size() - BLOCK_SIZE, BLOCK_SIZE);
ByteBuffer buffFirst2Blocks = fileStore.readFully(0, BLOCK_SIZE * 2);
ByteBuffer buff = ByteBuffer.allocate(3 * BLOCK_SIZE); ByteBuffer buff = ByteBuffer.allocate(3 * BLOCK_SIZE);
buff.limit(BLOCK_SIZE); buff.put(buffLastBlock);
fileStore.readFully(fileStore.size() - BLOCK_SIZE, buff); buff.put(buffFirst2Blocks);
buff.limit(3 * BLOCK_SIZE);
buff.position(BLOCK_SIZE);
fileStore.readFully(0, buff);
for (int i = 0; i < 3 * BLOCK_SIZE; i += BLOCK_SIZE) { for (int i = 0; i < 3 * BLOCK_SIZE; i += BLOCK_SIZE) {
String s = new String(buff.array(), i, BLOCK_SIZE, DataUtils.UTF8) String s = new String(buff.array(), i, BLOCK_SIZE, DataUtils.UTF8)
.trim(); .trim();
...@@ -1112,9 +1109,7 @@ public class MVStore { ...@@ -1112,9 +1109,7 @@ public class MVStore {
} }
private Chunk readChunkHeader(long start) { private Chunk readChunkHeader(long start) {
ByteBuffer buff = ByteBuffer.allocate(40); ByteBuffer buff = fileStore.readFully(start, 40);
fileStore.readFully(start, buff);
buff.rewind();
return Chunk.fromHeader(buff, start); return Chunk.fromHeader(buff, start);
} }
...@@ -1164,7 +1159,8 @@ public class MVStore { ...@@ -1164,7 +1159,8 @@ public class MVStore {
int length = MathUtils.roundUpInt(c.length, BLOCK_SIZE) + BLOCK_SIZE; int length = MathUtils.roundUpInt(c.length, BLOCK_SIZE) + BLOCK_SIZE;
buff = DataUtils.ensureCapacity(buff, length); buff = DataUtils.ensureCapacity(buff, length);
buff.limit(length); buff.limit(length);
fileStore.readFully(c.start, buff); ByteBuffer buff2 = fileStore.readFully(c.start, length);
buff.put(buff2);
long end = getEndPosition(); long end = getEndPosition();
fileStore.markUsed(end, length); fileStore.markUsed(end, length);
fileStore.free(c.start, length); fileStore.free(c.start, length);
...@@ -1196,7 +1192,8 @@ public class MVStore { ...@@ -1196,7 +1192,8 @@ public class MVStore {
int length = MathUtils.roundUpInt(c.length, BLOCK_SIZE) + BLOCK_SIZE; int length = MathUtils.roundUpInt(c.length, BLOCK_SIZE) + BLOCK_SIZE;
buff = DataUtils.ensureCapacity(buff, length); buff = DataUtils.ensureCapacity(buff, length);
buff.limit(length); buff.limit(length);
fileStore.readFully(c.start, buff); ByteBuffer buff2 = fileStore.readFully(c.start, length);
buff.put(buff2);
long pos = fileStore.allocate(length); long pos = fileStore.allocate(length);
fileStore.free(c.start, length); fileStore.free(c.start, length);
buff.position(0); buff.position(0);
...@@ -1325,8 +1322,7 @@ public class MVStore { ...@@ -1325,8 +1322,7 @@ public class MVStore {
} }
private void copyLive(Chunk chunk, ArrayList<Chunk> old) { private void copyLive(Chunk chunk, ArrayList<Chunk> old) {
ByteBuffer buff = ByteBuffer.allocate(chunk.length); ByteBuffer buff = fileStore.readFully(chunk.start, chunk.length);
fileStore.readFully(chunk.start, buff);
Chunk.fromHeader(buff, chunk.start); Chunk.fromHeader(buff, chunk.start);
int chunkLength = chunk.length; int chunkLength = chunk.length;
markMetaChanged(); markMetaChanged();
......
...@@ -30,20 +30,22 @@ public class OffHeapStore extends FileStore { ...@@ -30,20 +30,22 @@ public class OffHeapStore extends FileStore {
} }
@Override @Override
public void readFully(long pos, ByteBuffer dst) { public ByteBuffer readFully(long pos, int len) {
Entry<Long, ByteBuffer> mem = memory.floorEntry(pos); Entry<Long, ByteBuffer> memEntry = memory.floorEntry(pos);
if (mem == null) { if (memEntry == null) {
throw DataUtils.newIllegalStateException(DataUtils.ERROR_READING_FAILED, throw DataUtils.newIllegalStateException(DataUtils.ERROR_READING_FAILED,
"Could not read from position {0}", pos); "Could not read from position {0}", pos);
} }
readCount++; readCount++;
ByteBuffer buff = mem.getValue(); ByteBuffer buff = memEntry.getValue();
ByteBuffer read = buff.duplicate(); int oldLimit = buff.limit();
int offset = (int) (pos - mem.getKey()); int offset = (int) (pos - memEntry.getKey());
read.position(offset); buff.position(offset);
read.limit(dst.remaining() + offset); buff.limit(len + offset);
dst.put(read); ByteBuffer read = buff.slice();
dst.rewind(); buff.position(0);
buff.limit(oldLimit);
return read;
} }
@Override @Override
......
...@@ -169,13 +169,11 @@ public class Page { ...@@ -169,13 +169,11 @@ public class Page {
maxLength = (int) Math.min(fileSize - filePos, maxLength); maxLength = (int) Math.min(fileSize - filePos, maxLength);
int length = maxLength; int length = maxLength;
if (maxLength == Integer.MAX_VALUE) { if (maxLength == Integer.MAX_VALUE) {
buff = ByteBuffer.allocate(128); buff = fileStore.readFully(filePos, 128);
fileStore.readFully(filePos, buff);
maxLength = buff.getInt(); maxLength = buff.getInt();
// read the first bytes again // read the first bytes again
} }
buff = ByteBuffer.allocate(length); buff = fileStore.readFully(filePos, length);
fileStore.readFully(filePos, buff);
Page p = new Page(map, 0); Page p = new Page(map, 0);
p.pos = pos; p.pos = pos;
int chunkId = DataUtils.getPageChunkId(pos); int chunkId = DataUtils.getPageChunkId(pos);
......
...@@ -87,8 +87,7 @@ public class FilePathCache extends FilePathWrapper { ...@@ -87,8 +87,7 @@ public class FilePathCache extends FilePathWrapper {
} }
} }
len = Math.min(len, dst.remaining()); len = Math.min(len, dst.remaining());
System.arraycopy(buff.array(), off, dst.array(), dst.position(), len); dst.put(buff.array(), off, len);
dst.position(dst.position() + len);
return len; return len;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论