-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
484 additions
and
168 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
src/main/java/org/cryptomator/cryptofs/CiphertextDirCache.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package org.cryptomator.cryptofs; | ||
|
||
import com.github.benmanes.caffeine.cache.AsyncCache; | ||
import com.github.benmanes.caffeine.cache.Caffeine; | ||
|
||
import java.io.IOException; | ||
import java.time.Duration; | ||
import java.util.ArrayList; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
/** | ||
* Caches for the cleartext path of a directory its ciphertext path to the content directory. | ||
*/ | ||
public class CiphertextDirCache { | ||
|
||
private static final int MAX_CACHED_PATHS = 5000; | ||
private static final Duration MAX_CACHE_AGE = Duration.ofSeconds(20); | ||
|
||
private final AsyncCache<CryptoPath, CiphertextDirectory> ciphertextDirectories = Caffeine.newBuilder() // | ||
.maximumSize(MAX_CACHED_PATHS) // | ||
.expireAfterWrite(MAX_CACHE_AGE) // | ||
.buildAsync(); | ||
|
||
/** | ||
* Removes all (key,value) entries, where {@code key.startsWith(oldPrefix) == true}. | ||
* | ||
* @param basePrefix The prefix key which the keys are checked against | ||
*/ | ||
void removeAllKeysWithPrefix(CryptoPath basePrefix) { | ||
ciphertextDirectories.asMap().keySet().removeIf(p -> p.startsWith(basePrefix)); | ||
} | ||
|
||
/** | ||
* Remaps all (key,value) entries, where {@code key.startsWith(oldPrefix) == true}. | ||
* The new key is computed by replacing the oldPrefix with the newPrefix. | ||
* | ||
* @param oldPrefix the prefix key which the keys are checked against | ||
* @param newPrefix the prefix key which replaces {@code oldPrefix} | ||
*/ | ||
void recomputeAllKeysWithPrefix(CryptoPath oldPrefix, CryptoPath newPrefix) { | ||
var remappedEntries = new ArrayList<CacheEntry>(); | ||
ciphertextDirectories.asMap().entrySet().removeIf(e -> { | ||
if (e.getKey().startsWith(oldPrefix)) { | ||
var remappedPath = newPrefix.resolve(oldPrefix.relativize(e.getKey())); | ||
return remappedEntries.add(new CacheEntry(remappedPath, e.getValue())); | ||
} else { | ||
return false; | ||
} | ||
}); | ||
remappedEntries.forEach(e -> ciphertextDirectories.put(e.clearPath(), e.cipherDir())); | ||
} | ||
|
||
|
||
/** | ||
* Gets the cipher directory for the given cleartext path. If a cache miss occurs, the mapping is loaded with the {@code ifAbsent} function. | ||
* @param cleartextPath Cleartext path key | ||
* @param ifAbsent Function to compute the (cleartextPath, cipherDir) mapping on a cache miss. | ||
* @return a {@link CiphertextDirectory}, containing the dirId and the ciphertext content directory path | ||
* @throws IOException if the loading function throws an IOException | ||
*/ | ||
CiphertextDirectory get(CryptoPath cleartextPath, CipherDirLoader ifAbsent) throws IOException { | ||
var futureMapping = new CompletableFuture<CiphertextDirectory>(); | ||
var currentMapping = ciphertextDirectories.asMap().putIfAbsent(cleartextPath, futureMapping); | ||
if (currentMapping != null) { | ||
return currentMapping.join(); | ||
} else { | ||
futureMapping.complete(ifAbsent.load()); | ||
return futureMapping.join(); | ||
} | ||
} | ||
|
||
@FunctionalInterface | ||
interface CipherDirLoader { | ||
|
||
CiphertextDirectory load() throws IOException; | ||
} | ||
|
||
private record CacheEntry(CryptoPath clearPath, CompletableFuture<CiphertextDirectory> cipherDir) { | ||
|
||
} | ||
|
||
} |
21 changes: 21 additions & 0 deletions
21
src/main/java/org/cryptomator/cryptofs/CiphertextDirectory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.cryptomator.cryptofs; | ||
|
||
import java.nio.file.Path; | ||
import java.util.Objects; | ||
|
||
//own file due to dagger | ||
|
||
/** | ||
* Represents a ciphertext directory without it's mount point in the virtual filesystem. | ||
* | ||
* @param dirId The (ciphertext) dir id (not encrypted, just a uuid) | ||
* @param path The path to content directory (which contains the actual encrypted files and links to subdirectories) | ||
*/ | ||
public record CiphertextDirectory(String dirId, Path path) { | ||
|
||
public CiphertextDirectory(String dirId, Path path) { | ||
this.dirId = Objects.requireNonNull(dirId); | ||
this.path = Objects.requireNonNull(path); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.