Skip to content

Commit

Permalink
Variable expiration unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-manes committed May 8, 2017
1 parent be754c5 commit fc57249
Show file tree
Hide file tree
Showing 13 changed files with 291 additions and 148 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ before_install:

script:
- ./gradlew findbugsMain pmdMain -Dfindbugs -Dpmd
- ./gradlew -Dscan check -x :caffeine:slowCaffeineTest -x :caffeine:slowGuavaTest
- travis_wait ./gradlew -Dscan :caffeine:slowCaffeineTest
- travis_wait ./gradlew -Dscan :caffeine:slowGuavaTest
- ./gradlew --scan check -x :caffeine:slowCaffeineTest -x :caffeine:slowGuavaTest
- travis_wait ./gradlew --scan :caffeine:slowCaffeineTest
- travis_wait ./gradlew --scan :caffeine:slowGuavaTest
- sh -c 'cd examples/stats-metrics && ./gradlew test'
- sh -c 'cd examples/write-behind-rxjava && mvn test'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ public boolean hasWriteTime() {
}

protected Expiry<K, V> expiry() {
return Expiry.eternalExpiry();
throw new UnsupportedOperationException();
}

@Override
Expand Down Expand Up @@ -3243,13 +3243,15 @@ final class BoundedVarExpiration implements VarExpiration<K, V> {
Object lookupKey = cache.nodeFactory.newLookupKey(key);
Node<?, ?> node = cache.data.get(lookupKey);
if (node != null) {
node.setVariableTime(unit.convert(duration, TimeUnit.NANOSECONDS));
long durationNanos = TimeUnit.NANOSECONDS.convert(duration, unit);
long now = cache.expirationTicker().read();
node.setVariableTime(now + durationNanos);
}
}
@Override public Map<K, V> youngest(int limit) {
@Override public Map<K, V> oldest(int limit) {
return cache.variableSnapshot(/* ascending */ true, limit, transformer);
}
@Override public Map<K, V> oldest(int limit) {
@Override public Map<K, V> youngest(int limit) {
return cache.variableSnapshot(/* ascending */ false, limit, transformer);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,8 @@ boolean expiresAfterAccess() {
* described in the class javadoc.
*
* @param expiry the expiry to use in calculating the expiration time of cache entries
* @param <K1> key type of the weigher
* @param <V1> value type of the weigher
* @return this builder instance
* @throws IllegalStateException if expiration was already set
*/
Expand All @@ -613,8 +615,9 @@ boolean expiresVariable() {

@SuppressWarnings("unchecked")
Expiry<K, V> getExpiry(boolean isAsync) {
Expiry<K, V> delegate = (expiry == null) ? Expiry.eternalExpiry() : (Expiry<K, V>) expiry;
return isAsync ? (Expiry<K, V>) new AsyncExpiry<>(delegate) : delegate;
return isAsync && (expiry != null)
? (Expiry<K, V>) new AsyncExpiry<>(expiry)
: (Expiry<K, V>) expiry;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,35 +65,4 @@ public interface Expiry<K, V> {
* @return the length of time before the entry expires, in nanoseconds
*/
long expireAfterRead(K key, V value, long currentTime, long currentDuration);

/**
* Returns an expiry where entries never expire.
*
* @param <K> the type of keys
* @param <V> the type of values
* @return an expiry where entries never expire
*/
@SuppressWarnings("unchecked")
static <K, V> Expiry<K, V> eternalExpiry() {
return (Expiry<K, V>) EternalExpiry.INSTANCE;
}
}

enum EternalExpiry implements Expiry<Object, Object> {
INSTANCE;

@Override
public long expireAfterCreate(Object key, Object value, long currentTime) {
return Long.MAX_VALUE;
}

@Override
public long expireAfterUpdate(Object key, Object value, long currentTime, long currentDuration) {
return Long.MAX_VALUE;
}

@Override
public long expireAfterRead(Object key, Object value, long currentTime, long currentDuration) {
return Long.MAX_VALUE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void recordLoadFailure(long loadTime) {
@SuppressWarnings("deprecation")
public void recordEviction() {
try {
delegate.recordEviction(0);
delegate.recordEviction();
} catch (Throwable t) {
logger.log(Level.WARNING, "Exception thrown by stats counter", t);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,18 +214,14 @@ public void putIfAbsent(Map<Integer, Integer> map, CacheContext context) {
/* ---------------- Policy -------------- */

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE)
public void getExpiresAfter(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
assertThat(expireAfterAccess.getExpiresAfter(TimeUnit.MINUTES), is(1L));
}

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE)
public void setExpiresAfter(Cache<Integer, Integer> cache, CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
expireAfterAccess.setExpiresAfter(2, TimeUnit.MINUTES);
Expand All @@ -238,9 +234,7 @@ public void setExpiresAfter(Cache<Integer, Integer> cache, CacheContext context,

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
population = { Population.SINGLETON, Population.PARTIAL, Population.FULL },
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
population = { Population.SINGLETON, Population.PARTIAL, Population.FULL })
public void ageOf(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
assertThat(expireAfterAccess.ageOf(context.firstKey(), TimeUnit.SECONDS).getAsLong(), is(0L));
Expand All @@ -252,37 +246,30 @@ public void ageOf(CacheContext context,

/* ---------------- Policy: oldest -------------- */

@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE)
@Test(dataProvider = "caches", expectedExceptions = UnsupportedOperationException.class)
public void oldest_unmodifiable(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
expireAfterAccess.oldest(Integer.MAX_VALUE).clear();;
}

@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE)
@Test(dataProvider = "caches", expectedExceptions = IllegalArgumentException.class)
public void oldest_negative(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
expireAfterAccess.oldest(-1);
}

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE)
public void oldest_zero(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
assertThat(expireAfterAccess.oldest(0), is(emptyMap()));
}

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, population = Population.FULL,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expireAfterAccess = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS }, expiryTime = Expire.ONE_MINUTE)
@CacheSpec(implementation = Implementation.Caffeine,
population = Population.FULL, expireAfterAccess = Expire.ONE_MINUTE)
public void oldest_partial(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
int count = (int) context.initialSize() / 2;
Expand All @@ -292,8 +279,6 @@ public void oldest_partial(CacheContext context,
@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine,
population = {Population.PARTIAL, Population.FULL}, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS },
removalListener = { Listener.DEFAULT, Listener.REJECTING })
public void oldest_order(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
Expand All @@ -302,9 +287,7 @@ public void oldest_order(CacheContext context,
}

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE)
public void oldest_snapshot(Cache<Integer, Integer> cache, CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
Map<Integer, Integer> oldest = expireAfterAccess.oldest(Integer.MAX_VALUE);
Expand All @@ -314,37 +297,30 @@ public void oldest_snapshot(Cache<Integer, Integer> cache, CacheContext context,

/* ---------------- Policy: youngest -------------- */

@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE)
@Test(dataProvider = "caches", expectedExceptions = UnsupportedOperationException.class)
public void youngest_unmodifiable(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
expireAfterAccess.youngest(Integer.MAX_VALUE).clear();;
}

@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE)
@Test(dataProvider = "caches", expectedExceptions = IllegalArgumentException.class)
public void youngest_negative(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
expireAfterAccess.youngest(-1);
}

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE)
public void youngest_zero(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
assertThat(expireAfterAccess.youngest(0), is(emptyMap()));
}

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, population = Population.FULL,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS }, expireAfterAccess = Expire.ONE_MINUTE)
@CacheSpec(implementation = Implementation.Caffeine,
population = Population.FULL, expireAfterAccess = Expire.ONE_MINUTE)
public void youngest_partial(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
int count = (int) context.initialSize() / 2;
Expand All @@ -353,9 +329,7 @@ public void youngest_partial(CacheContext context,

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine,
population = {Population.PARTIAL, Population.FULL},
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expireAfterAccess = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS }, expiryTime = Expire.ONE_MINUTE,
population = {Population.PARTIAL, Population.FULL}, expireAfterAccess = Expire.ONE_MINUTE,
removalListener = { Listener.DEFAULT, Listener.REJECTING })
public void youngest_order(CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
Expand All @@ -365,9 +339,7 @@ public void youngest_order(CacheContext context,
}

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE,
mustExpiresWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiryTime = Expire.ONE_MINUTE,
expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS })
@CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE)
public void youngest_snapshot(Cache<Integer, Integer> cache, CacheContext context,
@ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) {
Map<Integer, Integer> youngest = expireAfterAccess.youngest(Integer.MAX_VALUE);
Expand Down
Loading

0 comments on commit fc57249

Please sign in to comment.