Koders를 검색하던중 ConnectPool의 구현을 C++의 template기반으로 구현한 소스가 있어 정리해 봤습니다.
유용하게 사용할수 있을것 같습니다.
아래 첨부된 소스의 원형은
http://www.koders.com/cpp/fid7219F33FFBFD5B5AAEC68184D06F48C0DAAF347C.aspx
에 존재합니다.
#pragma warning( disable : 4503 4355 4786 4290 )
#endif
#include <string>
#include <map>
class ConnectionID
{
public:
ConnectionID(
const std::string& database,
const std::string& user,
const std::string& password,
const std::string& host,
short port
): m_database(database),
m_user(user),
m_password(password),
m_host(host),
m_port(port)
{
}
friend bool operator < ( const ConnectionID&, const ConnectionID& );
friend bool operator == ( const ConnectionID&, const ConnectionID& );
friend bool operator != ( const ConnectionID&, const ConnectionID& );
const std::string& getDatabase() const { return m_database; }
const std::string& getUser() const { return m_user; }
const std::string& getPassword() const { return m_password; }
const std::string& getHost() const { return m_host; }
short getPort() const { return m_port; }
private:
std::string m_database;
std::string m_user;
std::string m_password;
std::string m_host;
short m_port;
};
inline bool operator < (const ConnectionID& lhs, const ConnectionID& rhs )
{
if (lhs.m_database < rhs.m_database) return true;
else if (rhs.m_database < lhs.m_database) return false;
else if (lhs.m_user < rhs.m_user) return true;
else if (rhs.m_user < lhs.m_user) return false;
else if (lhs.m_password < rhs.m_password) return true;
else if (rhs.m_password < lhs.m_password) return false;
else if (lhs.m_host < rhs.m_host) return true;
else if (rhs.m_host < lhs.m_host) return false;
else if (lhs.m_port < rhs.m_port) return true;
else if (rhs.m_port < lhs.m_port) return false;
else return false;
}
inline bool operator == (const ConnectionID& lhs, const ConnectionID& rhs)
{
return ((lhs.m_database == rhs.m_database) &&
(lhs.m_user == rhs.m_user) &&
(lhs.m_password == rhs.m_password) &&
(lhs.m_host == rhs.m_host) &&
(lhs.m_port == rhs.m_port));
}
inline bool operator != (const ConnectionID& lhs, const ConnectionID& rhs)
{
return !(lhs == rhs);
}
// -------------------------------------------------------------------------
template <typename T> class ConnectionPool {
public:
ConnectionPool( bool usePool = true)
: m_used( usePool) { }
T &create( const ConnectionID &id)
{
if (!m_used)
return new T( id);
else {
if (m_connections.find( id) == m_connections.end())
m_connections[id] = Connection( new T(id), 0);
} m_connections[id].second++;
return m_connections[id].first;
}
bool destroy( T *p)
{
if (!m_used)
delete p;
else {
const ConnectionID &id = p->connectionID();
if (m_connections.find( id) == m_connections.end())
return false;
else {
Connection &c = m_connections[id];
if (c.first != p)
return false;
else {
;
} c.second--;
if (c.second == 0)
{
m_connections.erase( id);
delete p;
}
}
} return true;
}
private:
typedef std::pair<T*, int> Connection;
typedef std::map<ConnectionID, Connection> Connections;
Connections m_connections;
bool m_used;
};
public:
T( const ConnectionID &id)
: m_connectionID(id) { }
const ConnectionID& connectionID() { return m_connectionID; }
private:
ConectionID m_connectionID;
};