package org.n3r.eql.cache; import com.google.common.base.Optional; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import lombok.val; import org.apache.commons.lang3.StringUtils; import org.n3r.diamond.client.Miner; import org.n3r.diamond.client.Minerable; import org.n3r.eql.impl.EqlUniqueSqlId; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; public class DiamondGuavaCacheProvider implements EqlCacheProvider { public static final String EQL_CACHE = "EQL.CACHE"; Cache<EqlUniqueSqlId, Cache<EqlCacheKey, Optional<Object>>> cache = CacheBuilder.newBuilder().build(); Cache<EqlUniqueSqlId, Optional<String>> cachEQLIdVersion = CacheBuilder.newBuilder().build(); @Override public Optional<Object> getCache(EqlCacheKey cacheKey) { val uniqueSQLId = cacheKey.getUniqueSQLId(); val cachedSqlIdVersion = cachEQLIdVersion.getIfPresent(uniqueSQLId); if (cachedSqlIdVersion == null) return null; String sqlIdVersion = getSqlIdCacheVersion(uniqueSQLId); if (!StringUtils.equals(sqlIdVersion, cachedSqlIdVersion.orNull())) { cache.invalidate(uniqueSQLId); cachEQLIdVersion.put(uniqueSQLId, Optional.fromNullable(sqlIdVersion)); return null; } val subCache = cache.getIfPresent(uniqueSQLId); if (subCache == null) return null; return subCache.getIfPresent(cacheKey); } @Override public void setCache(final EqlCacheKey cacheKey, Object result) { val uniqueSQLId = cacheKey.getUniqueSQLId(); try { val subCache = cache.get(uniqueSQLId, new Callable<Cache<EqlCacheKey, Optional<Object>>>() { @Override public Cache<EqlCacheKey, Optional<Object>> call() throws Exception { String sqlIdVersion = getSqlIdCacheVersion(uniqueSQLId); cachEQLIdVersion.put(uniqueSQLId, Optional.fromNullable(sqlIdVersion)); Cache<EqlCacheKey, Optional<Object>> subCache = CacheBuilder.newBuilder().build(); return subCache; } }); subCache.put(cacheKey, Optional.fromNullable(result)); } catch (ExecutionException e) { // should not happened } } private String getSqlIdCacheVersion(EqlUniqueSqlId uniquEQLId) { final String dataId = uniquEQLId.getSqlClassPath().replaceAll("/", "."); Minerable sqlFileProperties = new Miner().getMiner(EQL_CACHE, dataId); String key = uniquEQLId.getSqlId() + ".cacheVersion"; return sqlFileProperties.getString(key); } }