plate-tool/plate-tool-lib/src/transfer_region_cache.rs

120 lines
3.0 KiB
Rust

use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use crate::transfer::Transfer;
use crate::Well;
use uuid::Uuid;
#[derive(Debug)]
pub struct TransferRegionCache {
interior: Arc<Mutex<TransferRegionCacheInterior>>,
}
impl Default for TransferRegionCache {
fn default() -> Self {
Self::new()
}
}
impl TransferRegionCache {
pub fn new() -> Self {
TransferRegionCache {
interior: Arc::new(Mutex::new(TransferRegionCacheInterior::new()))
}
}
pub fn add_overwrite(&self, tr: &Transfer) {
let source = tr.transfer_region.get_source_wells();
let destination = tr.transfer_region.get_destination_wells();
let uuid = tr.id;
if let Ok(mut interior) = self.interior.lock() {
interior.cache.insert(uuid, InteriorWellSlices {
source: source.into(),
destination: destination.into(),
});
}
}
pub fn generate_cache(&self, trs: &[Transfer]) {
for tr in trs.iter() {
self.add_overwrite(tr);
}
}
pub fn invalidate(&self, tr: &Transfer) {
if let Ok(mut interior) = self.interior.lock() {
interior.cache.remove(&tr.id);
}
}
pub fn get_source(&self, tr: &Transfer) -> Option<Arc<[Well]>> {
self.get(tr, true)
}
pub fn get_or_calculate_source(&self, tr: &Transfer) -> Option<Arc<[Well]>> {
if !self.has(tr) {
self.add_overwrite(tr);
}
self.get_source(tr)
}
pub fn get_destination(&self, tr: &Transfer) -> Option<Arc<[Well]>> {
self.get(tr, false)
}
pub fn get_or_calculate_destination(&self, tr: &Transfer) -> Option<Arc<[Well]>> {
if !self.has(tr) {
self.add_overwrite(tr);
}
self.get_destination(tr)
}
fn get(&self, tr: &Transfer, is_source: bool) -> Option<Arc<[Well]>> {
if let Ok(interior) = self.interior.lock() {
interior.cache.get(&tr.id).map(|x|
if is_source {
x.source.clone()
} else {
x.destination.clone()
})
} else {
None
}
}
fn has(&self, tr: &Transfer) -> bool {
if let Ok(interior) = self.interior.lock() {
interior.cache.contains_key(&tr.get_uuid())
} else {
false
}
}
}
impl Clone for TransferRegionCache {
fn clone(&self) -> Self {
// Clone the interior RC without letting anyone know
// shhhh!
TransferRegionCache {
interior: self.interior.clone(),
}
}
}
#[derive(Debug)]
struct TransferRegionCacheInterior {
cache: HashMap<Uuid, InteriorWellSlices>,
}
impl TransferRegionCacheInterior {
fn new() -> Self {
TransferRegionCacheInterior {
cache: HashMap::new()
}
}
}
#[derive(Debug)]
struct InteriorWellSlices {
source: Arc<[Well]>,
destination: Arc<[Well]>,
}