HotEntryCache will update Instants only once per second

Calling Instant.now() several hundred thousand times per
second can be expensive. In my measurements >10% of the
time spend when loading new data was spend calling
Instant.now().
Fixed this by storing an Instant as static member and
updating it periodically in a separate thread.
This commit is contained in:
2018-12-21 19:16:55 +01:00
parent d95a71e32e
commit e537e94d39
4 changed files with 107 additions and 30 deletions

View File

@@ -45,6 +45,7 @@ public class HotEntryCacheTest {
cache.put("key", "value1");
clock.plusSeconds(2);
cache.updateTime();
cache.put("key", "value2");
@@ -64,19 +65,23 @@ public class HotEntryCacheTest {
Assert.assertEquals(cachedValue1_evicted, null);
}
// TODO that does not make sense. Get should not evict. We should be happy that
// the element is still in the map when we need it.
public void testGetEvicts() throws Exception {
public void testGetTouches() throws Exception {
final ModifiableFixedTimeClock clock = new ModifiableFixedTimeClock();
final Duration timeToLive = Duration.ofSeconds(10);
final HotEntryCache<String, String> cache = new HotEntryCache<>(timeToLive, clock);
cache.put("key", "value1");
// skip forward in time, but do not yet trigger eviction
clock.plus(timeToLive.plusMillis(1));
cache.updateTime();
final String cachedValue1_evicted = cache.get("key");
Assert.assertEquals(cachedValue1_evicted, null);
cache.get("key"); // will touch the entry
cache.triggerEvictionAndWait(); // if get didn't touch, then this will evict the entry
final String cachedValue1 = cache.get("key");
Assert.assertEquals(cachedValue1, "value1");
}
public void testEvictionByBackgroundThread() throws InterruptedException, ExecutionException, TimeoutException {
@@ -92,6 +97,7 @@ public class HotEntryCacheTest {
cache.put("key", "value1");
clock.plus(timeToLive.minusSeconds(1));
cache.updateTime();
cache.put("key2", "value2");
clock.plus(Duration.ofSeconds(1).plusMillis(1));
@@ -149,6 +155,7 @@ public class HotEntryCacheTest {
// seek, so that it is almost evicted
clock.plus(timeToLive.minusMillis(1));
cache.updateTime();
// the for each should touch the entries
cache.forEach(s -> {
@@ -156,12 +163,14 @@ public class HotEntryCacheTest {
// seek again
clock.plus(timeToLive.minusMillis(1));
cache.triggerEvictionAndWait();
// if the touch didn't happen, then the value is now evicted
Assert.assertEquals(evictionEventFuture.isDone(), false);
// seek again, so that the entry will get evicted
clock.plus(timeToLive.minusMillis(1));
cache.triggerEvictionAndWait();
Assert.assertEquals(cache.get("key"), null);
}