package com.tesora.dve.worker; /* * #%L * Tesora Inc. * Database Virtualization Engine * %% * Copyright (C) 2011 - 2014 Tesora Inc. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import com.tesora.dve.exceptions.PESQLException; public enum StatementManager { INSTANCE; // use double locking so that it works at higher conn counts final ConcurrentHashMap<Long, Set<WorkerStatement>> active = new ConcurrentHashMap<Long, Set<WorkerStatement>>(); private Set<WorkerStatement> getSet(Long connID) { // synchronized(this) { Set<WorkerStatement> e = active.get(connID); if (e == null) { e = Collections.newSetFromMap(new ConcurrentHashMap<WorkerStatement, Boolean>()); Set<WorkerStatement> realSet = active.putIfAbsent(connID, e); if (realSet != null) e = realSet; // active.put(connID, e); } return e; // } } public void registerStatement(long connectionId, WorkerStatement stmt) { Long connID = Long.valueOf(connectionId); Set<WorkerStatement> s = getSet(connID); // synchronized(s) { s.add(stmt); // } } public void unregisterStatement(long connectionId, WorkerStatement stmt) { Long connID = Long.valueOf(connectionId); Set<WorkerStatement> s = getSet(connID); boolean removeKey = false; // synchronized(s) { s.remove(stmt); removeKey = s.isEmpty(); // } if (removeKey) { // synchronized(this) { // Set<WorkerStatement> e = active.get(connID); // if (e == null) return; // synchronized(e) { // if (!e.isEmpty()) return; active.remove(connID); // } // } } } public void cancelAllStatements(long connectionId) throws PESQLException { Long connID = Long.valueOf(connectionId); // use a copy of in case the thing gets modified under us Set<WorkerStatement> s = getSet(connID); if (s == null) return; Set<WorkerStatement> copy = null; synchronized(s) { copy = new HashSet<WorkerStatement>(s); } for (WorkerStatement stmt : copy) { stmt.cancel(); } } public void cancellAllConnections() throws PESQLException { HashSet<WorkerStatement> copy = new HashSet<WorkerStatement>(); synchronized(this) { for(Set<WorkerStatement> v : active.values()) copy.addAll(v); } for (WorkerStatement stmt : copy) stmt.cancel(); } public void clear() { active.clear(); } }