Restored I/O graph

This commit is contained in:
Sebastian Stenzel
2016-01-28 21:21:21 +01:00
parent 6af4ee08f7
commit 26aa18de77
7 changed files with 94 additions and 92 deletions

View File

@@ -22,10 +22,6 @@
<groupId>org.cryptomator</groupId>
<artifactId>filesystem-api</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>commons</artifactId>
</dependency>
<!-- Tests -->
<dependency>

View File

@@ -20,20 +20,12 @@ public class StatsFileSystem extends StatsFolder implements FileSystem {
this.written = written;
}
public long getBytesRead() {
return read.sum();
public long getThenResetBytesRead() {
return read.sumThenReset();
}
public void resetBytesRead() {
read.reset();
}
public long getBytesWritten() {
return written.sum();
}
public void resetBytesWritten() {
written.reset();
public long getThenResetBytesWritten() {
return written.sumThenReset();
}
}

View File

@@ -19,32 +19,24 @@ public class StatsFileSystemTest {
statsFs.folder("foo").create();
File testFile = statsFs.folder("foo").file("bar");
Assert.assertEquals(0l, statsFs.getBytesRead());
Assert.assertEquals(0l, statsFs.getBytesWritten());
Assert.assertEquals(0l, statsFs.getThenResetBytesRead());
Assert.assertEquals(0l, statsFs.getThenResetBytesWritten());
try (WritableFile w = testFile.openWritable()) {
w.write(ByteBuffer.allocate(15));
}
Assert.assertEquals(0l, statsFs.getBytesRead());
Assert.assertEquals(15l, statsFs.getBytesWritten());
statsFs.resetBytesWritten();
Assert.assertEquals(0l, statsFs.getBytesRead());
Assert.assertEquals(0l, statsFs.getBytesWritten());
Assert.assertEquals(0l, statsFs.getThenResetBytesRead());
Assert.assertEquals(15l, statsFs.getThenResetBytesWritten());
Assert.assertEquals(0l, statsFs.getThenResetBytesWritten());
try (ReadableFile r = testFile.openReadable()) {
r.read(ByteBuffer.allocate(3));
}
Assert.assertEquals(3l, statsFs.getBytesRead());
Assert.assertEquals(0l, statsFs.getBytesWritten());
statsFs.resetBytesRead();
Assert.assertEquals(0l, statsFs.getBytesRead());
Assert.assertEquals(0l, statsFs.getBytesWritten());
Assert.assertEquals(3l, statsFs.getThenResetBytesRead());
Assert.assertEquals(0l, statsFs.getThenResetBytesRead());
Assert.assertEquals(0l, statsFs.getThenResetBytesWritten());
}
}

View File

@@ -90,6 +90,11 @@
<artifactId>filesystem-crypto</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>filesystem-stats</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>

View File

@@ -34,6 +34,10 @@
<groupId>org.cryptomator</groupId>
<artifactId>filesystem-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>filesystem-stats</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>frontend-api</artifactId>

View File

