Improve buffer performance

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent 9c1ba03bac
commit aab7f71e12

@ -1,3 +1,4 @@
use parking_lot::lock_api::Mutex;
use tauri::State; use tauri::State;
pub use file::*; pub use file::*;
@ -23,8 +24,8 @@ fn add_once_buffer(
) -> String { ) -> String {
let uri = format!("once://{}", key); let uri = format!("once://{}", key);
let once_buffer = VolatileBuffer::new(mime, buf); let once_buffer = VolatileBuffer::new(mime, buf);
let mut once_buffers = buffer_state.buffer.lock(); let mut once_buffers = buffer_state.buffer.write();
once_buffers.insert(key, once_buffer); once_buffers.insert(key, Mutex::new(once_buffer));
uri uri
} }

@ -4,6 +4,7 @@ use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use parking_lot::Mutex; use parking_lot::Mutex;
use parking_lot::RwLock as ParkingRwLock;
use tauri::async_runtime::RwLock; use tauri::async_runtime::RwLock;
use tokio::time::Instant; use tokio::time::Instant;
@ -41,7 +42,6 @@ impl ApiState {
#[derive(Clone)] #[derive(Clone)]
pub struct VolatileBuffer { pub struct VolatileBuffer {
pub accessed: bool,
pub valid_until: Instant, pub valid_until: Instant,
pub mime: String, pub mime: String,
pub buf: Vec<u8>, pub buf: Vec<u8>,
@ -50,8 +50,7 @@ pub struct VolatileBuffer {
impl VolatileBuffer { impl VolatileBuffer {
pub fn new(mime: String, buf: Vec<u8>) -> Self { pub fn new(mime: String, buf: Vec<u8>) -> Self {
Self { Self {
accessed: false, valid_until: Instant::now() + Duration::from_secs(120), // buffers that weren't accessed get deleted after 2 minutes
valid_until: Instant::now() + Duration::from_secs(60),
mime, mime,
buf, buf,
} }
@ -60,18 +59,19 @@ impl VolatileBuffer {
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct BufferState { pub struct BufferState {
pub buffer: Arc<Mutex<HashMap<String, VolatileBuffer>>>, pub buffer: Arc<ParkingRwLock<HashMap<String, Mutex<VolatileBuffer>>>>,
} }
impl BufferState { impl BufferState {
/// Checks if an entry for the specific key exists and resets /// Checks if an entry for the specific key exists and resets
/// its state so that it can safely be accessed again. /// its state so that it can safely be accessed again.
pub fn reserve_entry(&self, key: &String) -> bool { pub fn reserve_entry(&self, key: &String) -> bool {
let mut buffers = self.buffer.lock(); let buffers = self.buffer.read();
let entry = buffers.get_mut(key); let entry = buffers.get(key);
if let Some(entry) = entry { if let Some(entry) = entry {
entry.accessed = false; // reset that it has been accessed so it can be reused let mut entry = entry.lock();
entry.valid_until = Instant::now() + Duration::from_secs(120); // reset the timer so that it can be accessed again
true true
} else { } else {
false false
@ -80,12 +80,12 @@ impl BufferState {
/// Returns the cloned buffer entry and flags it for expiration /// Returns the cloned buffer entry and flags it for expiration
pub fn get_entry(&self, key: &str) -> Option<VolatileBuffer> { pub fn get_entry(&self, key: &str) -> Option<VolatileBuffer> {
let mut buffers = self.buffer.lock(); let buffers = self.buffer.read();
let entry = buffers.get_mut(key); let entry = buffers.get(key);
if let Some(entry) = entry { if let Some(entry) = entry {
entry.accessed = true; let mut entry = entry.lock();
entry.valid_until = Instant::now() + Duration::from_secs(10); // time to live is 10 seconds entry.valid_until = Instant::now() + Duration::from_secs(30); // ttl is 30 seconds after being accessed
Some(entry.clone()) Some(entry.clone())
} else { } else {
@ -95,15 +95,19 @@ impl BufferState {
/// Clears all expired entries /// Clears all expired entries
pub fn clear_expired(&self) { pub fn clear_expired(&self) {
let mut buffer = self.buffer.lock(); let keys: Vec<String> = {
let keys: Vec<String> = buffer.keys().cloned().collect(); let buffer = self.buffer.read();
buffer.keys().cloned().collect()
};
for key in keys { for key in keys {
let (accessed, valid_until) = { let valid_until = {
let entry = buffer.get(&key).unwrap(); let buffer = self.buffer.read();
(entry.accessed, entry.valid_until.clone()) let entry = buffer.get(&key).unwrap().lock();
entry.valid_until.clone()
}; };
if accessed && valid_until < Instant::now() { if valid_until < Instant::now() {
let mut buffer = self.buffer.write();
buffer.remove(&key); buffer.remove(&key);
} }
} }

Loading…
Cancel
Save