1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-22 22:03:39 +03:00

feature #206: Moved Pool classes to the new DB interface

This commit is contained in:
Ruben S. Montero 2010-04-03 16:54:54 +02:00
parent 4aaac043d0
commit 88f7cbe8c1
3 changed files with 92 additions and 105 deletions

View File

@ -17,19 +17,18 @@
#ifndef POOL_OBJECT_SQL_H_
#define POOL_OBJECT_SQL_H_
#include "SqliteDB.h"
#include "ObjectSQL.h"
#include <pthread.h>
using namespace std;
/**
* PoolObject class. Provides a SQL backend interface for Pool components. Each
* PoolObject class. Provides a SQL backend interface for Pool components. Each
* object is identified with and unique OID
*
* Note: The PoolObject provides a synchronization mechanism (mutex). This
*
* Note: The PoolObject provides a synchronization mechanism (mutex). This
* implementation assumes that the mutex IS LOCKED when the class destructor
* is called.
* is called.
*/
class PoolObjectSQL : public ObjectSQL
@ -44,10 +43,10 @@ public:
virtual ~PoolObjectSQL()
{
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);
};
int get_oid() const
{
return oid;
@ -63,7 +62,7 @@ public:
};
/**
* Set the object valid flag
* Set the object valid flag
* @param _valid new valid flag
*/
void set_valid(const bool _valid)
@ -86,8 +85,9 @@ public:
{
pthread_mutex_unlock(&mutex);
};
protected:
/**
* The object unique ID
*/
@ -96,7 +96,7 @@ protected:
/**
* The contents ob this object are valid
*/
bool valid;
bool valid;
private:
@ -106,8 +106,8 @@ private:
friend class PoolSQL;
/**
* The mutex for the PoolObject. This implementation assumes that the mutex
* IS LOCKED when the class destructor is called.
* The mutex for the PoolObject. This implementation assumes that the mutex
* IS LOCKED when the class destructor is called.
*/
pthread_mutex_t mutex;
};

View File

