//! Mechanism to defer dropping of large objects to background threads use super::*; use futures::{ prelude::*, future::OptionFuture, }; pub const DEFER_DROP_VEC_SIZE_FLOOR: usize = 1024 * 1024; // 1 MB /// Drop a `Vec` that is `Send` and `'static`. /// /// This will move the object to a background task if it is deemed nessisary. /// # Note /// This *must* be `await`ed to work properly. If you are not in an async context, use `drop_vec_sync`. pub fn drop_vec(vec: Vec) -> impl Future + 'static where T: Send + 'static { let len_bytes = vec.len() * std::mem::size_of::(); OptionFuture::from(if len_bytes > DEFER_DROP_VEC_SIZE_FLOOR { cfg_eprintln!(Verbose; config::get_global(), "Size of vector ({} bytes, {} elements of {:?}) exceeds defer drop size floor {}. Moving vector to a seperate thread for de-allocation", len_bytes, vec.len(), std::any::type_name::(), DEFER_DROP_VEC_SIZE_FLOOR); Some(async move { tokio::task::spawn_blocking(move || drop(vec)).await.expect("Child panic while dropping vector"); }) } else { None }).map(|_| ()) } /// Drop a `Vec` that is `Send` and `'static`. /// /// This will move the object to a background task if it is deemed nessisary. pub fn drop_vec_sync(vec: Vec) where T: Send + 'static { let len_bytes = vec.len() * std::mem::size_of::(); if len_bytes > DEFER_DROP_VEC_SIZE_FLOOR { cfg_eprintln!(Verbose; config::get_global(), "Size of vector ({} bytes, {} elements of {:?}) exceeds defer drop size floor {}. Moving vector to a seperate thread for de-allocation", len_bytes, vec.len(), std::any::type_name::(), DEFER_DROP_VEC_SIZE_FLOOR); tokio::task::spawn_blocking(move || drop(vec)); } }