From 425527ddb252737b98bad2e7eb4dc4a059816b99 Mon Sep 17 00:00:00 2001 From: Marc Baloup Date: Sun, 8 Aug 2021 12:56:36 +0200 Subject: [PATCH] Wrapper for lazy loaded values --- .../java/fr/pandacube/lib/core/util/Lazy.java | 48 +++++++++++++++++ .../lib/core/util/LazyOrException.java | 52 +++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 Core/src/main/java/fr/pandacube/lib/core/util/Lazy.java create mode 100644 Core/src/main/java/fr/pandacube/lib/core/util/LazyOrException.java diff --git a/Core/src/main/java/fr/pandacube/lib/core/util/Lazy.java b/Core/src/main/java/fr/pandacube/lib/core/util/Lazy.java new file mode 100644 index 0000000..a50373a --- /dev/null +++ b/Core/src/main/java/fr/pandacube/lib/core/util/Lazy.java @@ -0,0 +1,48 @@ +package fr.pandacube.lib.core.util; + +import java.util.Objects; +import java.util.function.Supplier; + +/** + * Represents a lazy loaded value. + * + * The value will be computed using the Supplier provided in the + * constructor, only the first time the {@link #get()} method is + * called. + * + * @param the type of the enclosed value. + */ +public class Lazy implements Supplier { + + private T cachedValue; + private final Supplier supplier; + private boolean cached = false; + + public Lazy(Supplier s) { + supplier = Objects.requireNonNull(s); + } + + /** + * Get the wrapped value, from cache or from the provider if it is not yet cached. + * + * If the provider throws an exception, it will be redirected to the caller as is, and no value will be cached (the next call to this method will + * execute the supplier again). + */ + @Override + public synchronized T get() { + if (!cached) // check outside synchronized method to reduce useless synchronization if value is already cached + set(supplier.get()); + return cachedValue; + } + + public synchronized void reset() { + cached = false; + cachedValue = null; + } + + public synchronized void set(T value) { + cachedValue = value; + cached = true; + } + +} diff --git a/Core/src/main/java/fr/pandacube/lib/core/util/LazyOrException.java b/Core/src/main/java/fr/pandacube/lib/core/util/LazyOrException.java new file mode 100644 index 0000000..e9bf467 --- /dev/null +++ b/Core/src/main/java/fr/pandacube/lib/core/util/LazyOrException.java @@ -0,0 +1,52 @@ +package fr.pandacube.lib.core.util; + +import java.util.Objects; + +/** + * Represents a lazy loaded value. + * + * The value will be computed using the Supplier provided in the + * constructor, only the first time the {@link #get()} method is + * called. + * + * @param the type of the enclosed value. + */ +public class LazyOrException { + + private T cachedValue; + private final SupplierException supplier; + private boolean cached = false; + + public LazyOrException(SupplierException s) { + supplier = Objects.requireNonNull(s); + } + + /** + * Get the wrapped value, from cache or from the provider if it is not yet cached. + * + * If the provider throws an exception, it will be redirected to the caller as is, and no value will be cached (the next call to this method will + * execute the supplier again). + */ + public synchronized T get() throws Exception { + if (!cached) // check outside synchronized method to reduce useless synchronization if value is already cached + set(supplier.get()); + return cachedValue; + } + + public synchronized void reset() { + cached = false; + cachedValue = null; + } + + public synchronized void set(T value) { + cachedValue = value; + cached = true; + } + + + @FunctionalInterface + public interface SupplierException { + public T get() throws Exception; + } + +}