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

Experimental off-heap memory storage engine "nioMemFS:" and "nioMemLZF:",…

Experimental off-heap memory storage engine "nioMemFS:" and "nioMemLZF:", suggestion from Mark Addleman.
上级 d0bf5d3c
...@@ -413,29 +413,23 @@ public final class CompressLZF implements Compressor { ...@@ -413,29 +413,23 @@ public final class CompressLZF implements Compressor {
* @param out the output area * @param out the output area
*/ */
public static void expand(ByteBuffer in, ByteBuffer out) { public static void expand(ByteBuffer in, ByteBuffer out) {
int inPos = in.position();
int outPos = out.position();
int outLen = out.capacity() - outPos;
// if ((inPos | outPos | outLen) < 0) {
if (inPos < 0 || outPos < 0 || outLen < 0) {
throw new IllegalArgumentException();
}
do { do {
int ctrl = in.get(inPos++) & 255; int ctrl = in.get() & 255;
if (ctrl < MAX_LITERAL) { if (ctrl < MAX_LITERAL) {
// literal run of length = ctrl + 1, // literal run of length = ctrl + 1,
ctrl++; ctrl++;
// copy to output and move forward this many bytes // copy to output and move forward this many bytes
System.arraycopy(in, inPos, out, outPos, ctrl); // (maybe slice would be faster)
outPos += ctrl; for (int i = 0; i < ctrl; i++) {
inPos += ctrl; out.put(in.get());
}
} else { } else {
// back reference // back reference
// the highest 3 bits are the match length // the highest 3 bits are the match length
int len = ctrl >> 5; int len = ctrl >> 5;
// if the length is maxed, add the next byte to the length // if the length is maxed, add the next byte to the length
if (len == 7) { if (len == 7) {
len += in.get(inPos++) & 255; len += in.get() & 255;
} }
// minimum back-reference is 3 bytes, // minimum back-reference is 3 bytes,
// so 2 was subtracted before storing size // so 2 was subtracted before storing size
...@@ -446,20 +440,17 @@ public final class CompressLZF implements Compressor { ...@@ -446,20 +440,17 @@ public final class CompressLZF implements Compressor {
ctrl = -((ctrl & 0x1f) << 8) - 1; ctrl = -((ctrl & 0x1f) << 8) - 1;
// the next byte augments/increases the offset // the next byte augments/increases the offset
ctrl -= in.get(inPos++) & 255; ctrl -= in.get() & 255;
// copy the back-reference bytes from the given // copy the back-reference bytes from the given
// location in output to current position // location in output to current position
ctrl += outPos; // (maybe slice would be faster)
if (outPos + len >= out.capacity()) { ctrl += out.position();
// reduce array bounds checking
throw new ArrayIndexOutOfBoundsException();
}
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
out.put(outPos++, out.get(ctrl++)); out.put(out.get(ctrl++));
} }
} }
} while (outPos < outLen); } while (out.position() < out.capacity());
} }
public int getAlgorithm() { public int getAlgorithm() {
......
...@@ -11,6 +11,7 @@ import java.io.ByteArrayOutputStream; ...@@ -11,6 +11,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
...@@ -198,6 +199,11 @@ public class TestCompress extends TestBase { ...@@ -198,6 +199,11 @@ public class TestCompress extends TestBase {
} }
private void test(int len) throws IOException { private void test(int len) throws IOException {
testByteArray(len);
testByteBuffer(len);
}
private void testByteArray(int len) throws IOException {
Random r = new Random(len); Random r = new Random(len);
for (int pattern = 0; pattern < 4; pattern++) { for (int pattern = 0; pattern < 4; pattern++) {
byte[] b = new byte[len]; byte[] b = new byte[len];
...@@ -258,5 +264,52 @@ public class TestCompress extends TestBase { ...@@ -258,5 +264,52 @@ public class TestCompress extends TestBase {
} }
} }
} }
private void testByteBuffer(int len) {
if (len < 4) {
return;
}
Random r = new Random(len);
CompressLZF comp = new CompressLZF();
for (int pattern = 0; pattern < 4; pattern++) {
byte[] b = new byte[len];
switch (pattern) {
case 0:
// leave empty
break;
case 1: {
r.nextBytes(b);
break;
}
case 2: {
for (int x = 0; x < len; x++) {
b[x] = (byte) (x & 10);
}
break;
}
case 3: {
for (int x = 0; x < len; x++) {
b[x] = (byte) (x / 10);
}
break;
}
default:
}
if (r.nextInt(2) < 1) {
for (int x = 0; x < len; x++) {
if (r.nextInt(20) < 1) {
b[x] = (byte) (r.nextInt(255));
}
}
}
ByteBuffer buff = ByteBuffer.wrap(b);
byte[] temp = new byte[100 + b.length * 2];
int compLen = comp.compress(buff, temp, 0);
ByteBuffer test = ByteBuffer.wrap(temp, 0, compLen);
byte[] exp = new byte[b.length];
CompressLZF.expand(test, ByteBuffer.wrap(exp));
assertEquals(b, exp);
}
}
} }
...@@ -70,8 +70,8 @@ public class TestFileSystem extends TestBase { ...@@ -70,8 +70,8 @@ public class TestFileSystem extends TestBase {
FileUtils.toRealPath(f); FileUtils.toRealPath(f);
testFileSystem(getBaseDir() + "/fs"); testFileSystem(getBaseDir() + "/fs");
testFileSystem("memFS:"); testFileSystem("memFS:");
testFileSystem("nioMemFS:");
testFileSystem("memLZF:"); testFileSystem("memLZF:");
testFileSystem("nioMemFS:");
testFileSystem("nioMemLZF:"); testFileSystem("nioMemLZF:");
testUserHome(); testUserHome();
try { try {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论