/* *************************************************************************************** * 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.core.service; import com.espertech.esper.util.CollectionUtil; import com.espertech.esper.util.ManagedReadWriteLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Set; /** * Service for holding references between statements and their event type use. */ public class StatementEventTypeRefImpl implements StatementEventTypeRef { private static final Logger log = LoggerFactory.getLogger(StatementEventTypeRefImpl.class); private final ManagedReadWriteLock mapLock; private final HashMap<String, Set<String>> typeToStmt; private final HashMap<String, String[]> stmtToType; /** * Ctor. */ public StatementEventTypeRefImpl() { typeToStmt = new HashMap<String, Set<String>>(); stmtToType = new HashMap<String, String[]>(); mapLock = new ManagedReadWriteLock("StatementEventTypeRefImpl", false); } public void addReferences(String statementName, String[] eventTypesReferenced) { if (eventTypesReferenced.length == 0) { return; } mapLock.acquireWriteLock(); try { for (String reference : eventTypesReferenced) { addReference(statementName, reference); } } finally { mapLock.releaseWriteLock(); } } public void removeReferencesStatement(String statementName) { mapLock.acquireWriteLock(); try { String[] types = stmtToType.remove(statementName); if (types != null) { for (String type : types) { removeReference(statementName, type); } } } finally { mapLock.releaseWriteLock(); } } public void removeReferencesType(String name) { mapLock.acquireWriteLock(); try { Set<String> statementNames = typeToStmt.remove(name); if (statementNames != null) { for (String statementName : statementNames) { removeReference(statementName, name); } } } finally { mapLock.releaseWriteLock(); } } public boolean isInUse(String eventTypeName) { mapLock.acquireReadLock(); try { return typeToStmt.containsKey(eventTypeName); } finally { mapLock.releaseReadLock(); } } public Set<String> getStatementNamesForType(String eventTypeName) { mapLock.acquireReadLock(); try { Set<String> types = typeToStmt.get(eventTypeName); if (types == null) { return Collections.EMPTY_SET; } return Collections.unmodifiableSet(types); } finally { mapLock.releaseReadLock(); } } public String[] getTypesForStatementName(String statementName) { mapLock.acquireReadLock(); try { String[] types = stmtToType.get(statementName); if (types == null) { return new String[0]; } return types; } finally { mapLock.releaseReadLock(); } } private void addReference(String statementName, String eventTypeName) { // add to types Set<String> statements = typeToStmt.get(eventTypeName); if (statements == null) { statements = new HashSet<String>(); typeToStmt.put(eventTypeName, statements); } statements.add(statementName); // add to statements String[] types = stmtToType.get(statementName); if (types == null) { types = new String[]{eventTypeName}; } else { int index = CollectionUtil.findItem(types, eventTypeName); if (index == -1) { types = (String[]) CollectionUtil.arrayExpandAddSingle(types, eventTypeName); } } stmtToType.put(statementName, types); } private void removeReference(String statementName, String eventTypeName) { // remove from types Set<String> statements = typeToStmt.get(eventTypeName); if (statements != null) { if (!statements.remove(statementName)) { log.info("Failed to find statement name '" + statementName + "' in collection"); } if (statements.isEmpty()) { typeToStmt.remove(eventTypeName); } } // remove from statements String[] types = stmtToType.get(statementName); if (types != null) { int index = CollectionUtil.findItem(types, eventTypeName); if (index != -1) { if (types.length == 1) { stmtToType.remove(statementName); } else { types = (String[]) CollectionUtil.arrayShrinkRemoveSingle(types, index); stmtToType.put(statementName, types); } } else { log.info("Failed to find type name '" + eventTypeName + "' in collection"); } } } /** * For testing, returns the mapping of event type name to statement names. * * @return mapping */ protected HashMap<String, Set<String>> getTypeToStmt() { return typeToStmt; } /** * For testing, returns the mapping of statement names to event type names. * * @return mapping */ protected HashMap<String, String[]> getStmtToType() { return stmtToType; } }