Author: wyoung
Date: Thu Jul 12 03:03:52 2007
New Revision: 1670

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=1670&view=rev
Log:
First cut at new ConnectionPool class.  Compiles and looks good, but to
really test it, we'll need to get thread safety stuff in place.

Added:
    trunk/lib/cpool.cpp
    trunk/lib/cpool.h
Modified:
    trunk/Wishlist
    trunk/mysql++.bkl

Modified: trunk/Wishlist
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/Wishlist?rev=1670&r1=1669&r2=1670&view=diff
==============================================================================
--- trunk/Wishlist (original)
+++ trunk/Wishlist Thu Jul 12 03:03:52 2007
@@ -14,10 +14,6 @@
     it can be done without breaking the ABI, which would force
     a feature to v3.0.
 
-    o Add ConnectionPool class, described in this post:
-
-      http://lists.mysql.com/plusplus/6631
-    
     o Extend the manipulators to handle nullable versions of
       the types we already support.  Should just be a matter of
       duplicating the existing type-specific manipulator functions,

Added: trunk/lib/cpool.cpp
URL: http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/cpool.cpp?rev=1670&view=auto
==============================================================================
--- trunk/lib/cpool.cpp (added)
+++ trunk/lib/cpool.cpp Thu Jul 12 03:03:52 2007
@@ -1,0 +1,86 @@
+/***********************************************************************
+ cpool.cpp - Implements the ConnectionPool class.
+
+ Copyright (c) 2007 by Educational Technology Resources, Inc.
+ Others may also hold copyrights on code in this file.  See the
+ CREDITS file in the top directory of the distribution for details.
+
+ This file is part of MySQL++.
+
+ MySQL++ is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ MySQL++ 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with MySQL++; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ USA
+***********************************************************************/
+
+#include "cpool.h"
+
+#include "connection.h"
+
+namespace mysqlpp {
+
+
+//// connection ////////////////////////////////////////////////////////
+
+Connection*
+ConnectionPool::connection()
+{
+       lock();
+
+       // Find first unused connection in the pool
+       PoolIt it = pool_.begin();
+       while ((it != pool_.end()) && it->in_use) {
+               ++it;
+       }
+       
+       if (it != pool_.end()) {
+               // Found at least one unused connection.  Try to find more, and
+               // decide which is the most recently used.
+               unsigned int tmax = max_idle_time();
+               time_t now = time(0);
+               PoolIt mru = it;
+               ++it;
+               while (it != pool_.end()) {
+                       if (it->in_use) {
+                               // Can't use this one, it's busy
+                               ++it;                   
+                       }
+                       else if ((now - it->last_used) > tmax) {
+                               // This one's too old; nuke it
+                               PoolIt doomed = it;
+                               ++it;
+                               pool_.erase(doomed);
+                       }
+                       else if (it->last_used > mru->last_used) {
+                               // Ah, found a free one more recently used; 
hang onto it
+                               mru = it;
+                               ++it;
+                       }
+               }
+
+               mru->in_use = true;
+               unlock();
+               return mru->conn;
+       }
+       else {
+               // Pool was empty when this function was called, so create and
+               // return a new one.
+               pool_.push_back(ConnectionInfo(create()));
+               Connection* pc = pool_.back().conn;
+               unlock();
+               return pc;
+       }
+}
+
+} // end namespace mysqlpp
+

