All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ai.stapi.schema.scopeProvider.ScopeCacher Maven / Gradle / Ivy

There is a newer version: 0.3.2
Show newest version
package ai.stapi.schema.scopeProvider;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class ScopeCacher {

  private final ScopeProvider scopeProvider;
  private final Map, Object>> cache;

  public ScopeCacher(ScopeProvider scopeProvider) {
    this.scopeProvider = scopeProvider;
    this.cache = new ConcurrentHashMap<>();
  }

  public void cache(Class consumerClass, Object cachedData) {
    var currentScope = this.scopeProvider.provide();
    var scoped = this.getCurrentScopeCache(currentScope);
    scoped.put(consumerClass, cachedData);
  }

  public boolean hasCached(Class consumerClass) {
    var currentScope = this.scopeProvider.provide();
    var scoped = this.getCurrentScopeCache(currentScope);
    return scoped.containsKey(consumerClass);
  }

  public  T getCachedOrCompute(
      Class consumerClass,
      ComputeFunction computeFunction
  ) {
    var currentScope = this.scopeProvider.provide();
    var scoped = this.getCurrentScopeCache(currentScope);
    var current = (T) scoped.get(consumerClass);
    if (current != null) {
      return current;
    }
    var computed = computeFunction.compute(currentScope);
    scoped.put(consumerClass, computed);
    return computed;
  }

  @Nullable
  public  T getCached(Class consumerClass) {
    var currentScope = this.scopeProvider.provide();
    var scoped = this.getCurrentScopeCache(currentScope);
    return (T) scoped.get(consumerClass);
  }

  public  T recompute(
      Class consumerClass,
      T initialValue,
      RecomputeWithInitialValueFunction computeFunction
  ) {
    var currentScope = this.scopeProvider.provide();
    var scoped = this.getCurrentScopeCache(currentScope);
    var previous = (T) scoped.get(consumerClass);
    var newCache = computeFunction.compute(
        currentScope,
        previous == null ? initialValue : previous
    );
    scoped.put(consumerClass, newCache);

    return newCache;
  }

  public  T recompute(
      Class consumerClass,
      RecomputeFunction computeFunction
  ) {
    var currentScope = this.scopeProvider.provide();
    var scoped = this.getCurrentScopeCache(currentScope);
    var previous = (T) scoped.get(consumerClass);
    var newCache = computeFunction.compute(
        currentScope,
        previous == null ? Optional.empty() : Optional.of(previous)
    );
    scoped.put(consumerClass, newCache);

    return newCache;
  }

  @NotNull
  private Map, Object> getCurrentScopeCache(ScopeOptions currentScope) {
    return this.cache.computeIfAbsent(
        currentScope,
        key -> new ConcurrentHashMap<>()
    );
  }

  public interface ComputeFunction {

    T compute(ScopeOptions scopeOptions);
  }

  public interface RecomputeFunction {

    T compute(ScopeOptions scopeOptions, Optional previous);
  }

  public interface RecomputeWithInitialValueFunction {

    T compute(ScopeOptions scopeOptions, T previous);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy