diff --git a/src/main/java/part2/cache/CachingDataStorageImpl.java b/src/main/java/part2/cache/CachingDataStorageImpl.java index a2ae460..a9664d5 100755 --- a/src/main/java/part2/cache/CachingDataStorageImpl.java +++ b/src/main/java/part2/cache/CachingDataStorageImpl.java @@ -3,6 +3,7 @@ import db.DataStorage; import db.SlowCompletableFutureDb; +import java.util.Optional; import java.util.concurrent.*; public class CachingDataStorageImpl implements CachingDataStorage { @@ -32,12 +33,29 @@ public CachingDataStorageImpl(DataStorage db, int timeout, TimeUnit t @Override public OutdatableResult getOutdatable(String key) { - // TODO implement - // TODO use ScheduledExecutorService to remove outdated result from cache - see SlowCompletableFutureDb implementation - // TODO complete OutdatableResult::outdated after removing outdated result from cache - // TODO don't use obtrudeException on result - just don't - // TODO use remove(Object key, Object value) to remove target value - // TODO Start timeout after receiving result in CompletableFuture, not after receiving CompletableFuture itself - throw new UnsupportedOperationException(); + + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture outdated = new CompletableFuture<>(); + OutdatableResult outdatableResult = new OutdatableResult<>(result, outdated); + OutdatableResult cachedResult = cache.putIfAbsent(key, outdatableResult); + + if (cachedResult != null) + return cachedResult; + db.get(key).whenComplete((t, thr) -> { + if (thr != null) { + result.completeExceptionally(thr); + } else { + result.complete(t); + } + scheduledExecutorService.schedule( + () -> { + cache.remove(key, outdatableResult); + outdated.complete(null); + }, + timeout, + timeoutUnits); + }); + + return outdatableResult; } }