array backed pool

This commit is contained in:
dignifiedquire
2023-02-18 16:26:58 +01:00
parent b2c5560e30
commit c2e275cb96
2 changed files with 37 additions and 9 deletions

View File

@@ -196,12 +196,12 @@ impl Sql {
/// Creates a new connection pool.
fn new_pool(dbfile: &Path, passphrase: String) -> Result<Pool> {
let mut connections = Vec::new();
for _ in 0..3 {
let connection = new_connection(dbfile, &passphrase)?;
connections.push(connection);
}
let mut connections = [None, None, None]; // array from iter is not stable yet
for c in &mut connections {
let connection = new_connection(dbfile, &passphrase)?;
*c = Some(connection);
}
let pool = Pool::new(connections);
Ok(pool)
}

View File

@@ -7,10 +7,13 @@ use std::sync::{Arc, Weak};
use parking_lot::{Condvar, Mutex};
use rusqlite::Connection;
/// Total size of the connection pool.
pub const POOL_SIZE: usize = 3;
/// Inner connection pool.
struct InnerPool {
/// Available connections.
connections: Mutex<Vec<Connection>>,
connections: Mutex<[Option<Connection>; POOL_SIZE]>,
/// Conditional variable to notify about added connections.
///
@@ -24,7 +27,19 @@ impl InnerPool {
/// The connection could be new or returned back.
fn put(&self, connection: Connection) {
let mut connections = self.connections.lock();
connections.push(connection);
let mut found_one = false;
for c in &mut *connections {
if c.is_none() {
*c = Some(connection);
found_one = true;
break;
}
}
assert!(
found_one,
"attempted to put more connections than available"
);
drop(connections);
self.cond.notify_one();
}
@@ -79,7 +94,7 @@ impl fmt::Debug for Pool {
impl Pool {
/// Creates a new connection pool.
pub fn new(connections: Vec<Connection>) -> Self {
pub fn new(connections: [Option<Connection>; POOL_SIZE]) -> Self {
let inner = Arc::new(InnerPool {
connections: Mutex::new(connections),
cond: Condvar::new(),
@@ -92,7 +107,7 @@ impl Pool {
let mut connections = self.inner.connections.lock();
loop {
if let Some(conn) = connections.pop() {
if let Some(conn) = get_next(&mut *connections) {
return PooledConnection {
pool: Arc::downgrade(&self.inner),
conn: Some(conn),
@@ -103,3 +118,16 @@ impl Pool {
}
}
}
/// Returns the first available connection.
///
/// `None` if no connection is availble.
fn get_next(connections: &mut [Option<Connection>; POOL_SIZE]) -> Option<Connection> {
for c in &mut *connections {
if c.is_some() {
return c.take();
}
}
None
}