diff --git a/src/interval_set.rs b/src/interval_set.rs index 6a059e3..acc6a74 100644 --- a/src/interval_set.rs +++ b/src/interval_set.rs @@ -91,7 +91,7 @@ impl IntervalSet { } pub fn merge(&mut self, other: &IntervalSet) { - self.0.extend(other.0.clone()); + self.0.extend(other.0.iter().cloned()); self.coalesce(); } diff --git a/src/lib.rs b/src/lib.rs index 79945dd..569ba5d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,7 @@ use crate::executors::*; use crate::interval::*; use crate::interval_set::*; use crate::requirement::*; +use crate::resource_interval::*; use crate::schedule::*; use crate::storage::*; use crate::task::*; @@ -27,6 +28,7 @@ pub mod executors; pub mod interval; pub mod interval_set; pub mod requirement; +pub mod resource_interval; pub mod schedule; pub mod storage; pub mod task; diff --git a/src/resource_interval.rs b/src/resource_interval.rs new file mode 100644 index 0000000..ab36f15 --- /dev/null +++ b/src/resource_interval.rs @@ -0,0 +1,66 @@ +use super::*; +use std::ops::{Add, Deref, DerefMut, Sub}; + +/// Contains a map of resource and intervals. The intervals could +/// represent where a resource is available, or where it's required +/// Resources are independent, so overlaps between the +/// interval sets are possible. +pub struct ResourceInterval(HashMap); + +impl ResourceInterval { + fn new() -> Self { + ResourceInterval(HashMap::new()) + } +} + +impl Deref for ResourceInterval { + type Target = HashMap; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl DerefMut for ResourceInterval { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From> for ResourceInterval { + fn from(hm: HashMap) -> Self { + ResourceInterval(hm) + } +} + +impl From<&HashMap> for ResourceInterval { + fn from(hm: &HashMap) -> Self { + ResourceInterval(hm.clone()) + } +} + +impl Add for &ResourceInterval { + type Output = ResourceInterval; + fn add(self, other: &ResourceInterval) -> Self::Output { + let res: HashMap = + other.0.iter().fold(self.0.clone(), |mut acc, (res, is)| { + acc.entry(res.clone()) + .or_insert(IntervalSet::new()) + .merge(is); + acc + }); + ResourceInterval(res) + } +} + +impl Sub for &ResourceInterval { + type Output = ResourceInterval; + fn sub(self, other: &ResourceInterval) -> Self::Output { + let res: HashMap = + other.0.iter().fold(self.0.clone(), |mut acc, (res, is)| { + acc.entry(res.clone()) + .or_insert(IntervalSet::new()) + .difference(is); + acc + }); + ResourceInterval(res) + } +}