From 819d0080d4524c96dde8d9650cade9d01b3bb310 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Ho=C3=9F?= Date: Sun, 31 Jul 2016 01:54:56 +0200 Subject: [PATCH] fix #77 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Sebastian Hoß --- README.asciidoc | 2 +- .../GuavaCacheBasedLongUnaryOperatorMemoizer.java | 36 ++++++++ .../xn__ho_hia/memoization/guava/GuavaMemoize.java | 90 ++++++++++++++++++++ ...avaCacheBasedLongUnaryOperatorMemoizerTest.java | 96 ++++++++++++++++++++++ .../guava/GuavaMemoizeCustomKeyTest.java | 17 ++++ .../guava/GuavaMemoizeDefaultsTest.java | 16 ++++ .../memoization/guava/GuavaMemoizeLambdaTest.java | 15 ++++ 7 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 memoization-guava/src/main/java/de/xn__ho_hia/memoization/guava/GuavaCacheBasedLongUnaryOperatorMemoizer.java create mode 100644 memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaCacheBasedLongUnaryOperatorMemoizerTest.java diff --git a/README.asciidoc b/README.asciidoc index 7ded656..9d737a4 100755 --- a/README.asciidoc +++ b/README.asciidoc @@ -211,7 +211,7 @@ _Java link:https://en.wikipedia.org/wiki/Memoization[memoization] library - trad | link:{jdk-api}/java/util/function/LongUnaryOperator.html[LongUnaryOperator] | ✓ -| link:{issue}/77[#77] +| ✓ | link:{issue}/149[#149] | ✓ diff --git a/memoization-guava/src/main/java/de/xn__ho_hia/memoization/guava/GuavaCacheBasedLongUnaryOperatorMemoizer.java b/memoization-guava/src/main/java/de/xn__ho_hia/memoization/guava/GuavaCacheBasedLongUnaryOperatorMemoizer.java new file mode 100644 index 0000000..057c88a --- /dev/null +++ b/memoization-guava/src/main/java/de/xn__ho_hia/memoization/guava/GuavaCacheBasedLongUnaryOperatorMemoizer.java @@ -0,0 +1,36 @@ +/* + * This file is part of memoization.java. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://creativecommons.org/publicdomain/zero/1.0/. No part of memoization.java, + * including this file, may be copied, modified, propagated, or distributed except according to the terms contained + * in the LICENSE file. + */ +package de.xn__ho_hia.memoization.guava; + +import java.util.function.LongFunction; +import java.util.function.LongUnaryOperator; + +import com.google.common.cache.Cache; + +final class GuavaCacheBasedLongUnaryOperatorMemoizer + extends AbstractGuavaCacheBasedMemoizer + implements LongUnaryOperator { + + private final LongFunction keyFunction; + private final LongUnaryOperator function; + + GuavaCacheBasedLongUnaryOperatorMemoizer( + final Cache cache, + final LongFunction keyFunction, + final LongUnaryOperator function) { + super(cache); + this.keyFunction = keyFunction; + this.function = function; + } + + @Override + public long applyAsLong(final long operand) { + final KEY key = keyFunction.apply(operand); + return get(key, givenKey -> Long.valueOf(function.applyAsLong(operand))).longValue(); + } + +} diff --git a/memoization-guava/src/main/java/de/xn__ho_hia/memoization/guava/GuavaMemoize.java b/memoization-guava/src/main/java/de/xn__ho_hia/memoization/guava/GuavaMemoize.java index 890f843..1eb2a10 100755 --- a/memoization-guava/src/main/java/de/xn__ho_hia/memoization/guava/GuavaMemoize.java +++ b/memoization-guava/src/main/java/de/xn__ho_hia/memoization/guava/GuavaMemoize.java @@ -42,6 +42,7 @@ import java.util.function.LongPredicate; import java.util.function.LongSupplier; import java.util.function.LongToDoubleFunction; import java.util.function.LongToIntFunction; +import java.util.function.LongUnaryOperator; import java.util.function.Predicate; import java.util.function.Supplier; @@ -107,6 +108,7 @@ import de.xn__ho_hia.memoization.shared.MemoizationDefaults; * @see LongSupplier * @see LongToDoubleFunction * @see LongToIntFunction + * @see LongUnaryOperator * @see Predicate * @see Supplier * @see Wikipedia: Memoization @@ -2667,6 +2669,94 @@ public final class GuavaMemoize { /** *

+ * Memoizes a {@link LongUnaryOperator} in a Guava {@link Cache}. + *

