-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Expiry static factory methods (fixes #1499)
- Loading branch information
Showing
26 changed files
with
326 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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,11 +15,28 @@ | |
*/ | ||
package com.github.benmanes.caffeine.cache; | ||
|
||
import static com.github.benmanes.caffeine.cache.Caffeine.toNanosSaturated; | ||
import static java.util.Objects.requireNonNull; | ||
|
||
import java.io.Serializable; | ||
import java.time.Duration; | ||
import java.util.function.BiFunction; | ||
|
||
import org.checkerframework.checker.index.qual.NonNegative; | ||
|
||
import com.google.errorprone.annotations.CanIgnoreReturnValue; | ||
|
||
/** | ||
* Calculates when cache entries expire. A single expiration time is retained so that the lifetime | ||
* of an entry may be extended or reduced by subsequent evaluations. | ||
* <p> | ||
* Usage example: | ||
* <pre>{@code | ||
* LoadingCache<Key, Graph> cache = Caffeine.newBuilder() | ||
* .expireAfter(Expiry.creating((Key key, Graph graph) -> | ||
* Duration.between(Instant.now(), graph.createdOn().plusHours(5)))) | ||
* .build(key -> createExpensiveGraph(key)); | ||
* }</pre> | ||
* | ||
* @author [email protected] (Ben Manes) | ||
*/ | ||
|
@@ -76,4 +93,121 @@ public interface Expiry<K, V> { | |
* @return the length of time before the entry expires, in nanoseconds | ||
*/ | ||
long expireAfterRead(K key, V value, long currentTime, @NonNegative long currentDuration); | ||
|
||
/** | ||
* Returns an {@code Expiry} that specifies that the entry should be automatically removed from | ||
* the cache once the duration has elapsed after the entry's creation. The expiration time is | ||
* not modified when the entry is updated or read. | ||
* | ||
* <pre>{@code | ||
* Expiry<Key, Graph> expiry = Expiry.creating((key, graph) -> | ||
* Duration.between(Instant.now(), graph.createdOn().plusHours(5))); | ||
* }</pre> | ||
* | ||
* @param function the function used to calculate the length of time after an entry is created | ||
* before it should be automatically removed | ||
* @return an {@code Expiry} instance with the specified expiry function | ||
*/ | ||
static <K, V> Expiry<K, V> creating(BiFunction<K, V, Duration> function) { | ||
return new ExpiryAfterCreate<>(function); | ||
} | ||
|
||
/** | ||
* Returns an {@code Expiry} that specifies that the entry should be automatically removed from | ||
* the cache once the duration has elapsed after the entry's creation or replacement of its value. | ||
* The expiration time is not modified when the entry is read. | ||
* | ||
* <pre>{@code | ||
* Expiry<Key, Graph> expiry = Expiry.writing((key, graph) -> | ||
* Duration.between(Instant.now(), graph.modifiedOn().plusHours(5))); | ||
* }</pre> | ||
* | ||
* @param function the function used to calculate the length of time after an entry is created | ||
* or updated that it should be automatically removed | ||
* @return an {@code Expiry} instance with the specified expiry function | ||
*/ | ||
static <K, V> Expiry<K, V> writing(BiFunction<K, V, Duration> function) { | ||
return new ExpiryAfterWrite<>(function); | ||
} | ||
|
||
/** | ||
* Returns an {@code Expiry} that specifies that the entry should be automatically removed from | ||
* the cache once the duration has elapsed after the entry's creation, replacement of its value, | ||
* or after it was last read. | ||
* | ||
* <pre>{@code | ||
* Expiry<Key, Graph> expiry = Expiry.accessing((key, graph) -> | ||
* graph.isDirected() ? Duration.ofHours(1) : Duration.ofHours(3)); | ||
* }</pre> | ||
* | ||
* @param function the function used to calculate the length of time after an entry last accessed | ||
* that it should be automatically removed | ||
* @return an {@code Expiry} instance with the specified expiry function | ||
*/ | ||
static <K, V> Expiry<K, V> accessing(BiFunction<K, V, Duration> function) { | ||
return new ExpiryAfterAccess<>(function); | ||
} | ||
} | ||
|
||
final class ExpiryAfterCreate<K, V> implements Expiry<K, V>, Serializable { | ||
private static final long serialVersionUID = 1L; | ||
|
||
@SuppressWarnings("serial") | ||
final BiFunction<K, V, Duration> function; | ||
|
||
public ExpiryAfterCreate(BiFunction<K, V, Duration> calculator) { | ||
this.function = requireNonNull(calculator); | ||
} | ||
@Override public long expireAfterCreate(K key, V value, long currentTime) { | ||
return toNanosSaturated(function.apply(key, value)); | ||
} | ||
@CanIgnoreReturnValue | ||
@Override public long expireAfterUpdate(K key, V value, long currentTime, long currentDuration) { | ||
return currentDuration; | ||
} | ||
@CanIgnoreReturnValue | ||
@Override public long expireAfterRead(K key, V value, long currentTime, long currentDuration) { | ||
return currentDuration; | ||
} | ||
} | ||
|
||
final class ExpiryAfterWrite<K, V> implements Expiry<K, V>, Serializable { | ||
private static final long serialVersionUID = 1L; | ||
|
||
@SuppressWarnings("serial") | ||
final BiFunction<K, V, Duration> function; | ||
|
||
public ExpiryAfterWrite(BiFunction<K, V, Duration> calculator) { | ||
this.function = requireNonNull(calculator); | ||
} | ||
@Override public long expireAfterCreate(K key, V value, long currentTime) { | ||
return toNanosSaturated(function.apply(key, value)); | ||
} | ||
@Override public long expireAfterUpdate(K key, V value, long currentTime, long currentDuration) { | ||
return toNanosSaturated(function.apply(key, value)); | ||
} | ||
@CanIgnoreReturnValue | ||
@Override public long expireAfterRead(K key, V value, long currentTime, long currentDuration) { | ||
return currentDuration; | ||
} | ||
} | ||
|
||
final class ExpiryAfterAccess<K, V> implements Expiry<K, V>, Serializable { | ||
private static final long serialVersionUID = 1L; | ||
|
||
@SuppressWarnings("serial") | ||
final BiFunction<K, V, Duration> function; | ||
|
||
public ExpiryAfterAccess(BiFunction<K, V, Duration> calculator) { | ||
this.function = requireNonNull(calculator); | ||
} | ||
@Override public long expireAfterCreate(K key, V value, long currentTime) { | ||
return toNanosSaturated(function.apply(key, value)); | ||
} | ||
@Override public long expireAfterUpdate(K key, V value, long currentTime, long currentDuration) { | ||
return toNanosSaturated(function.apply(key, value)); | ||
} | ||
@Override public long expireAfterRead(K key, V value, long currentTime, long currentDuration) { | ||
return toNanosSaturated(function.apply(key, value)); | ||
} | ||
} |
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
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.