/* * ************************************************************************************* * Copyright (C) 2008 EsperTech, Inc. All rights reserved. * * http://esper.codehaus.org * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * * ************************************************************************************* */ package com.espertech.esper.pattern.pool; import com.espertech.esper.client.hook.ConditionPatternEngineSubexpressionMax; import com.espertech.esper.pattern.EvalFollowedByNode; import com.espertech.esper.util.ExecutionPathDebugLog; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.*; import java.util.concurrent.atomic.AtomicLong; public class PatternSubexpressionPoolEngineSvc { private static final Log log = LogFactory.getLog(PatternSubexpressionPoolEngineSvc.class); private volatile long maxPoolCountConfigured; private final boolean preventStart; private final AtomicLong poolCount; private final Set<StatementEntry> patternContexts; public PatternSubexpressionPoolEngineSvc(long maxPoolCountConfigured, boolean preventStart) { this.maxPoolCountConfigured = maxPoolCountConfigured; this.preventStart = preventStart; this.poolCount = new AtomicLong(); this.patternContexts = Collections.synchronizedSet(new HashSet<StatementEntry>()); } public void setPatternMaxSubexpressions(Long maxSubexpressions) { if (maxSubexpressions == null) { maxPoolCountConfigured = -1; } else { maxPoolCountConfigured = maxSubexpressions; } } public void addPatternContext(String statementName, PatternSubexpressionPoolStmtHandler stmtCounts) { patternContexts.add(new StatementEntry(statementName, stmtCounts)); } public void removeStatement(String name) { Set<StatementEntry> removed = new HashSet<StatementEntry>(); for (StatementEntry context : patternContexts) { if (context.getStatementName().equals(name)) { removed.add(context); } } patternContexts.removeAll(removed); } public boolean tryIncreaseCount(EvalFollowedByNode evalFollowedByNode) { // test pool max long newMax = poolCount.incrementAndGet(); if (newMax > maxPoolCountConfigured && maxPoolCountConfigured >= 0) { Map<String, Long> counts = getCounts(); evalFollowedByNode.getContext().getAgentInstanceContext().getStatementContext().getExceptionHandlingService().handleCondition(new ConditionPatternEngineSubexpressionMax(maxPoolCountConfigured, counts), evalFollowedByNode.getContext().getAgentInstanceContext().getStatementContext().getEpStatementHandle()); if ((ExecutionPathDebugLog.isDebugEnabled) && (log.isDebugEnabled() && (ExecutionPathDebugLog.isTimerDebugEnabled))) { PatternSubexpressionPoolStmtHandler stmtHandler = evalFollowedByNode.getContext().getAgentInstanceContext().getStatementContext().getPatternSubexpressionPoolSvc().getStmtHandler(); String stmtName = evalFollowedByNode.getContext().getAgentInstanceContext().getStatementContext().getStatementName(); log.debug(".tryIncreaseCount For statement '" + stmtName + "' pool count overflow at " + newMax + " statement count was " + stmtHandler.getCount() + " preventStart=" + preventStart); } if (preventStart) { poolCount.decrementAndGet(); return false; } else { return true; } } if ((ExecutionPathDebugLog.isDebugEnabled) && log.isDebugEnabled()) { PatternSubexpressionPoolStmtHandler stmtHandler = evalFollowedByNode.getContext().getAgentInstanceContext().getStatementContext().getPatternSubexpressionPoolSvc().getStmtHandler(); String stmtName = evalFollowedByNode.getContext().getAgentInstanceContext().getStatementContext().getStatementName(); log.debug(".tryIncreaseCount For statement '" + stmtName + "' pool count increases to " + newMax + " statement count was " + stmtHandler.getCount()); } return true; } // Relevant for recovery of state public void forceIncreaseCount(EvalFollowedByNode evalFollowedByNode) { long newMax = poolCount.incrementAndGet(); if ((ExecutionPathDebugLog.isDebugEnabled) && log.isDebugEnabled()) { PatternSubexpressionPoolStmtHandler stmtHandler = evalFollowedByNode.getContext().getAgentInstanceContext().getStatementContext().getPatternSubexpressionPoolSvc().getStmtHandler(); String stmtName = evalFollowedByNode.getContext().getAgentInstanceContext().getStatementContext().getStatementName(); log.debug(".forceIncreaseCount For statement '" + stmtName + "' pool count increases to " + newMax + " statement count was " + stmtHandler.getCount()); } } public void decreaseCount(EvalFollowedByNode evalFollowedByNode) { long newMax = poolCount.decrementAndGet(); if ((ExecutionPathDebugLog.isDebugEnabled) && log.isDebugEnabled()) { PatternSubexpressionPoolStmtHandler stmtHandler = evalFollowedByNode.getContext().getAgentInstanceContext().getStatementContext().getPatternSubexpressionPoolSvc().getStmtHandler(); String stmtName = evalFollowedByNode.getContext().getAgentInstanceContext().getStatementContext().getStatementName(); log.debug(".decreaseCount For statement '" + stmtName + "' pool count decreases to " + newMax + " statement count was " + stmtHandler.getCount()); } } private Map<String,Long> getCounts() { Map<String,Long> counts = new HashMap<String,Long>(); for (StatementEntry context : patternContexts) { Long count = counts.get(context.getStatementName()); if (count == null) { count = 0L; } count += context.getStmtCounts().getCount(); counts.put(context.getStatementName(), count); } return counts; } public static class StatementEntry { private final String statementName; private final PatternSubexpressionPoolStmtHandler stmtCounts; public StatementEntry(String statementName, PatternSubexpressionPoolStmtHandler stmtCounts) { this.statementName = statementName; this.stmtCounts = stmtCounts; } public String getStatementName() { return statementName; } public PatternSubexpressionPoolStmtHandler getStmtCounts() { return stmtCounts; } } }