diff --git a/src/main/java/com/yegor256/tojos/CachedTojos.java b/src/main/java/com/yegor256/tojos/CachedTojos.java new file mode 100644 index 0000000..ae69e35 --- /dev/null +++ b/src/main/java/com/yegor256/tojos/CachedTojos.java @@ -0,0 +1,73 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2022 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.yegor256.tojos; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * The wrapper which caches underlying tojos. + * Modify operation clears the cache. + * This class is NOT thread-safe. + * @since 1.0 + */ +public final class CachedTojos implements Tojos { + + /** + * Underlying tojos. + */ + private final Tojos wrapped; + + /** + * Cache for tojos. + */ + private final List cache; + + /** + * Ctor. + * @param wrapped Tojos which need to be cached + */ + public CachedTojos(final Tojos wrapped) { + this.wrapped = wrapped; + this.cache = new ArrayList<>(0); + } + + @Override + public Tojo add(final String name) { + this.cache.clear(); + return this.wrapped.add(name); + } + + @Override + public List select(final Predicate filter) { + if (this.cache.isEmpty()) { + this.cache.addAll(this.wrapped.select(x -> true)); + } + return this.cache.stream() + .filter(filter) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/yegor256/tojos/MonoTojos.java b/src/main/java/com/yegor256/tojos/MonoTojos.java index e0d3a5e..722ddc2 100644 --- a/src/main/java/com/yegor256/tojos/MonoTojos.java +++ b/src/main/java/com/yegor256/tojos/MonoTojos.java @@ -29,7 +29,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.function.Function; +import java.util.function.Predicate; /** * All tojos in a {@link Mono}. @@ -75,12 +75,12 @@ public Tojo add(final String name) { } @Override - public List select(final Function filter) { + public List select(final Predicate filter) { final Collection> rows = this.mono.read(); final List tojos = new ArrayList<>(rows.size()); for (final Map row : rows) { final Tojo tojo = new MonoTojo(this.mono, row.get(Tojos.KEY)); - if (filter.apply(tojo)) { + if (filter.test(tojo)) { tojos.add(tojo); } } diff --git a/src/main/java/com/yegor256/tojos/SmartTojos.java b/src/main/java/com/yegor256/tojos/SmartTojos.java index 6b8ddf7..9805a0d 100644 --- a/src/main/java/com/yegor256/tojos/SmartTojos.java +++ b/src/main/java/com/yegor256/tojos/SmartTojos.java @@ -24,7 +24,7 @@ package com.yegor256.tojos; import java.util.List; -import java.util.function.Function; +import java.util.function.Predicate; /** * All file-objects. @@ -80,7 +80,7 @@ public Tojo add(final String name) { } @Override - public List select(final Function filter) { + public List select(final Predicate filter) { return this.origin.select(filter); } } diff --git a/src/main/java/com/yegor256/tojos/Tojos.java b/src/main/java/com/yegor256/tojos/Tojos.java index 1beeb1f..a8c827e 100644 --- a/src/main/java/com/yegor256/tojos/Tojos.java +++ b/src/main/java/com/yegor256/tojos/Tojos.java @@ -24,7 +24,7 @@ package com.yegor256.tojos; import java.util.List; -import java.util.function.Function; +import java.util.function.Predicate; /** * Text Object Java Object (TOJO) in a storage. @@ -61,6 +61,6 @@ public interface Tojos { * @param filter The filter * @return Collection of them */ - List select(Function filter); + List select(Predicate filter); } diff --git a/src/test/java/com/yegor256/tojos/CachedTojosTest.java b/src/test/java/com/yegor256/tojos/CachedTojosTest.java new file mode 100644 index 0000000..724edd7 --- /dev/null +++ b/src/test/java/com/yegor256/tojos/CachedTojosTest.java @@ -0,0 +1,70 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2022 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.yegor256.tojos; + +import java.nio.file.Path; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +/** + * Test for cached tojos. Not thread-safe. + * @since 1.0 + * @checkstyle MagicNumberCheck (70 lines) + */ +class CachedTojosTest { + + @Test + void testAddClearsCache(@TempDir final Path temp) { + final Tojos tojos = new MonoTojos(new Csv(temp.resolve("my-tojos-1.csv"))); + final String[] keys = new String[] {"k10", "k20"}; + tojos.add("A0").set(keys[0], "v10").set(keys[1], "vv10"); + tojos.add("B0").set(keys[0], "v20").set(keys[1], "vv20"); + tojos.add("C0").set(keys[0], "v30").set(keys[1], "vv30"); + final Tojos cached = new CachedTojos(tojos); + cached.select(x -> true); + cached.add("D0").set(keys[0], "v40").set(keys[1], "vv40"); + MatcherAssert.assertThat( + cached.select(x -> true).size(), + Matchers.equalTo(4) + ); + } + + @Test + void testSelectFromCached(@TempDir final Path temp) { + final Tojos tojos = new MonoTojos(new Csv(temp.resolve("my-tojos-2.csv"))); + final String[] keys = new String[] {"k11", "k21"}; + tojos.add("A1").set(keys[0], "v11").set(keys[1], "vv11"); + tojos.add("B1").set(keys[0], "v21").set(keys[1], "vv21"); + tojos.add("C1").set(keys[0], "v31").set(keys[1], "vv31"); + final Tojos cached = new CachedTojos(tojos); + cached.select(x -> true); + tojos.add("D1").set(keys[0], "v41").set(keys[1], "vv41"); + MatcherAssert.assertThat( + cached.select(x -> true).size(), + Matchers.equalTo(3) + ); + } +}