ConcurrentNodeFactory.java
package edu.udel.cis.vsl.gmc.concurrent;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import edu.udel.cis.vsl.gmc.seq.StateManager;
public class ConcurrentNodeFactory<STATE, TRANSITION> {
/**
* Maps each STATE to a unique {@link SequentialNode}.
*/
private Map<STATE, ConcurrentNode<STATE>> nodeMap = new HashMap<>();
/**
* A {@link StateManager} can be used to compute the next state and
* normalize a state.
*/
private ConcurrentStateManagerIF<STATE, TRANSITION> stateManager;
public ConcurrentNodeFactory(
ConcurrentStateManagerIF<STATE, TRANSITION> stateManager) {
this.stateManager = stateManager;
}
/**
* Implements the fly-weight pattern.
*
* @param state
* @return the existing {@link SequentialNode} mapped to the state, or a new
* {@link SequentialNode} mapped to the state if there was no entry
* in the map for the key state. Note that the
* {@link SequentialNode} will always store the normalized or
* simplified version of {@code state}.
*/
public ConcurrentNode<STATE> getNode(STATE state) {
ConcurrentNode<STATE> result = nodeMap.get(state);
if (result == null) {
STATE normalizedState = stateManager.normalize(state);
if (normalizedState != state) {
result = nodeMap.get(normalizedState);
if (result == null) {
result = new ConcurrentNode<STATE>(normalizedState);
nodeMap.put(normalizedState, result);
}
} else {
result = new ConcurrentNode<STATE>(state);
}
nodeMap.put(state, result);
}
return result;
}
/**
* Construct a new stack entry which will be pushed onto the stack.
*
* @param node
* The {@link SequentialNode} that wraps the source state.
* @param transitions
* This could be the ample set or ample set complement of the
* source state.
* @param full
* Whether {@code transitions} is ample set complement or not.
* @return The newly constructed {@link StackEntry}.
*/
public StackEntry<STATE, TRANSITION> newStackEntry(
ConcurrentNode<STATE> node, Collection<TRANSITION> transitions,
boolean full) {
return new StackEntry<>(node, transitions, full);
}
/**
* @return the number of search nodes saved.
*/
public int numOfSearchNodeSaved() {
return nodeMap.size();
}
}