@ -21,7 +21,7 @@
#include <string>
#include <queue>
#include "SqliteDB.h"
#include "SqlDB.h"
#include "PoolObjectSQL.h"
#include "Log.h"
#include "Hook.h"
@ -30,11 +30,11 @@ using namespace std;
/**
* PoolSQL class. Provides a base class to implement persistent generic pools.
* The PoolSQL provides a synchronization mechanism (mutex) to operate in
* multithreaded applications. Any modification or access function to the pool
* The PoolSQL provides a synchronization mechanism (mutex) to operate in
* multithreaded applications. Any modification or access function to the pool
* SHOULD block the mutex.
*/
class PoolSQL: public Hookable
class PoolSQL: public Callbackable, Hookable
{
public:
@ -43,10 +43,10 @@ public:
* the last used Object identifier by querying the corresponding database
* table. This function SHOULD be called before any pool related function.
* @param _db a pointer to the database
* @param table the name of the table supporting the pool (to set the oid
* @param table the name of the table supporting the pool (to set the oid
* counter). If null the OID counter is not updated.
*/
PoolSQL(SqliteDB * _db, const char * table=0);
PoolSQL(SqlDB * _db, const char * table=0);
virtual ~PoolSQL();
@ -60,11 +60,11 @@ public:
PoolObjectSQL *objsql);
/**
* Gets an object from the pool (if needed the object is loaded from the
* Gets an object from the pool (if needed the object is loaded from the
* database).
* @param oid the object unique identifier
* @param lock locks the object if true
*
*
* @return a pointer to the object, 0 in case of failure
*/
virtual PoolObjectSQL * get(
@ -76,48 +76,48 @@ public:
* @param oids a vector with the oids of the objects.
* @param the name of the DB table.
* @param where condition in SQL format.
*
* @return 0 on success
*
* @return 0 on success
*/
virtual int search(
vector<int>& oids,
const char * table,
const string& where);
/**
* Updates the object's data in the data base. The object mutex SHOULD be
* locked.
* @param objsql a pointer to the object
*
*
* @return 0 on success.
*/
virtual int update(
PoolObjectSQL * objsql)
{
int rc;
rc = objsql->update(db);
if ( rc == 0 )
{
do_hooks(objsql, Hook::UPDATE);
}
return rc;
};
/**
* Removes all the elements from the pool
*/
void clean();
protected:
/**
* Pointer to the database.
*/
SqliteDB * db;
SqlDB * db;
/**
* Function to lock the pool
*/
@ -133,13 +133,13 @@ protected:
{
pthread_mutex_unlock(&mutex);
};
private:
pthread_mutex_t mutex;
/**
* Max size for the pool, to control the memory footprint of the pool. This
* Max size for the pool, to control the memory footprint of the pool. This
* number MUST be greater than the max. number of objects that are
* accessed simultaneously.
*/
@ -152,7 +152,7 @@ private:
int lastOID;
/**
* The pool is implemented with a Map of SQL object pointers, using the
* The pool is implemented with a Map of SQL object pointers, using the
* OID as key.
*/
map<int,PoolObjectSQL *> pool;
@ -164,18 +164,28 @@ private:
virtual PoolObjectSQL * create() = 0;
/**
* OID queue to implement a FIFO-like replacement policy for the pool
* cache.
* OID queue to implement a FIFO-like replacement policy for the pool
* cache.
*/
queue<int> oid_queue;
/**
* FIFO-like replacement policy function. Before removing an object (pop)
* from the cache its lock is checked. The object is removed only if
* the associated mutex IS NOT blocked. Otherwise the oid is sent to the
* back of the queue.
* from the cache its lock is checked. The object is removed only if
* the associated mutex IS NOT blocked. Otherwise the oid is sent to the
* back of the queue.
*/
void replace();
/**
* Callback to set the lastOID (PoolSQL::PoolSQL)
*/
int init_cb(void *nil, int num, char **values, char **names);
/**
* Callback to store the IDs of pool objects (PoolSQL::search)
*/
int search_cb(void *_oids, int num, char **values, char **names);
};
#endif /*POOL_SQL_H_*/
#endif /*POOL_SQL_H_*/

View File

@ -18,7 +18,7 @@
#include <sstream>
#include <iostream>
#include <stdexcept>
#include <algorithm>
#include <algorithm>
#include "PoolSQL.h"
@ -36,49 +36,32 @@ const unsigned int PoolSQL::MAX_POOL_SIZE = 500;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
extern "C"
int PoolSQL::init_cb(void *nil, int num, char **values, char **names)
{
int init_cb (
void * _i,
int num,
char ** values,
char ** names)
if ( (num<=0) || (values[0] == 0) )
{
int * i;
lastOID = -1;
return -1;
}
i = static_cast<int *>(_i);
lastOID = atoi(values[0]);
if ( (i == 0) || (num<=0) || (values[0] == 0) )
{
*i = -1;
return -1;
}
*i = atoi(values[0]);
return 0;
};
return 0;
}
/* -------------------------------------------------------------------------- */
PoolSQL::PoolSQL(SqliteDB * _db, const char * table): Hookable(), db(_db)
PoolSQL::PoolSQL(SqlDB * _db, const char * table): db(_db), lastOID(-1)
{
ostringstream oss;
pthread_mutex_init(&mutex,0);
// Get next id from the DB table
lastOID = -1;
if ( table != 0 )
{
oss << "SELECT MAX(oid) FROM " << table;
set_callback(static_cast<Callbackable::CallBack>(&PoolSQL::init_cb),0);
db->exec(oss,init_cb,(void *) &lastOID);
}
oss << "SELECT MAX(oid) FROM " << table;
db->exec(oss,this);
};
/* -------------------------------------------------------------------------- */
@ -93,10 +76,10 @@ PoolSQL::~PoolSQL()
for ( it = pool.begin(); it != pool.end(); it++)
{
it->second->lock();
delete it->second;
}
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);
@ -138,7 +121,7 @@ int PoolSQL::allocate(
}
do_hooks(objsql, Hook::ALLOCATE);
objsql->unlock();
delete objsql;
@ -164,7 +147,7 @@ PoolObjectSQL * PoolSQL::get(
index = pool.find(oid);
if ( index != pool.end() )
{
{
if ( index->second->isValid() == false )
{
objectsql = 0;
@ -184,7 +167,7 @@ PoolObjectSQL * PoolSQL::get(
return objectsql;
}
else
{
{
objectsql = create();
objectsql->oid = oid;
@ -196,7 +179,7 @@ PoolObjectSQL * PoolSQL::get(
delete objectsql;
unlock();
return 0;
}
@ -228,7 +211,7 @@ void PoolSQL::replace()
bool removed = false;
int oid;
int rc;
map<int,PoolObjectSQL *>::iterator index;
while (!removed)
@ -245,7 +228,7 @@ void PoolSQL::replace()
rc = pthread_mutex_trylock(&(index->second->mutex));
if ( rc == EBUSY ) // In use by other thread, move to back
{
{
oid_queue.pop();
oid_queue.push(oid);
}
@ -254,7 +237,7 @@ void PoolSQL::replace()
delete index->second;
pool.erase(index);
oid_queue.pop();
removed = true;
}
@ -273,44 +256,35 @@ void PoolSQL::clean()
for ( it = pool.begin(); it != pool.end(); it++)
{
it->second->lock();
delete it->second;
pool.erase(it);
}
unlock();
unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int PoolSQL:: search_cb(void * _oids, int num, char **values, char **names)
{
vector<int> * oids;
extern "C"
{
static int search_cb(
void * _oids,
int num,
char ** values,
char ** names)
{
vector<int> * oids;
oids = static_cast<vector<int> *>(_oids);
if ( num == 0 || values == 0 || values[0] == 0 )
{
return -1;
}
oids->push_back(atoi(values[0]));
return 0;
}
}
/* -------------------------------------------------------------------------- */
int PoolSQL::search(
vector<int>& oids,
const char * table,
@ -318,14 +292,17 @@ int PoolSQL::search(
{
ostringstream sql;
int rc;
lock();
set_callback(static_cast<Callbackable::CallBack>(&PoolSQL::search_cb),
static_cast<void *>(&oids));
sql << "SELECT oid FROM " << table << " WHERE " << where;
rc = db->exec(sql, search_cb, (void *) &oids);
rc = db->exec(sql, this);
unlock();
return rc;
}
}