mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
CE-938 update memoization to say if it should store null values or not
This commit is contained in:
@ -43,8 +43,9 @@ public class Memoization<K, V>
|
||||
|
||||
private final Map<K, MemoizedResult<V>> map = Collections.synchronizedMap(new LinkedHashMap<>());
|
||||
|
||||
private Duration timeout = Duration.ofSeconds(600);
|
||||
private Integer maxSize = 1000;
|
||||
private Duration timeout = Duration.ofSeconds(600);
|
||||
private Integer maxSize = 1000;
|
||||
private boolean mayStoreNullValues = true;
|
||||
|
||||
|
||||
|
||||
@ -58,6 +59,40 @@ public class Memoization<K, V>
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Memoization(Integer maxSize)
|
||||
{
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Memoization(Duration timeout)
|
||||
{
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Memoization(Duration timeout, Integer maxSize)
|
||||
{
|
||||
this.timeout = timeout;
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Get the memoized Value for a given input Key - computing it if it wasn't previously
|
||||
** memoized (or expired).
|
||||
@ -153,6 +188,14 @@ public class Memoization<K, V>
|
||||
*******************************************************************************/
|
||||
public void storeResult(K key, V value)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if the value is null, and we're not supposed to store nulls, then return w/o storing //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(value == null && !mayStoreNullValues)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
map.put(key, new MemoizedResult<>(value));
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -277,4 +320,35 @@ public class Memoization<K, V>
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for mayStoreNullValues
|
||||
*******************************************************************************/
|
||||
public boolean getMayStoreNullValues()
|
||||
{
|
||||
return (this.mayStoreNullValues);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for mayStoreNullValues
|
||||
*******************************************************************************/
|
||||
public void setMayStoreNullValues(boolean mayStoreNullValues)
|
||||
{
|
||||
this.mayStoreNullValues = mayStoreNullValues;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for mayStoreNullValues
|
||||
*******************************************************************************/
|
||||
public Memoization<K, V> withMayStoreNullValues(boolean mayStoreNullValues)
|
||||
{
|
||||
this.mayStoreNullValues = mayStoreNullValues;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -119,6 +119,57 @@ class MemoizationTest extends BaseTest
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testMayNotStoreNull()
|
||||
{
|
||||
Memoization<String, String> memoization = new Memoization<>();
|
||||
memoization.setMayStoreNullValues(false);
|
||||
|
||||
AtomicInteger callCounter = new AtomicInteger();
|
||||
callCounter.set(0);
|
||||
UnsafeFunction<String, String, Exception> supplier = name ->
|
||||
{
|
||||
callCounter.getAndIncrement();
|
||||
if(name.equals("throw"))
|
||||
{
|
||||
throw (new Exception("You asked me to throw"));
|
||||
}
|
||||
else if(name.equals("null"))
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (name);
|
||||
}
|
||||
};
|
||||
|
||||
assertThat(memoization.getResult("null", supplier)).isEmpty();
|
||||
assertEquals(1, callCounter.get());
|
||||
|
||||
assertThat(memoization.getResult("null", supplier)).isEmpty();
|
||||
assertEquals(2, callCounter.get()); // should re-run the supplier, incrementing the counter
|
||||
|
||||
assertThat(memoization.getResult("throw", supplier)).isEmpty();
|
||||
assertEquals(3, callCounter.get());
|
||||
|
||||
assertThat(memoization.getResult("throw", supplier)).isEmpty();
|
||||
assertEquals(4, callCounter.get()); // should re-run the supplier, incrementing the counter
|
||||
|
||||
//noinspection AssertBetweenInconvertibleTypes
|
||||
assertThat(memoization.getResult("foo", supplier)).isPresent().get().isEqualTo("foo");
|
||||
assertEquals(5, callCounter.get());
|
||||
|
||||
//noinspection AssertBetweenInconvertibleTypes
|
||||
assertThat(memoization.getResult("foo", supplier)).isPresent().get().isEqualTo("foo");
|
||||
assertEquals(5, callCounter.get()); // should NOT re-run the supplier, NOT incrementing the counter
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
Reference in New Issue
Block a user