package brainslug.flow.execution.token; import brainslug.flow.execution.instance.FlowInstanceTokenList; import brainslug.util.IdGenerator; import brainslug.flow.definition.Identifier; import brainslug.util.Option; import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class HashMapTokenStore implements TokenStore { Map<Identifier, Map<Identifier, Token>> instanceToTokenMap = new ConcurrentHashMap<Identifier, Map<Identifier, Token>>(); IdGenerator idGenerator; public HashMapTokenStore(IdGenerator idGenerator) { this.idGenerator = idGenerator; } public List<Token> tokensForInstance(Identifier instanceId) { return new ArrayList<Token>(getOrCreateInstanceTokenMap(instanceId).values()); } Map<Identifier, Token> getOrCreateInstanceTokenMap(Identifier instanceId) { if (instanceToTokenMap.get(instanceId) == null) { Map<Identifier, Token> instanceTokens = new ConcurrentHashMap<Identifier, Token>(); instanceToTokenMap.put(instanceId, instanceTokens); return instanceTokens; } else { return instanceToTokenMap.get(instanceId); } } @Override public FlowInstanceTokenList getInstanceTokens(Identifier instanceId) { return new TokenList(tokensForInstance(instanceId)); } @Override public FlowInstanceTokenList getNodeTokens(Identifier nodeId, Identifier instanceId) { List<Token> nodeTokens = new ArrayList<Token>(); for (Token instanceToken : tokensForInstance(instanceId)) { if(instanceToken.getNodeId().equals(nodeId) && !instanceToken.isDead()) { nodeTokens.add(instanceToken); } } return new TokenList(nodeTokens); } @Override public Token addToken(Identifier instanceId, Identifier nodeId, Option<Identifier> sourceNodeId, boolean isFinal) { Token token = new Token(idGenerator.generateId(), nodeId, sourceNodeId, instanceId, false, isFinal); getOrCreateInstanceTokenMap(instanceId).put(token.getId(), token); return token; } @Override public boolean setDead(Identifier instanceId, Identifier tokenIdToDelete) { Option<Token> token = findToken(instanceId, tokenIdToDelete); if (token.isPresent()) { token.get().setDead(true); return true; } return false; } private Option<Token> findToken(Identifier instanceId, Identifier tokenIdToDelete) { for (final Iterator<Token> instanceTokens = tokensForInstance(instanceId).iterator(); instanceTokens.hasNext(); ) { Token nextToken = instanceTokens.next(); if (nextToken.getId().equals(tokenIdToDelete)) { return Option.of(nextToken); } } return Option.empty(); } @Override public boolean setFinal(Identifier instanceId, Identifier tokenId) { Option<Token> token = findToken(instanceId, tokenId); if (token.isPresent()) { token.get().setFinal(true); return true; } return false; } }