61 lines
1.7 KiB
C++
61 lines
1.7 KiB
C++
#include <queue>
|
|
#include <mutex>
|
|
#include <condition_variable>
|
|
#include <cassert>
|
|
#include <memory>
|
|
#include "database.hpp"
|
|
|
|
class DatabasePool {
|
|
public:
|
|
// Construct pool with path + size
|
|
DatabasePool(const std::string& path)
|
|
: db_path(path)
|
|
{
|
|
// Enable multithreaded SQLite
|
|
assert(sqlite3_config(SQLITE_CONFIG_MULTITHREAD) == SQLITE_OK);
|
|
assert(sqlite3_initialize() == SQLITE_OK);
|
|
}
|
|
|
|
bool init(size_t size){
|
|
try{
|
|
// Pre-create the pool
|
|
for (size_t i = 0; i < size; ++i) {
|
|
auto db = std::make_shared<decltype(make_database(db_path))>(make_database(db_path));
|
|
db->sync_schema();
|
|
pool.push(db);
|
|
}
|
|
// init the database
|
|
auto db = acquire();
|
|
release(db);
|
|
return true;
|
|
}
|
|
catch (...) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Acquire a database connection from the pool
|
|
std::shared_ptr<decltype(make_database(std::string{}))> acquire() {
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
cv.wait(lock, [&]{ return !pool.empty(); });
|
|
auto db = pool.front();
|
|
pool.pop();
|
|
return db;
|
|
}
|
|
|
|
// Return a connection to the pool
|
|
void release(std::shared_ptr<decltype(make_database(std::string{}))> db) {
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
pool.push(db);
|
|
lock.unlock();
|
|
cv.notify_one();
|
|
}
|
|
|
|
private:
|
|
std::queue<std::shared_ptr<decltype(make_database(std::string{}))>> pool;
|
|
std::mutex mutex;
|
|
std::condition_variable cv;
|
|
const std::string db_path;
|
|
};
|
|
|
|
extern std::unique_ptr<DatabasePool> dbpool; |