/*
* Copyright (c) 2017 OBiBa. All rights reserved.
*
* This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.obiba.magma.support;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.SortedSet;
import javax.validation.constraints.NotNull;
import org.obiba.magma.MagmaRuntimeException;
import org.obiba.magma.Value;
import org.obiba.magma.ValueType;
import org.obiba.magma.VariableEntity;
import org.obiba.magma.VectorSource;
import org.springframework.cache.Cache;
import com.google.common.base.Joiner;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
public class CachedVectorSource implements VectorSource {
private Cache cache;
private VectorSource wrapped;
private CachedVariableValueSource variableValueSource;
public CachedVectorSource(@NotNull CachedVariableValueSource variableValueSource, @NotNull Cache cache) {
this.cache = cache;
this.variableValueSource = variableValueSource;
try {
this.wrapped = variableValueSource.getWrapped().asVectorSource();
} catch(MagmaRuntimeException ex) {
//ignore
}
}
@Override
public ValueType getValueType() {
return getCached(getCacheKey("getValueType"), new Supplier<ValueType>() {
@Override
public ValueType get() {
return getWrapped().getValueType();
}
});
}
@Override
public Iterable<Value> getValues(final SortedSet<VariableEntity> entities) {
boolean missing = true;
List<Value> res = new ArrayList<>();
for(VariableEntity variableEntity : entities) {
Cache.ValueWrapper valueWrapper = cache.get(getCacheKey("getValues", variableEntity.getIdentifier()));
if (valueWrapper == null) {
missing = false;
break;
}
res.add((Value)valueWrapper.get());
}
if (!missing) return res;
ArrayList<Value> values = Lists.newArrayList(getWrapped().getValues(entities));
ArrayList<VariableEntity> variableEntities = Lists.newArrayList(entities);
for(int i = 0; i < variableEntities.size(); i++) {
cache.put(getCacheKey("getValues", variableEntities.get(i).getIdentifier()), values.get(i));
}
return values;
}
public VectorSource getWrapped() {
if (wrapped == null) throw new MagmaRuntimeException("wrapped value not initialized");
return wrapped;
}
public void evictValues(VariableEntity variableEntity) {
cache.evict(getCacheKey("getValue", variableEntity.getIdentifier()));
}
private <T> T getCached(Object key, Supplier<T> supplier) {
return CacheUtils.getCached(cache, key, supplier);
}
private String getCacheKey(Object... parts) {
return Joiner
.on(".").join(Iterables.concat(Arrays.asList(variableValueSource.getName(), "VectorSource"), Arrays.asList(parts)));
}
}