/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * 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.epl.named; import com.espertech.esper.client.EventType; import com.espertech.esper.core.service.StatementAgentInstanceLock; import com.espertech.esper.core.service.StatementContext; import com.espertech.esper.core.service.StatementResultService; import com.espertech.esper.epl.lookup.IndexMultiKey; import com.espertech.esper.epl.metric.MetricReportingService; import com.espertech.esper.event.vaevent.ValueAddEventProcessor; import com.espertech.esper.view.ViewProcessingException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * This service hold for each named window a dedicated processor and a lock to the named window. * This lock is shrared between the named window and on-delete statements. */ public class NamedWindowMgmtServiceImpl implements NamedWindowMgmtService { private final Map<String, NamedWindowProcessor> processors; private final Map<String, NamedWindowLockPair> windowStatementLocks; private final Set<NamedWindowLifecycleObserver> observers; private final boolean enableQueryPlanLog; private final MetricReportingService metricReportingService; public NamedWindowMgmtServiceImpl(boolean enableQueryPlanLog, MetricReportingService metricReportingService) { this.processors = new HashMap<String, NamedWindowProcessor>(); this.windowStatementLocks = new HashMap<String, NamedWindowLockPair>(); this.observers = new HashSet<NamedWindowLifecycleObserver>(); this.enableQueryPlanLog = enableQueryPlanLog; this.metricReportingService = metricReportingService; } public void destroy() { processors.clear(); } public String[] getNamedWindows() { Set<String> names = processors.keySet(); return names.toArray(new String[names.size()]); } public StatementAgentInstanceLock getNamedWindowLock(String windowName) { NamedWindowLockPair pair = windowStatementLocks.get(windowName); if (pair == null) { return null; } return pair.getLock(); } public void addNamedWindowLock(String windowName, StatementAgentInstanceLock statementResourceLock, String statementName) { windowStatementLocks.put(windowName, new NamedWindowLockPair(statementName, statementResourceLock)); } public void removeNamedWindowLock(String statementName) { for (Map.Entry<String, NamedWindowLockPair> entry : windowStatementLocks.entrySet()) { if (entry.getValue().getStatementName().equals(statementName)) { windowStatementLocks.remove(entry.getKey()); return; } } } public boolean isNamedWindow(String name) { return processors.containsKey(name); } public NamedWindowProcessor getProcessor(String name) { return processors.get(name); } public IndexMultiKey[] getNamedWindowIndexes(String windowName) { NamedWindowProcessor processor = processors.get(windowName); if (processor == null) { return null; } return processor.getProcessorInstance(null).getIndexDescriptors(); } public void removeNamedWindowIfFound(String namedWindowName) { NamedWindowProcessor processor = processors.get(namedWindowName); if (processor == null) { return; } processor.clearProcessorInstances(); removeProcessor(namedWindowName); } public NamedWindowProcessor addProcessor(String name, String contextName, EventType eventType, StatementResultService statementResultService, ValueAddEventProcessor revisionProcessor, String eplExpression, String statementName, boolean isPrioritized, boolean isEnableSubqueryIndexShare, boolean isBatchingDataWindow, boolean isVirtualDataWindow, Set<String> optionalUniqueKeyProps, String eventTypeAsName, StatementContext statementContextCreateWindow, NamedWindowDispatchService namedWindowDispatchService) throws ViewProcessingException { if (processors.containsKey(name)) { throw new ViewProcessingException("A named window by name '" + name + "' has already been created"); } NamedWindowProcessor processor = namedWindowDispatchService.createProcessor(name, this, namedWindowDispatchService, contextName, eventType, statementResultService, revisionProcessor, eplExpression, statementName, isPrioritized, isEnableSubqueryIndexShare, enableQueryPlanLog, metricReportingService, isBatchingDataWindow, isVirtualDataWindow, optionalUniqueKeyProps, eventTypeAsName, statementContextCreateWindow); processors.put(name, processor); if (!observers.isEmpty()) { NamedWindowLifecycleEvent theEvent = new NamedWindowLifecycleEvent(name, processor, NamedWindowLifecycleEvent.LifecycleEventType.CREATE); for (NamedWindowLifecycleObserver observer : observers) { observer.observe(theEvent); } } return processor; } public void removeProcessor(String name) { NamedWindowProcessor processor = processors.get(name); if (processor != null) { processor.destroy(); processors.remove(name); if (!observers.isEmpty()) { NamedWindowLifecycleEvent theEvent = new NamedWindowLifecycleEvent(name, processor, NamedWindowLifecycleEvent.LifecycleEventType.DESTROY); for (NamedWindowLifecycleObserver observer : observers) { observer.observe(theEvent); } } } } public void addObserver(NamedWindowLifecycleObserver observer) { observers.add(observer); } public void removeObserver(NamedWindowLifecycleObserver observer) { observers.remove(observer); } private static class NamedWindowLockPair { private final String statementName; private final StatementAgentInstanceLock lock; private NamedWindowLockPair(String statementName, StatementAgentInstanceLock lock) { this.statementName = statementName; this.lock = lock; } public String getStatementName() { return statementName; } public StatementAgentInstanceLock getLock() { return lock; } } }