Added: trunk/lib/cpool.h
URL: http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/cpool.h?rev=1670&view=auto
==============================================================================
--- trunk/lib/cpool.h (added)
+++ trunk/lib/cpool.h Thu Jul 12 03:03:52 2007
@@ -1,0 +1,128 @@
+/// \file cpool.h
+/// \brief Declares the ConnectionPool class.
+
+/***********************************************************************
+ Copyright (c) 2007 by Educational Technology Resources, Inc.
+ Others may also hold copyrights on code in this file.  See the
+ CREDITS file in the top directory of the distribution for details.
+
+ This file is part of MySQL++.
+
+ MySQL++ is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ MySQL++ 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with MySQL++; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ USA
+***********************************************************************/
+
+#if !defined(MYSQLPP_CPOOL_H)
+#define MYSQLPP_CPOOL_H
+
+#include "common.h"
+#include "lockable.h"
+
+#include <list>
+
+#include <time.h>
+
+namespace mysqlpp {
+
+#if !defined(DOXYGEN_IGNORE)
+// Make Doxygen ignore this
+class MYSQLPP_EXPORT Connection;
+#endif
+
+/// \brief A class to manage a pool of connections, for use in a
+/// multi-threaded program to allow multiple simultaneous queries.
+///
+/// This class manages a pool of active database connections.  This is
+/// useful in a multi-threaded program, because the MySQL C API doesn't
+/// permit multiple simultaneous operations on a single connection.  You
+/// can get around this limitation by having multiple connections, but
+/// this isn't easy to do well.  This class does it well. :)
+///
+/// The pool use policy is to always use the most recently used
+/// connection that's not being used right now.  This ensures that
+/// excess connections get killed off reasonably quickly.  By contrast,
+/// picking the least recently used connection can result in a large
+/// pool of sparsely used connections because we'd keep resetting the
+/// last-used time of the least recently used connection.
+
+class ConnectionPool : public Lockable
+{
+public:
+       /// \brief Default ctor
+       ConnectionPool() :
+       Lockable(false)
+       {
+       }
+
+       /// \brief Dtor
+       virtual ~ConnectionPool() { }
+       
+       /// \brief Get the most recently used connection in the pool.
+       ///
+       /// This method creates a new connection if an unused one doesn't
+       /// exist, and destroys any that have remained unused for too long.
+       ///
+       /// \retval a pointer to the most recently used connection
+       Connection* connection();
+
+protected:
+       //// Subclass overrides
+       /// \brief Create a new connection
+       ///
+       /// Subclasses must override this.
+       ///
+       /// Essentially, this method lets your code tell ConnectionPool
+       /// what server to connect to, what login parameters to use, what
+       /// connection options to enable, etc.  ConnectionPool can't know
+       /// any of this without your help.
+       ///
+       /// \retval A connected Connection object
+       virtual Connection* create() = 0;
+
+       /// \brief Returns the maximum number of seconds a connection is
+       /// able to remain idle before it is dropped.
+       ///
+       /// Subclasses must override this as it encodes a policy issue,
+       /// something that MySQL++ can't declare by fiat.
+       ///
+       /// \retval number of seconds before an idle connection is destroyed
+       /// due to lack of use
+       virtual unsigned int max_idle_time() = 0;
+
+private:
+       //// Internal types
+       struct ConnectionInfo {
+               Connection* conn;
+               time_t last_used;
+               bool in_use;
+
+               ConnectionInfo(Connection* c) :
+               conn(c),
+               last_used(time(0)),
+               in_use(true)
+               {
+               }
+       };
+       typedef std::list<ConnectionInfo> PoolT;
+       typedef PoolT::iterator PoolIt;
+
+       //// Internal data
+       PoolT pool_;
+};
+
+} // end namespace mysqlpp
+
+#endif // !defined(MYSQLPP_CPOOL_H)
+

Modified: trunk/mysql++.bkl
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/mysql%2B%2B.bkl?rev=1670&r1=1669&r2=1670&view=diff
==============================================================================
--- trunk/mysql++.bkl (original)
+++ trunk/mysql++.bkl Thu Jul 12 03:03:52 2007
@@ -41,6 +41,7 @@
                        <sources>
                                lib/coldata.cpp
                                lib/connection.cpp
+                               lib/cpool.cpp
                                lib/datetime.cpp
                                lib/field_names.cpp
                                lib/fields.cpp


_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits

Reply via email to