package util.statemachine.implementation.prover.cache; import java.util.HashMap; import java.util.List; import java.util.Map; import util.cache.TtlCache; import util.statemachine.MachineState; import util.statemachine.Move; import util.statemachine.Role; import util.statemachine.exceptions.GoalDefinitionException; import util.statemachine.exceptions.MoveDefinitionException; import util.statemachine.exceptions.TransitionDefinitionException; import util.statemachine.implementation.prover.ProverStateMachine; public final class CachedProverStateMachine extends ProverStateMachine { private final class Entry { public Map<Role, Integer> goals; public Map<Role, List<Move>> moves; public Map<List<Move>, MachineState> nexts; public Boolean terminal; public Entry() { goals = new HashMap<Role, Integer>(); moves = new HashMap<Role, List<Move>>(); nexts = new HashMap<List<Move>, MachineState>(); terminal = null; } } private final TtlCache<MachineState, Entry> ttlCache; public CachedProverStateMachine() { ttlCache = new TtlCache<MachineState, Entry>(1); } private Entry getEntry(MachineState state) { if (!ttlCache.containsKey(state)) { ttlCache.put(state, new Entry()); } return ttlCache.get(state); } @Override public int getGoal(MachineState state, Role role) throws GoalDefinitionException { Entry entry = getEntry(state); synchronized (entry) { if (!entry.goals.containsKey(role)) { entry.goals.put(role, super.getGoal(state, role)); } return entry.goals.get(role); } } @Override public List<Move> getLegalMoves(MachineState state, Role role) throws MoveDefinitionException { Entry entry = getEntry(state); synchronized (entry) { if (!entry.moves.containsKey(role)) { entry.moves.put(role, super.getLegalMoves(state, role)); } return entry.moves.get(role); } } @Override public MachineState getNextState(MachineState state, List<Move> moves) throws TransitionDefinitionException { Entry entry = getEntry(state); synchronized (entry) { if (!entry.nexts.containsKey(moves)) { entry.nexts.put(moves, super.getNextState(state, moves)); } return entry.nexts.get(moves); } } @Override public boolean isTerminal(MachineState state) { Entry entry = getEntry(state); synchronized (entry) { if (entry.terminal == null) { entry.terminal = super.isTerminal(state); } return entry.terminal; } } @Override public void doPerMoveWork() { prune(); } public void prune() { ttlCache.prune(); } }