+ *

Features

+ *
    + *
  • Default cache
  • + *
  • Default cache key
  • + *
+ * + * @param longUnaryOperator + * The {@link LongUnaryOperator} to memoize. + * @return The wrapped {@link LongUnaryOperator}. + */ + public static final LongUnaryOperator longUnaryOperator( + final LongUnaryOperator longUnaryOperator) { + return longUnaryOperator(longUnaryOperator, CacheBuilder.newBuilder().build()); + } + + /** + *

+ * Memoizes a {@link LongUnaryOperator} in a Guava {@link Cache}. + *

+ *

Features

+ *
    + *
  • Custom cache
  • + *
  • Default cache key
  • + *
+ * + * @param longUnaryOperator + * The {@link LongUnaryOperator} to memoize. + * @param cache + * The {@link Cache} to use. + * @return The wrapped {@link LongUnaryOperator}. + */ + public static final LongUnaryOperator longUnaryOperator( + final LongUnaryOperator longUnaryOperator, + final Cache cache) { + return longUnaryOperator(longUnaryOperator, Long::valueOf, cache); + } + + /** + *

+ * Memoizes a {@link LongUnaryOperator} in a Guava {@link Cache}. + *

+ *

Features

+ *
    + *
  • Default cache
  • + *
  • Custom cache key
  • + *
+ * + * @param longUnaryOperator + * The {@link LongUnaryOperator} to memoize. + * @param keyFunction + * The {@link LongFunction} to compute the cache key. + * @return The wrapped {@link LongUnaryOperator}. + */ + public static final LongUnaryOperator longUnaryOperator( + final LongUnaryOperator longUnaryOperator, + final LongFunction keyFunction) { + return longUnaryOperator(longUnaryOperator, keyFunction, CacheBuilder.newBuilder().build()); + } + + /** + *

+ * Memoizes a {@link LongUnaryOperator} in a Guava {@link Cache}. + *

+ *

Features

+ *
    + *
  • Custom cache
  • + *
  • Custom cache key
  • + *
+ * + * @param longUnaryOperator + * The {@link LongUnaryOperator} to memoize. + * @param keyFunction + * The {@link LongFunction} to compute the cache key. + * @param cache + * The {@link Cache} to use. + * @return The wrapped {@link LongUnaryOperator}. + */ + public static final LongUnaryOperator longUnaryOperator( + final LongUnaryOperator longUnaryOperator, + final LongFunction keyFunction, + final Cache cache) { + return new GuavaCacheBasedLongUnaryOperatorMemoizer<>(cache, keyFunction, longUnaryOperator); + } + + /** + *

* Memoizes a {@link Predicate} in a Guava {@link Cache}. *

*

Features

diff --git a/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaCacheBasedLongUnaryOperatorMemoizerTest.java b/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaCacheBasedLongUnaryOperatorMemoizerTest.java new file mode 100644 index 0000000..3486afa --- /dev/null +++ b/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaCacheBasedLongUnaryOperatorMemoizerTest.java @@ -0,0 +1,96 @@ +/* + * This file is part of memoization.java. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://creativecommons.org/publicdomain/zero/1.0/. No part of memoization.java, + * including this file, may be copied, modified, propagated, or distributed except according to the terms contained + * in the LICENSE file. + */ +package de.xn__ho_hia.memoization.guava; + +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.any; + +import java.util.concurrent.ExecutionException; +import java.util.function.LongFunction; +import java.util.function.LongUnaryOperator; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mockito; + +import de.xn__ho_hia.memoization.shared.MemoizationException; +import de.xn__ho_hia.quality.suppression.CompilerWarnings; + +/** + * + * + */ +@SuppressWarnings({ CompilerWarnings.NLS, CompilerWarnings.STATIC_METHOD }) +public class GuavaCacheBasedLongUnaryOperatorMemoizerTest { + + /** Captures expected exceptions. */ + @Rule + public ExpectedException thrown = ExpectedException.none(); + + /** + * + */ + @Test + public void shouldAcceptLoadingCache() { + // given + final LongUnaryOperator function = a -> 123; + final LongFunction keyFunction = Long::valueOf; + final Cache cache = CacheBuilder.newBuilder().build(); + + // when + final GuavaCacheBasedLongUnaryOperatorMemoizer memoizer = new GuavaCacheBasedLongUnaryOperatorMemoizer<>( + cache, keyFunction, function); + + // then + Assert.assertNotNull(memoizer); + } + + /** + * + */ + @Test + public void shouldTransformInput() { + // given + final LongUnaryOperator function = a -> 123; + final LongFunction keyFunction = Long::valueOf; + final Cache cache = CacheBuilder.newBuilder().build(); + + // when + final GuavaCacheBasedLongUnaryOperatorMemoizer memoizer = new GuavaCacheBasedLongUnaryOperatorMemoizer<>( + cache, keyFunction, function); + + // then + Assert.assertEquals("Memoized value does not match expectation", 123, memoizer.applyAsLong(789)); + } + + /** + * @throws ExecutionException + * Added for the call to 'cache.get(..)'. + */ + @Test + @SuppressWarnings(CompilerWarnings.UNCHECKED) + public void shouldWrapExecutionExceptionInMemoizationException() throws ExecutionException { + // given + final LongFunction keyFunction = Long::valueOf; + final Cache cache = Mockito.mock(Cache.class); + given(cache.get(any(), any())).willThrow(ExecutionException.class); + final GuavaCacheBasedLongUnaryOperatorMemoizer memoizer = new GuavaCacheBasedLongUnaryOperatorMemoizer<>( + cache, keyFunction, null); + + // when + thrown.expect(MemoizationException.class); + + // then + memoizer.applyAsLong(789); + } + +} diff --git a/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeCustomKeyTest.java b/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeCustomKeyTest.java index 7259669..e66096f 100644 --- a/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeCustomKeyTest.java +++ b/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeCustomKeyTest.java @@ -35,6 +35,7 @@ import java.util.function.LongPredicate; import java.util.function.LongSupplier; import java.util.function.LongToDoubleFunction; import java.util.function.LongToIntFunction; +import java.util.function.LongUnaryOperator; import java.util.function.Predicate; import java.util.function.Supplier; @@ -521,6 +522,22 @@ public class GuavaMemoizeCustomKeyTest { * */ @Test + public void shouldMemoizeLongUnaryOperatorWithKeyFunction() { + // given + final LongUnaryOperator function = a -> 123; + final LongFunction keyFunction = a -> "key"; + + // when + final LongUnaryOperator memoize = GuavaMemoize.longUnaryOperator(function, keyFunction); + + // then + Assert.assertNotNull("Memoized LongUnaryOperator is NULL", memoize); + } + + /** + * + */ + @Test public void shouldMemoizePredicateWithKeyFunction() { // given final Predicate predicate = a -> true; diff --git a/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeDefaultsTest.java b/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeDefaultsTest.java index 52b8f5f..58daa35 100644 --- a/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeDefaultsTest.java +++ b/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeDefaultsTest.java @@ -35,6 +35,7 @@ import java.util.function.LongPredicate; import java.util.function.LongSupplier; import java.util.function.LongToDoubleFunction; import java.util.function.LongToIntFunction; +import java.util.function.LongUnaryOperator; import java.util.function.Predicate; import java.util.function.Supplier; @@ -489,6 +490,21 @@ public class GuavaMemoizeDefaultsTest { * */ @Test + public void shouldMemoizeLongUnaryOperator() { + // given + final LongUnaryOperator function = a -> 123; + + // when + final LongUnaryOperator memoize = GuavaMemoize.longUnaryOperator(function); + + // then + Assert.assertNotNull("Memoized LongUnaryOperator is NULL", memoize); + } + + /** + * + */ + @Test public void shouldMemoizePredicate() { // given final Predicate predicate = a -> true; diff --git a/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeLambdaTest.java b/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeLambdaTest.java index 4536e3a..6fd1e7a 100644 --- a/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeLambdaTest.java +++ b/memoization-guava/src/test/java/de/xn__ho_hia/memoization/guava/GuavaMemoizeLambdaTest.java @@ -35,6 +35,7 @@ import java.util.function.LongPredicate; import java.util.function.LongSupplier; import java.util.function.LongToDoubleFunction; import java.util.function.LongToIntFunction; +import java.util.function.LongUnaryOperator; import java.util.function.Predicate; import java.util.function.Supplier; @@ -460,6 +461,20 @@ public class GuavaMemoizeLambdaTest { * */ @Test + public void shouldMemoizeLongUnaryOperatorWithLambda() { + // given + + // when + final LongUnaryOperator memoize = GuavaMemoize.longUnaryOperator(a -> 123); + + // then + Assert.assertNotNull("Memoized LongUnaryOperator is NULL", memoize); + } + + /** + * + */ + @Test public void shouldMemoizePredicateWithLambda() { // given -- 2.11.4.GIT