Browse Source

- CryptoFS + InMemory Benchmark test
- faster growing in-memory files

Sebastian Stenzel 9 năm trước cách đây
mục cha
commit
a6bbc0ed44

+ 36 - 0
main/filesystem-crypto/src/test/java/org/cryptomator/filesystem/crypto/CryptoFileSystemComponentIntegrationTest.java

@@ -1,5 +1,6 @@
 package org.cryptomator.filesystem.crypto;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 
@@ -14,11 +15,15 @@ import org.cryptomator.filesystem.inmem.InMemoryFileSystem;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class CryptoFileSystemComponentIntegrationTest {
 
 	private static final CryptoFileSystemComponent cryptoFsComp = DaggerCryptoFileSystemComponent.builder().cryptoEngineModule(new CryptoEngineTestModule()).build();
 
+	private static final Logger LOG = LoggerFactory.getLogger(CryptoFileSystemComponentIntegrationTest.class);
+
 	private FileSystem ciphertextFs;
 	private FileSystem cleartextFs;
 
@@ -72,6 +77,37 @@ public class CryptoFileSystemComponentIntegrationTest {
 		}
 	}
 
+	@Test(timeout = 2000000) // assuming a minimum speed of 10mb/s during encryption and decryption 20s should be enough
+	public void testEncryptionAndDecryptionSpeed() throws InterruptedException, IOException {
+		File file = cleartextFs.file("benchmark.test");
+
+		final long encStart = System.nanoTime();
+		try (WritableFile writable = file.openWritable()) {
+			final ByteBuffer cleartext = ByteBuffer.allocate(100000); // 100k
+			for (int i = 0; i < 1000; i++) { // 100M total
+				cleartext.rewind();
+				writable.write(cleartext);
+			}
+		}
+		final long encEnd = System.nanoTime();
+		LOG.debug("Encryption of 100M took {}ms", (encEnd - encStart) / 1000 / 1000);
+
+		final long decStart = System.nanoTime();
+		try (ReadableFile readable = file.openReadable()) {
+			final ByteBuffer cleartext = ByteBuffer.allocate(100000); // 100k
+			for (int i = 0; i < 1000; i++) { // 100M total
+				cleartext.clear();
+				readable.read(cleartext);
+				cleartext.flip();
+				Assert.assertEquals(cleartext.get(), 0x00);
+			}
+		}
+		final long decEnd = System.nanoTime();
+		LOG.debug("Decryption of 100M took {}ms", (decEnd - decStart) / 1000 / 1000);
+
+		file.delete();
+	}
+
 	@Test
 	public void testRandomAccess() {
 		File cleartextFile = cleartextFs.file("test");

+ 8 - 1
main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryFile.java

@@ -23,11 +23,18 @@ import org.cryptomator.filesystem.WritableFile;
 
 class InMemoryFile extends InMemoryNode implements File {
 
+	/** 1000kb */
+	static final int INITIAL_SIZE = 100 * 1024;
+
+	/** 140% */
+	static final double GROWTH_RATE = 1.4;
+
 	private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-	private ByteBuffer content = ByteBuffer.allocate(0);
+	private volatile ByteBuffer content = ByteBuffer.allocate(INITIAL_SIZE);
 
 	public InMemoryFile(InMemoryFolder parent, String name, Instant lastModified, Instant creationTime) {
 		super(parent, name, lastModified, creationTime);
+		content.flip();
 	}
 
 	@Override

+ 1 - 1
main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryReadableFile.java

@@ -22,7 +22,7 @@ class InMemoryReadableFile implements ReadableFile {
 	private final Supplier<ByteBuffer> contentGetter;
 	private final ReadLock readLock;
 	private boolean open = true;
-	private int position = 0;
+	private volatile int position = 0;
 
 	public InMemoryReadableFile(Supplier<ByteBuffer> contentGetter, ReadLock readLock) {
 		this.contentGetter = contentGetter;

+ 7 - 3
main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryWritableFile.java

@@ -28,7 +28,7 @@ public class InMemoryWritableFile implements WritableFile {
 	private final WriteLock writeLock;
 
 	private boolean open = true;
-	private int position = 0;
+	private volatile int position = 0;
 
 	public InMemoryWritableFile(Consumer<Instant> lastModifiedSetter, Consumer<Instant> creationTimeSetter, Supplier<ByteBuffer> contentGetter, Consumer<ByteBuffer> contentSetter, Consumer<Void> deleter,
 			WriteLock writeLock) {
@@ -74,15 +74,19 @@ public class InMemoryWritableFile implements WritableFile {
 	@Override
 	public int write(ByteBuffer source) throws UncheckedIOException {
 		ByteBuffer destination = contentGetter.get();
+		int oldFileSize = destination.limit();
 		int requiredSize = position + source.remaining();
+		int newFileSize = Math.max(oldFileSize, requiredSize);
 		if (destination.capacity() < requiredSize) {
 			ByteBuffer old = destination;
-			old.rewind();
-			destination = ByteBuffer.allocate(requiredSize);
+			old.clear();
+			int newBufferSize = Math.max(requiredSize, (int) (destination.capacity() * InMemoryFile.GROWTH_RATE));
+			destination = ByteBuffer.allocate(newBufferSize);
 			ByteBuffers.copy(old, destination);
 			contentSetter.accept(destination);
 		}
 		destination.position(position);
+		destination.limit(newFileSize);
 		int numWritten = ByteBuffers.copy(source, destination);
 		this.position += numWritten;
 		return numWritten;