class DefaultCallInvocationResultCache implements CallInvocationResultCache {

    public <T> T get(String callName, Object[] args, Function<Object[], T> compute) {
        LoadingCache<ObjectsWrapper, Optional<Object>> functionResultCache = cachesPerFunction.get(callName);
        if (functionResultCache == null) {
            functionResultCache = CacheBuilder.<ObjectsWrapper, Optional<Object>>newBuilder()
                    .expireAfterAccess(configuration.getFunctionCacheExpirationTime(callName).toMillis(), TimeUnit.MILLISECONDS)
                    .build(new CacheLoader<ObjectsWrapper, Optional<Object>>() {
                        @Override
                        public Optional<Object> load(ObjectsWrapper arguments) {
                            return Optional.ofNullable((compute.apply(arguments.getObjects())));
                        }
                    });
            cachesPerFunction.putIfAbsent(callName, functionResultCache);
        }
        return (T) functionResultCache.getUnchecked(new ObjectsWrapper(args)).orElse(null);
    }

    public  DefaultCallInvocationResultCache(ExecutorConfiguration configuration);

}