You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dirstat/src/state.rs

104 lines
1.9 KiB

use super::*;
use tokio::sync::{
Semaphore,
SemaphorePermit
};
use futures::Future;
use futures::future::OptionFuture;
use data::Cache;
use config::Config;
/// Program state
#[derive(Debug, Clone)]
pub struct State
{
config: Arc<Config>,
cache: Cache,
depth: usize,
throttle: Option<Arc<Semaphore>>,
}
#[derive(Debug)]
pub struct TaskLock<'a>(&'a Option<Arc<Semaphore>>);
impl<'a> TaskLock<'a>
{
/// Enter this lock section.
pub fn enter(self) -> OptionFuture<impl Future<Output = SemaphorePermit<'a>> + 'a>
{
self.0.as_ref().map(|x| x.acquire()).into()
}
}
impl State
{
/// Create a new state
pub fn new(cfg: Config) -> Self
{
Self {
throttle: cfg.max_tasks.map(|max| Arc::new(Semaphore::new(max.get()))),
cache: Cache::new(),
depth: 1,
config: Arc::new(cfg),
}
}
/// Get the semaphore for this state
pub fn lock(&self) -> TaskLock<'_>
{
TaskLock(&self.throttle)
}
/// Current depth of this tree
pub fn depth(&self) -> usize
{
self.depth
}
/// Clone into increased depth, if config allows a deeper run.
pub fn deeper(&self) -> Option<Self>
{
if self.config.recursive.can_run(self.depth+1) {
Some(Self{
depth: self.depth + 1,
..self.clone()
})
} else {
None
}
}
/// The configuration for this run
pub fn config(&self) -> &Config
{
&self.config
}
/// A reference to the cache of this run
pub fn cache(&self) -> &Cache
{
&self.cache
}
/// Subscribe to this state's cache
pub fn cache_sub(&self) -> Cache
{
self.cache.clone()
}
/// Try to consume the state into the cache.
///
/// Fails if there are other references of this state alive.
pub fn try_into_cache(self) -> Result<(Cache, Config), Self>
{
match Arc::try_unwrap(self.config)
{
Ok(cfg) => Ok((self.cache, cfg)),
Err(config) => Err(Self{config, ..self}),
}
}
}