Skip to content

autoMemoize (automatic caching)

johnmcclean-aol edited this page Nov 26, 2015 · 2 revisions

simple-react 0.99.3 and above allow the results of each stage to be cached (or memoized) using a pluggable cache provider (such as a simple ConcurrentMap or Guava cache).

Configuring a cache

The autoMemoizeOn method in LazyReact accepts a Cachable Functional Interface.

public LazyReact autoMemoizeOn( Cachable memoizeCache)

Cachable itself looks like this

public interface Cachable<OUT> {

	public OUT computeIfAbsent(Object key, Function<Object,OUT> fn);
}

This means that autoMemoizeOn accepts a higher-order function with two parameters, the data input (next element in the Stream) into the current Stage of the Stream, and a function that represents the work to be done at that stage of the Stream.

autoMemoize with no caching

To help explain how autoMemoize works, let's take a look at an example that just passes data through to the next stage. In this case we will simply call the provided function, with the data input (cache key).

LazyReact react = new LazyReact().autoMemoizeOn((input,fn)-> fn.apply(input));
List result = react.of("data1","data1","data2","data2")
			   .map(i->calc(i))
			   .toList();

In the above example, no caching occurs, data is simply passed directly to the provided function. But we do now have our Cachable lambda expression acting as an intermediary for every operation!

Next step, let's plugin a simple cache!

autoMemoize with a ConcurrentHashMap

LazyFutureStreams can be configured to cache the results of operations at each stage. Caches can be pluggable so LRU or TTL based caches can be used.

Map cache = new ConcurrentHashMap<>();
LazyReact react = new LazyReact().autoMemoizeOn((key,fn)-> cache.computeIfAbsent(key,fn));
List result = react.of("data1","data1","data2","data2")
			   .map(i->calc(i))
			   .toList();

autoMemoize with a Guava cache

We aren't limited to using ConcurrentHashMaps, we can plug in any cache implementation we like. Let's try a Guava cache!

//configure LRU cache with max time to live
Cache<Object, String> cache = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .expireAfterWrite(10, TimeUnit.MINUTES)
       .build();
       
LazyReact react = new LazyReact().autoMemoizeOn((key,fn)-> cache.get(key,()->fn.apply(key));
List result = react.of("data1","data1","data2","data2")
               .map(i->calc(i))
               .toList();
Clone this wiki locally