diff --git a/src/main/java/part3/exercise/ComposeCachingDataStorage.java b/src/main/java/part3/exercise/ComposeCachingDataStorage.java index 64d1b3d..d59cbf2 100755 --- a/src/main/java/part3/exercise/ComposeCachingDataStorage.java +++ b/src/main/java/part3/exercise/ComposeCachingDataStorage.java @@ -2,20 +2,40 @@ import part2.cache.CachingDataStorage; +import java.util.concurrent.CompletableFuture; import java.util.function.Function; public class ComposeCachingDataStorage implements CachingDataStorage { + private final CachingDataStorage storage1; + private final CachingDataStorage storage2; + private final Function mapping; public ComposeCachingDataStorage(CachingDataStorage storage1, CachingDataStorage storage2, Function mapping) { - // TODO - throw new UnsupportedOperationException(); + this.storage1 = storage1; + this.storage2 = storage2; + this.mapping = mapping; } + @Override public OutdatableResult getOutdatable(K1 key) { - // TODO - throw new UnsupportedOperationException(); + final OutdatableResult outdatable = storage1.getOutdatable(key); + final CompletableFuture> outdated + = outdatable.getResult().thenApply(v -> storage2.getOutdatable(mapping.apply(v))); + + final OutdatableResult result + = new OutdatableResult<>(new CompletableFuture<>(), new CompletableFuture<>()); + + outdatable.getOutdated().thenAccept(v -> result.getOutdated().complete(v)); + + outdated.thenAccept(v -> { + v.getResult().thenAccept(t -> { + result.getResult().complete(t); + result.getOutdated().thenAccept(o -> result.getOutdated().complete(o)); + }); + }); + return result; } } diff --git a/src/main/java/part3/exercise/ListCachingDataStorage.java b/src/main/java/part3/exercise/ListCachingDataStorage.java index bb47836..be942cb 100755 --- a/src/main/java/part3/exercise/ListCachingDataStorage.java +++ b/src/main/java/part3/exercise/ListCachingDataStorage.java @@ -3,17 +3,44 @@ import part2.cache.CachingDataStorage; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.stream.Collectors; public class ListCachingDataStorage implements CachingDataStorage, List> { + private final CachingDataStorage storage; public ListCachingDataStorage(CachingDataStorage storage) { - // TODO - throw new UnsupportedOperationException(); + this.storage = storage; + } + + private T getOrNull(Future f) { + try { + return f.get(); + } catch (InterruptedException | ExecutionException e1) { + e1.printStackTrace(); + return null; + } } @Override public OutdatableResult> getOutdatable(List key) { - // TODO - throw new UnsupportedOperationException(); + final List> collect = key.stream() + .map(storage::getOutdatable) + .collect(Collectors.toList()); + + final CompletableFuture voidCompletableFuture = CompletableFuture.allOf(collect.stream() + .map(OutdatableResult::getResult) + .toArray(CompletableFuture[]::new)); + + return new OutdatableResult<>(voidCompletableFuture.thenApply(v -> collect.stream() + .map(OutdatableResult::getResult) + .map(this::getOrNull) + .collect(Collectors.toList())), + CompletableFuture.anyOf(collect.stream() + .map(OutdatableResult::getOutdated) + .toArray(CompletableFuture[]::new)) + .thenApply(v -> null)); } } diff --git a/src/main/java/part3/exercise/MappingCachingDataStorage.java b/src/main/java/part3/exercise/MappingCachingDataStorage.java index 39ef5ea..1ca489c 100755 --- a/src/main/java/part3/exercise/MappingCachingDataStorage.java +++ b/src/main/java/part3/exercise/MappingCachingDataStorage.java @@ -6,17 +6,23 @@ import java.util.function.Function; public class MappingCachingDataStorage implements CachingDataStorage { + private final CachingDataStorage storage; + private final Function mapKey; + private final BiFunction mapValue; public MappingCachingDataStorage(CachingDataStorage storage, Function mapKey, BiFunction mapValue) { - // TODO - throw new UnsupportedOperationException(); + this.storage = storage; + this.mapKey = mapKey; + this.mapValue = mapValue; } @Override public OutdatableResult getOutdatable(K key) { - // TODO - throw new UnsupportedOperationException(); + final OutdatableResult outdatable = storage.getOutdatable(mapKey.apply(key)); + + return new OutdatableResult<>(outdatable.getResult().thenApply(v -> mapValue.apply(key, v)), + outdatable.getOutdated()); } } diff --git a/src/main/java/part3/exercise/PairCachingDataStorage.java b/src/main/java/part3/exercise/PairCachingDataStorage.java index fa3a735..9b07d0b 100755 --- a/src/main/java/part3/exercise/PairCachingDataStorage.java +++ b/src/main/java/part3/exercise/PairCachingDataStorage.java @@ -2,23 +2,35 @@ import part2.cache.CachingDataStorage; +import java.util.concurrent.CompletableFuture; import java.util.function.BiFunction; import java.util.function.Function; public class PairCachingDataStorage implements CachingDataStorage { + private final CachingDataStorage storage1; + private final CachingDataStorage storage2; + private final Function getKey1; + private final Function getKey2; + private final Function> resultMapper; + public PairCachingDataStorage(CachingDataStorage storage1, CachingDataStorage storage2, Function getKey1, Function getKey2, Function> resultMapper) { - // TODO - throw new UnsupportedOperationException(); + this.storage1 = storage1; + this.storage2 = storage2; + this.getKey1 = getKey1; + this.getKey2 = getKey2; + this.resultMapper = resultMapper; } @Override public OutdatableResult getOutdatable(K key) { - // TODO - throw new UnsupportedOperationException(); + final OutdatableResult outdatable = storage1.getOutdatable(getKey1.apply(key)); + final OutdatableResult outdatable1 = storage2.getOutdatable(getKey2.apply(key)); + return new OutdatableResult<>(outdatable.getResult().thenCombine(outdatable1.getResult(), resultMapper.apply(key)), + CompletableFuture.anyOf(outdatable.getOutdated(), outdatable1.getOutdated()).thenApply(x -> null)); } }