/* * YAQP - Yet Another QSAR Project: Machine Learning algorithms designed for * the prediction of toxicological features of chemical compounds become * available on the Web. Yaqp is developed under OpenTox (http://opentox.org) * which is an FP7-funded EU research project. * * Copyright (C) 2009-2010 Pantelis Sopasakis & Charalampos Chomenides * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package org.opentox.db.util; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ArrayBlockingQueue; import org.opentox.db.exceptions.DbException; import org.opentox.db.queries.HyperStatement; import org.opentox.util.logging.YaqpLogger; import org.opentox.util.logging.levels.Fatal; import static org.opentox.core.exceptions.Cause.*; /** * Pool of hyper statements. This pool implements a first-in-first-out architecture * for the management of hyperStatements. A HyperStatement is pulled out of this pool, * the it is initialized with variables and executed. Afterwards, it is returned back to * the Pool, where it is cleared and recycle back in the queue. * * @author Sopasakis Pantelis * @author Charalampos Chomenides * * @see HyperStatement * @see PrepStmt */ public class PrepSwimmingPool { /** * Multiplicity for the stored HyperStatements. Specifies how many clones * of a HyperStatement are stored in the Pool. */ private static final int _POOL_SIZE = 10; private static PrepSwimmingPool instanceOfThis = null; public static PrepSwimmingPool POOL = getInstance(); /** * Our pool */ private Map<PrepStmt, ArrayBlockingQueue<HyperStatement>> BlockingQueues = new HashMap<PrepStmt, ArrayBlockingQueue<HyperStatement>>(); private PrepSwimmingPool() { try { TheDbConnector db = TheDbConnector.DB; for (PrepStmt prepStmt : PrepStmt.values()) { ArrayBlockingQueue<HyperStatement> queue_i = new ArrayBlockingQueue<HyperStatement>(_POOL_SIZE); for (int i = 0; i < _POOL_SIZE; i++) { queue_i.add(new HyperStatement(prepStmt.getSql())); } BlockingQueues.put(prepStmt, queue_i); } } catch (Exception ex) { YaqpLogger.LOG.log(new Fatal(getClass(), "XPP501 - " + ex.toString())); throw new RuntimeException("XPP501", ex); } } private static PrepSwimmingPool getInstance() { if (instanceOfThis == null) { instanceOfThis = new PrepSwimmingPool(); } return instanceOfThis; } /** * Get the first available Hyperstatement from the pool. In case there are no * available statements, wait. * @param prepStmt Prepared Statement (PrepStmt) for which the HyperStatement is requested. * @return HyperStatement corresponding to a given PrepStmt object. * @throws InterruptedException If the method is interrupted while waiting for a * Hyperstatement to become available. */ public HyperStatement take(PrepStmt prepStmt) throws InterruptedException { return BlockingQueues.get(prepStmt).take(); } /** * Wheter the Pool corresponding to a given PrepStmt is empty. * @param prepStmt a PrepStmt object. * @return true if the pool is empty of such HyperStatements. */ public boolean isEmpty(PrepStmt prepStmt) { return BlockingQueues.get(prepStmt).peek() == null ? true : false; } /** * Once a HyperStatement is exploited, it should be returned back to the pool * to become available for some other client who need to perform a same operation. * @param hp A used HyperStatement * @throws DbException If the Prepared Statement committed for recycle does not * belong to the Pool. */ public void recycle(HyperStatement hp) throws DbException { PrepStmt hp_prepStmt = null; for (PrepStmt prepStmt : PrepStmt.values()) { if (prepStmt.getSql().equalsIgnoreCase(hp.toString())) { hp_prepStmt = prepStmt; } } if (hp_prepStmt == null) { throw new DbException(XDB16, "The HyperStatement you provided does " + "not correspond to a registered prepared statement :" + hp_prepStmt.getSql()); } try { hp.flush(); BlockingQueues.get(hp_prepStmt).put(hp); } catch (InterruptedException ex) { throw new DbException(XDB17, ex); } } }