/*******************************************************************************
* (c) Copyright 2016 Hewlett-Packard Development Company, L.P.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Apache License v2.0 which accompany this distribution.
*
* The Apache License is available at
* http://www.apache.org/licenses/LICENSE-2.0
*
*******************************************************************************/
package io.cloudslang.lang.compiler.caching;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import io.cloudslang.lang.compiler.SlangSource;
import io.cloudslang.lang.compiler.modeller.result.ExecutableModellingResult;
import java.util.concurrent.TimeUnit;
import org.apache.commons.codec.digest.DigestUtils;
import javax.annotation.PostConstruct;
public class CachedPrecompileServiceImpl implements CachedPrecompileService {
private Cache<String, CacheValue> cache;
@PostConstruct
public void init() {
cache = CacheBuilder.newBuilder()
.maximumSize(500)
.concurrencyLevel(2 * Runtime.getRuntime().availableProcessors())
.expireAfterWrite(60, TimeUnit.MINUTES)
.build();
}
@Override
public void cacheValue(String path, ExecutableModellingResult modellingResult, SlangSource source) {
if (path != null) {
CacheValue cacheValue = new CacheValue(source, modellingResult);
cache.put(path, cacheValue);
}
}
@Override
public CacheResult getValueFromCache(String path, SlangSource currentSource) {
if (path == null) {
return null;
}
CacheValue cachedValue = cache.getIfPresent(path);
CacheValueState state;
ExecutableModellingResult executableModellingResult = null;
if (cachedValue == null) {
state = CacheValueState.MISSING;
} else {
if (hasChangedSinceCached(currentSource, cachedValue.getSource())) {
state = CacheValueState.OUTDATED;
} else {
state = CacheValueState.VALID;
executableModellingResult = cachedValue.getExecutableModellingResult();
}
}
return new CacheResult(state, executableModellingResult);
}
@Override
public void invalidateEntry(String path) {
if (path != null) {
cache.invalidate(path);
}
}
@Override
public void invalidateAll() {
cache.invalidateAll();
}
boolean hasChangedSinceCached(SlangSource source1, SlangSource source2) {
String source1AsStr = source1.toString();
String source2AsStr = source2.toString();
return (source1AsStr.length() != source2AsStr.length()) ||
(!DigestUtils.md5Hex(source1AsStr).equals(DigestUtils.md5Hex(source2AsStr))) ||
(!DigestUtils.sha256Hex(source1AsStr).equals(DigestUtils.sha256Hex(source2AsStr)));
}
}