@@ -29,6 +29,7 @@ import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.Label;
import javafx.stage.Stage;
@@ -126,7 +127,7 @@ public class UnlockedController extends AbstractFXMLViewController {
// IO Graph
// ****************************************
private void startIoSampling(final Object sampler) {
private void startIoSampling() {
final Series<Number, Number> decryptedBytes = new Series<>();
decryptedBytes.setName("decrypted");
final Series<Number, Number> encryptedBytes = new Series<>();
@@ -136,7 +137,7 @@ public class UnlockedController extends AbstractFXMLViewController {
ioGraph.getData().add(encryptedBytes);
ioAnimation = new Timeline();
ioAnimation.getKeyFrames().add(new KeyFrame(Duration.seconds(IO_SAMPLING_INTERVAL), new IoSamplingAnimationHandler(sampler, decryptedBytes, encryptedBytes)));
ioAnimation.getKeyFrames().add(new KeyFrame(Duration.seconds(IO_SAMPLING_INTERVAL), new IoSamplingAnimationHandler(decryptedBytes, encryptedBytes)));
ioAnimation.setCycleCount(Animation.INDEFINITE);
ioAnimation.play();
}
@@ -153,45 +154,41 @@ public class UnlockedController extends AbstractFXMLViewController {
private static final double BYTES_TO_MEGABYTES_FACTOR = 1.0 / IO_SAMPLING_INTERVAL / 1024.0 / 1024.0;
private static final double SMOOTHING_FACTOR = 0.3;
private static final long EFFECTIVELY_ZERO = 100000; // 100kb
private final Object sampler;
private final Series<Number, Number> decryptedBytes;
private final Series<Number, Number> encryptedBytes;
private final int step = 0;
private final long oldDecBytes = 0;
private final long oldEncBytes = 0;
private int step = 0;
private long oldDecBytes = 0;
private long oldEncBytes = 0;
public IoSamplingAnimationHandler(Object sampler, Series<Number, Number> decryptedBytes, Series<Number, Number> encryptedBytes) {
this.sampler = sampler;
public IoSamplingAnimationHandler(Series<Number, Number> decryptedBytes, Series<Number, Number> encryptedBytes) {
this.decryptedBytes = decryptedBytes;
this.encryptedBytes = encryptedBytes;
}
@Override
public void handle(ActionEvent event) {
/*
* step++;
*
* final long decBytes = sampler.pollDecryptedBytes(true);
* final double smoothedDecBytes = oldDecBytes + SMOOTHING_FACTOR * (decBytes - oldDecBytes);
* final double smoothedDecMb = smoothedDecBytes * BYTES_TO_MEGABYTES_FACTOR;
* oldDecBytes = smoothedDecBytes > EFFECTIVELY_ZERO ? (long) smoothedDecBytes : 0l;
* decryptedBytes.getData().add(new Data<Number, Number>(step, smoothedDecMb));
* if (decryptedBytes.getData().size() > IO_SAMPLING_STEPS) {
* decryptedBytes.getData().remove(0);
* }
*
* final long encBytes = sampler.pollEncryptedBytes(true);
* final double smoothedEncBytes = oldEncBytes + SMOOTHING_FACTOR * (encBytes - oldEncBytes);
* final double smoothedEncMb = smoothedEncBytes * BYTES_TO_MEGABYTES_FACTOR;
* oldEncBytes = smoothedEncBytes > EFFECTIVELY_ZERO ? (long) smoothedEncBytes : 0l;
* encryptedBytes.getData().add(new Data<Number, Number>(step, smoothedEncMb));
* if (encryptedBytes.getData().size() > IO_SAMPLING_STEPS) {
* encryptedBytes.getData().remove(0);
* }
*
* xAxis.setLowerBound(step - IO_SAMPLING_STEPS);
* xAxis.setUpperBound(step);
*/
step++;
final long decBytes = vault.pollBytesRead();
final double smoothedDecBytes = oldDecBytes + SMOOTHING_FACTOR * (decBytes - oldDecBytes);
final double smoothedDecMb = smoothedDecBytes * BYTES_TO_MEGABYTES_FACTOR;
oldDecBytes = smoothedDecBytes > EFFECTIVELY_ZERO ? (long) smoothedDecBytes : 0l;
decryptedBytes.getData().add(new Data<Number, Number>(step, smoothedDecMb));
if (decryptedBytes.getData().size() > IO_SAMPLING_STEPS) {
decryptedBytes.getData().remove(0);
}
final long encBytes = vault.pollBytesWritten();
final double smoothedEncBytes = oldEncBytes + SMOOTHING_FACTOR * (encBytes - oldEncBytes);
final double smoothedEncMb = smoothedEncBytes * BYTES_TO_MEGABYTES_FACTOR;
oldEncBytes = smoothedEncBytes > EFFECTIVELY_ZERO ? (long) smoothedEncBytes : 0l;
encryptedBytes.getData().add(new Data<Number, Number>(step, smoothedEncMb));
if (encryptedBytes.getData().size() > IO_SAMPLING_STEPS) {
encryptedBytes.getData().remove(0);
}
xAxis.setLowerBound(step - IO_SAMPLING_STEPS);
xAxis.setUpperBound(step);
}
}
@@ -214,15 +211,9 @@ public class UnlockedController extends AbstractFXMLViewController {
}
});
// sample crypto-throughput:
/*
* stopIoSampling();
* if (vault.getCryptor() instanceof CryptorIOSampling) {
* startIoSampling((CryptorIOSampling) vault.getCryptor());
* } else {
* ioGraph.setVisible(false);
* }
*/
// (re)start throughput statistics:
stopIoSampling();
startIoSampling();
}
public LockListener getListener() {

View File

@@ -21,6 +21,7 @@ import org.cryptomator.filesystem.FileSystem;
import org.cryptomator.filesystem.crypto.CryptoFileSystemDelegate;
import org.cryptomator.filesystem.crypto.CryptoFileSystemFactory;
import org.cryptomator.filesystem.nio.NioFileSystem;
import org.cryptomator.filesystem.stats.StatsFileSystem;
import org.cryptomator.frontend.CommandFailedException;
import org.cryptomator.frontend.Frontend;
import org.cryptomator.frontend.Frontend.MountParam;
@@ -42,7 +43,6 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
private static final long serialVersionUID = 3754487289683599469L;
@Deprecated
public static final String VAULT_FILE_EXTENSION = ".cryptomator";
@Deprecated
@@ -58,6 +58,7 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
private String mountName;
private Character winDriveLetter;
private Optional<StatsFileSystem> statsFileSystem = Optional.empty();
private DeferredClosable<Frontend> filesystemFrontend = DeferredClosable.empty();
/**
@@ -76,14 +77,10 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
}
}
public boolean isValidVaultDirectory() {
return Files.isDirectory(path) && path.getFileName().toString().endsWith(VAULT_FILE_EXTENSION);
}
public boolean containsMasterKey() throws IOException {
final Path masterKeyPath = path.resolve(VAULT_MASTERKEY_FILE);
return Files.isRegularFile(masterKeyPath);
}
/*
* ******************************************************************************
* Commands
********************************************************************************/
public void create(CharSequence passphrase) throws IOException {
try {
@@ -110,10 +107,12 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
try {
FileSystem fs = NioFileSystem.rootedAt(path);
FileSystem cryptoFs = cryptoFileSystemFactory.unlockExisting(fs, passphrase, this);
StatsFileSystem statsFs = new StatsFileSystem(cryptoFs);
statsFileSystem = Optional.of(statsFs);
String contextPath = StringUtils.prependIfMissing(mountName, "/");
Frontend frontend = frontendFactory.get().create(cryptoFs, contextPath);
Frontend frontend = frontendFactory.get().create(statsFs, contextPath);
filesystemFrontend = closer.closeLater(frontend);
setUnlocked(true);
unlocked.set(true);
} catch (UncheckedIOException e) {
throw new FrontendCreationFailedException(e);
}
@@ -121,7 +120,8 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
public synchronized void deactivateFrontend() {
filesystemFrontend.close();
setUnlocked(false);
statsFileSystem = Optional.empty();
unlocked.set(false);
}
private Map<MountParam, Optional<String>> getMountParams() {
@@ -150,7 +150,10 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
Optionals.ifPresent(filesystemFrontend.get(), Frontend::unmount);
}
/* Delegate Methods */
/*
* ******************************************************************************
* Delegate methods
********************************************************************************/
@Override
public void authenticationFailed(String cleartextPath) {
@@ -162,7 +165,10 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
return namesOfResourcesWithInvalidMac.contains(cleartextPath);
}
/* Getter/Setter */
/*
* ******************************************************************************
* Getter/Setter
********************************************************************************/
public Path getPath() {
return path;
@@ -175,6 +181,15 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
return StringUtils.removeEnd(path.getFileName().toString(), VAULT_FILE_EXTENSION);
}
public boolean isValidVaultDirectory() {
return Files.isDirectory(path) && path.getFileName().toString().endsWith(VAULT_FILE_EXTENSION);
}
public boolean containsMasterKey() throws IOException {
final Path masterKeyPath = path.resolve(VAULT_MASTERKEY_FILE);
return Files.isRegularFile(masterKeyPath);
}
public ObjectProperty<Boolean> unlockedProperty() {
return unlocked;
}
@@ -183,10 +198,6 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
return unlocked.get();
}
public void setUnlocked(boolean unlocked) {
this.unlocked.set(unlocked);
}
public ObservableList<String> getNamesOfResourcesWithInvalidMac() {
return namesOfResourcesWithInvalidMac;
}
@@ -195,6 +206,14 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
return whitelistedResourcesWithInvalidMac;
}
public long pollBytesRead() {
return statsFileSystem.map(StatsFileSystem::getThenResetBytesRead).orElse(0l);
}
public long pollBytesWritten() {
return statsFileSystem.map(StatsFileSystem::getThenResetBytesWritten).orElse(0l);
}
/**
* Tries to form a similar string using the regular latin alphabet.
*
@@ -247,7 +266,10 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
this.winDriveLetter = winDriveLetter;
}
/* hashcode/equals */
/*
* ******************************************************************************
* Hashcode / Equals
********************************************************************************/
@Override
public int hashCode() {