Skip to content

Commit

Permalink
feat: implement reset behavior for pooled resources when given back
Browse files Browse the repository at this point in the history
  • Loading branch information
jpraynaud committed Jun 12, 2024
1 parent 2aced62 commit 198d759
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 11 deletions.
8 changes: 7 additions & 1 deletion mithril-common/src/crypto_helper/merkle_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{
sync::Arc,
};

use crate::{StdError, StdResult};
use crate::{resource_pool::Reset, StdError, StdResult};

use super::{MKProof, MKTree, MKTreeNode};

Expand Down Expand Up @@ -235,6 +235,12 @@ impl<K: MKMapKey, V: MKMapValue<K>> MKMap<K, V> {
}
}

impl<K: MKMapKey, V: MKMapValue<K>> Reset for MKMap<K, V> {
fn reset(&mut self) -> StdResult<()> {
self.compress()
}
}

impl<K: MKMapKey, V: MKMapValue<K>> Clone for MKMap<K, V> {
fn clone(&self) -> Self {
// Cloning should never fail so uwnrap is safe
Expand Down
33 changes: 23 additions & 10 deletions mithril-common/src/resource_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub enum ResourcePoolError {
}

/// Resource pool implementation (FIFO)
pub struct ResourcePool<T: Send + Sync> {
pub struct ResourcePool<T: Reset + Send + Sync> {
/// The size of the pool
size: usize,

Expand All @@ -38,7 +38,7 @@ pub struct ResourcePool<T: Send + Sync> {
not_empty: Condvar,
}

impl<T: Send + Sync> ResourcePool<T> {
impl<T: Reset + Send + Sync> ResourcePool<T> {
/// Create a new resource pool
pub fn new(pool_size: usize, resources: Vec<T>) -> Self {
Self {
Expand Down Expand Up @@ -103,9 +103,12 @@ impl<T: Send + Sync> ResourcePool<T> {
resource_pool_item: ResourcePoolItem<'_, T>,
) -> StdResult<()> {
let mut resource_pool_item = resource_pool_item;
resource_pool_item
.take()
.map(|resource_item| self.give_back_resource(resource_item, self.discriminant()?));
resource_pool_item.take().map(|resource_item| {
let mut resource_item = resource_item;
resource_item.reset()?;

self.give_back_resource(resource_item, self.discriminant()?)
});

Ok(())
}
Expand Down Expand Up @@ -154,13 +157,13 @@ impl<T: Send + Sync> ResourcePool<T> {
}

/// Resource pool item which will return the resource to the pool when dropped
pub struct ResourcePoolItem<'a, T: Send + Sync> {
pub struct ResourcePoolItem<'a, T: Reset + Send + Sync> {
resource_pool: &'a ResourcePool<T>,
discriminant: u64,
resource: Option<T>,
}

impl<'a, T: Send + Sync> ResourcePoolItem<'a, T> {
impl<'a, T: Reset + Send + Sync> ResourcePoolItem<'a, T> {
/// Create a new resource pool item
pub fn new(resource_pool: &'a ResourcePool<T>, resource: T) -> Self {
let discriminant = *resource_pool.discriminant.lock().unwrap();
Expand All @@ -182,21 +185,21 @@ impl<'a, T: Send + Sync> ResourcePoolItem<'a, T> {
}
}

impl<T: Send + Sync> Deref for ResourcePoolItem<'_, T> {
impl<T: Reset + Send + Sync> Deref for ResourcePoolItem<'_, T> {
type Target = T;

fn deref(&self) -> &T {
self.resource.as_ref().unwrap()
}
}

impl<T: Send + Sync> DerefMut for ResourcePoolItem<'_, T> {
impl<T: Reset + Send + Sync> DerefMut for ResourcePoolItem<'_, T> {
fn deref_mut(&mut self) -> &mut T {
self.resource.as_mut().unwrap()
}
}

impl<T: Send + Sync> Drop for ResourcePoolItem<'_, T> {
impl<T: Reset + Send + Sync> Drop for ResourcePoolItem<'_, T> {
fn drop(&mut self) {
self.take().map(|resource| {
self.resource_pool
Expand All @@ -205,12 +208,22 @@ impl<T: Send + Sync> Drop for ResourcePoolItem<'_, T> {
}
}

/// Reset trait implemented by pooled resources
pub trait Reset {
/// Reset the resource
fn reset(&mut self) -> StdResult<()> {
Ok(())
}
}

#[cfg(test)]
mod tests {
use std::time::Duration;

use super::*;

impl Reset for String {}

#[test]
fn test_resource_pool_acquire_returns_resource_when_available() {
let pool_size = 10;
Expand Down

0 comments on commit 198d759

Please sign in to comment.