Skip to content

Commit

Permalink
Create cache files with CREATE_NEW & SPARSE options
Browse files Browse the repository at this point in the history
  • Loading branch information
tlrx committed Oct 18, 2021
1 parent dce0347 commit 8b78ed2
Showing 1 changed file with 18 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ public interface ModificationListener {
void onCacheFileDelete(CacheFile cacheFile);
}

private static final StandardOpenOption[] OPEN_OPTIONS = new StandardOpenOption[] {
private static final StandardOpenOption[] CREATE_OPTIONS = new StandardOpenOption[] {
StandardOpenOption.READ,
StandardOpenOption.WRITE,
StandardOpenOption.CREATE,
StandardOpenOption.CREATE_NEW,
StandardOpenOption.SPARSE };

private static final StandardOpenOption[] OPEN_OPTIONS = new StandardOpenOption[] { StandardOpenOption.READ, StandardOpenOption.WRITE };

/**
* Reference counter that counts the number of eviction listeners referencing this cache file plus the number of open file channels
* for it. Once this instance has been evicted, all listeners notified and all {@link FileChannelReference} for it released,
Expand Down Expand Up @@ -100,8 +102,8 @@ private final class FileChannelReference extends AbstractRefCounted {

private final FileChannel fileChannel;

FileChannelReference() throws IOException {
this.fileChannel = FileChannel.open(file, OPEN_OPTIONS);
FileChannelReference(StandardOpenOption[] options) throws IOException {
this.fileChannel = FileChannel.open(file, options);
refCounter.incRef();
}

Expand All @@ -124,19 +126,26 @@ protected void closeInternal() {
@Nullable
private volatile FileChannelReference channelRef;

/**
* Indicates if the file has already been created.
* This is useful to pass the right options when opening the file.
*/
private volatile boolean created;

public CacheFile(CacheKey cacheKey, long length, Path file, ModificationListener listener) {
this(cacheKey, new SparseFileTracker(file.toString(), length), file, listener);
this(cacheKey, new SparseFileTracker(file.toString(), length), file, listener, false);
}

public CacheFile(CacheKey cacheKey, long length, Path file, SortedSet<ByteRange> ranges, ModificationListener listener) {
this(cacheKey, new SparseFileTracker(file.toString(), length, ranges), file, listener);
this(cacheKey, new SparseFileTracker(file.toString(), length, ranges), file, listener, true);
}

private CacheFile(CacheKey cacheKey, SparseFileTracker tracker, Path file, ModificationListener listener) {
private CacheFile(CacheKey cacheKey, SparseFileTracker tracker, Path file, ModificationListener listener, boolean fileExists) {
this.cacheKey = Objects.requireNonNull(cacheKey);
this.tracker = Objects.requireNonNull(tracker);
this.file = Objects.requireNonNull(file);
this.listener = Objects.requireNonNull(listener);
this.created = fileExists;
assert invariant();
}

Expand Down Expand Up @@ -182,7 +191,8 @@ public void acquire(final EvictionListener listener) throws IOException {
ensureOpen();
if (listeners.isEmpty()) {
assert channelRef == null;
channelRef = new FileChannelReference();
channelRef = new FileChannelReference(created ? OPEN_OPTIONS : CREATE_OPTIONS);
created = true;
}
final boolean added = listeners.add(listener);
assert added : "listener already exists " + listener;
Expand Down

0 comments on commit 8b78ed2

Please sign in to comment.