diff --git a/src/main/java/part2/cache/CachingDataStorageImpl.java b/src/main/java/part2/cache/CachingDataStorageImpl.java index a2ae460..5004191 100755 --- a/src/main/java/part2/cache/CachingDataStorageImpl.java +++ b/src/main/java/part2/cache/CachingDataStorageImpl.java @@ -1,8 +1,6 @@ package part2.cache; import db.DataStorage; -import db.SlowCompletableFutureDb; - import java.util.concurrent.*; public class CachingDataStorageImpl implements CachingDataStorage { @@ -17,27 +15,44 @@ public class CachingDataStorageImpl implements CachingDataStorage private final ThreadFactory threadFactory = Executors.defaultThreadFactory(); @Override - public Thread newThread(Runnable r) { + public Thread newThread (Runnable r) { final Thread thread = threadFactory.newThread(r); thread.setDaemon(true); return thread; } }); - public CachingDataStorageImpl(DataStorage db, int timeout, TimeUnit timeoutUnits) { + public CachingDataStorageImpl (DataStorage db, int timeout, TimeUnit timeoutUnits) { this.db = db; this.timeout = timeout; this.timeoutUnits = timeoutUnits; } @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(); + public OutdatableResult getOutdatable (String key) { + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture outdated = new CompletableFuture<>(); + OutdatableResult outdateResult = new OutdatableResult<>(result, outdated); + OutdatableResult cacheResult = cache.putIfAbsent(key, outdateResult); + + if (cacheResult != null) { + return outdateResult; + } + + db.get(key) + .whenComplete((t, throwable) -> { + if (throwable != null) { + result.completeExceptionally(throwable); + } else { + result.complete(t); + } + scheduledExecutorService.schedule(() -> { + cache.remove(key, outdateResult); + outdated.complete(null); + }, + timeout, + timeoutUnits); + }); + return outdateResult; } -} +} \ No newline at end of file