improved directory name caching (>95% hitrate now)

This commit is contained in:
Sebastian Stenzel
2015-05-29 10:47:50 +02:00
parent 744f9db958
commit 49646aae41
7 changed files with 74 additions and 98 deletions
@@ -33,8 +33,8 @@ public class AbstractCryptorDecorator implements Cryptor {
}
@Override
public String encryptDirectoryPath(String cleartextPath, String nativePathSep) {
return cryptor.encryptDirectoryPath(cleartextPath, nativePathSep);
public String encryptDirectoryPath(String cleartextDirectoryId, String nativePathSep) {
return cryptor.encryptDirectoryPath(cleartextDirectoryId, nativePathSep);
}
@Override
@@ -45,7 +45,7 @@ public interface Cryptor extends Destroyable {
/**
* Encrypts a given plaintext path representing a directory structure. See {@link #encryptFilename(String, CryptorMetadataSupport)} for contents inside directories.
*
* @param cleartextDirectoryId A relative path (UTF-8 encoded), whose path components are separated by '/'
* @param cleartextDirectoryId A unique directory id
* @param nativePathSep Path separator like "/" used on local file system. Must not be null, even if cleartextPath is a sole file name without any path separators.
* @return Encrypted path.
*/
@@ -12,7 +12,7 @@ public class PathCachingCryptorDecorator extends AbstractCryptorDecorator {
private static final int MAX_CACHED_PATHS = 5000;
private static final int MAX_CACHED_NAMES = 5000;
private final Map<String, String> pathCache = new LRUMap<>(MAX_CACHED_PATHS); // <cleartextPath, ciphertextPath>
private final Map<String, String> pathCache = new LRUMap<>(MAX_CACHED_PATHS); // <cleartextDirectoryId, ciphertextPath>
private final BidiMap<String, String> nameCache = new BidiLRUMap<>(MAX_CACHED_NAMES); // <cleartextName, ciphertextName>
private PathCachingCryptorDecorator(Cryptor cryptor) {
@@ -26,36 +26,23 @@ public class PathCachingCryptorDecorator extends AbstractCryptorDecorator {
/* Cryptor */
@Override
public String encryptDirectoryPath(String cleartextPath, String nativePathSep) {
if (pathCache.containsKey(cleartextPath)) {
return pathCache.get(cleartextPath);
} else {
final String ciphertextPath = cryptor.encryptDirectoryPath(cleartextPath, nativePathSep);
pathCache.put(cleartextPath, ciphertextPath);
return ciphertextPath;
}
public String encryptDirectoryPath(String cleartextDirectoryId, String nativePathSep) {
return pathCache.computeIfAbsent(cleartextDirectoryId, id -> cryptor.encryptDirectoryPath(id, nativePathSep));
}
@Override
public String encryptFilename(String cleartextName) {
if (nameCache.containsKey(cleartextName)) {
return nameCache.get(cleartextName);
} else {
final String ciphertextName = cryptor.encryptFilename(cleartextName);
nameCache.put(cleartextName, ciphertextName);
return ciphertextName;
}
return nameCache.computeIfAbsent(cleartextName, name -> cryptor.encryptFilename(name));
}
@Override
public String decryptFilename(String ciphertextName) throws DecryptFailedException {
if (nameCache.containsValue(ciphertextName)) {
return nameCache.getKey(ciphertextName);
} else {
final String cleartextName = cryptor.decryptFilename(ciphertextName);
String cleartextName = nameCache.getKey(ciphertextName);
if (cleartextName == null) {
cleartextName = cryptor.decryptFilename(ciphertextName);
nameCache.put(cleartextName, ciphertextName);
return ciphertextName;
}
return cleartextName;
}
private static class BidiLRUMap<K, V> extends AbstractDualBidiMap<K, V> {