org.ggp.base.util.GoalTuplePool Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alloy-ggp-base Show documentation
Show all versions of alloy-ggp-base Show documentation
A modified version of the GGP-Base library for Alloy.
The newest version!
package org.ggp.base.util;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
public class GoalTuplePool {
private static final GoalTuplePoolNode INITIAL_NODE = new GoalTuplePoolNode();
public static class GoalTuplePoolNode {
private final ConcurrentMap children = new ConcurrentHashMap(5, 0.75f, 4);
private final ImmutableList asList;
private final ImmutableIntArray asArray;
private GoalTuplePoolNode() {
this.asList = ImmutableList.of();
this.asArray = ImmutableIntArray.empty();
}
private GoalTuplePoolNode(ImmutableList soFar, int addition) {
this.asList = ImmutableList.copyOf(Iterables.concat(soFar, ImmutableList.of(addition)));
this.asArray = ImmutableIntArray.copyOf(asList);
}
public GoalTuplePoolNode get(Integer value) {
GoalTuplePoolNode result = children.get(value);
if (result != null) {
return result;
}
GoalTuplePoolNode newNode = new GoalTuplePoolNode(asList, value);
children.putIfAbsent(value, newNode);
return children.get(value);
}
public ImmutableList getList() {
return asList;
}
public ImmutableIntArray getArray() {
return asArray;
}
}
/**
* The lowest-level way to get a goal value tuple. This does not require
* any superfluous object creation.
*/
public static GoalTuplePoolNode getInitialNode() {
return INITIAL_NODE;
}
public static ImmutableList canonicalize(List input) {
GoalTuplePoolNode curNode = getInitialNode();
for (Integer goalValue : input) {
curNode = curNode.get(goalValue);
}
return curNode.getList();
}
public static ImmutableList canonicalize(int... input) {
GoalTuplePoolNode curNode = getInitialNode();
for (int goalValue : input) {
curNode = curNode.get(goalValue);
}
return curNode.getList();
}
public static ImmutableIntArray canonicalize(ImmutableIntArray input) {
GoalTuplePoolNode curNode = getInitialNode();
for (int i = 0; i < input.size(); i++) {
curNode = curNode.get(input.get(i));
}
return curNode.getArray();
}
//I expect to get all 0s and all 100s a lot for min and max goal values,
//and having to create these at node creation time
private static final LoadingCache> ALL_ZEROS_CACHE =
CacheBuilder.newBuilder().build(new CacheLoader>() {
@Override
public ImmutableList load(Integer tupleLength) throws Exception {
int[] goalResults = new int[tupleLength];
return canonicalize(goalResults);
}
});
public static ImmutableList getAllZeros(int numRoles) {
return ALL_ZEROS_CACHE.getUnchecked(numRoles);
}
private static final LoadingCache> ALL_HUNDREDS_CACHE =
CacheBuilder.newBuilder().build(new CacheLoader>() {
@Override
public ImmutableList load(Integer tupleLength) throws Exception {
int[] goalResults = new int[tupleLength];
Arrays.fill(goalResults, 100);
return canonicalize(goalResults);
}
});
public static ImmutableList getAllHundreds(int numRoles) {
return ALL_HUNDREDS_CACHE.getUnchecked(numRoles);
}
}