Adjusting implementations of traits for interval sets and resource intervals
This commit is contained in:
parent
9cd2be5255
commit
3031ab8767
+30
-33
@@ -1,5 +1,4 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use std::convert::From;
|
|
||||||
use std::ops::{Add, BitAnd, BitOr, Deref, DerefMut, Not, Sub};
|
use std::ops::{Add, BitAnd, BitOr, Deref, DerefMut, Not, Sub};
|
||||||
|
|
||||||
/// A coalescing set of intervals
|
/// A coalescing set of intervals
|
||||||
@@ -159,43 +158,41 @@ impl From<&[Interval]> for IntervalSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Not for &IntervalSet {
|
|
||||||
type Output = IntervalSet;
|
|
||||||
fn not(self) -> Self::Output {
|
|
||||||
self.complement()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Add for &IntervalSet {
|
|
||||||
type Output = IntervalSet;
|
|
||||||
fn add(self, other: &IntervalSet) -> Self::Output {
|
|
||||||
self.union(other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Sub for &IntervalSet {
|
|
||||||
type Output = IntervalSet;
|
|
||||||
fn sub(self, other: &IntervalSet) -> Self::Output {
|
|
||||||
self.difference(other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl BitOr for &IntervalSet {
|
|
||||||
type Output = IntervalSet;
|
|
||||||
fn bitor(self, other: &IntervalSet) -> Self::Output {
|
|
||||||
self.union(other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl BitAnd for &IntervalSet {
|
|
||||||
type Output = IntervalSet;
|
|
||||||
fn bitand(self, other: &IntervalSet) -> Self::Output {
|
|
||||||
self.intersection(other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Not for IntervalSet {
|
impl Not for IntervalSet {
|
||||||
type Output = IntervalSet;
|
type Output = Self;
|
||||||
fn not(self) -> Self::Output {
|
fn not(self) -> Self {
|
||||||
self.complement()
|
self.complement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Add for IntervalSet {
|
||||||
|
type Output = Self;
|
||||||
|
fn add(self, other: Self) -> Self {
|
||||||
|
self.union(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub for IntervalSet {
|
||||||
|
type Output = Self;
|
||||||
|
fn sub(self, other: Self) -> Self::Output {
|
||||||
|
self.difference(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitOr for IntervalSet {
|
||||||
|
type Output = Self;
|
||||||
|
fn bitor(self, other: Self) -> Self {
|
||||||
|
self.union(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitAnd for IntervalSet {
|
||||||
|
type Output = Self;
|
||||||
|
fn bitand(self, other: Self) -> Self {
|
||||||
|
self.intersection(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
+75
-12
@@ -5,12 +5,29 @@ use std::ops::{Add, Deref, DerefMut, Sub};
|
|||||||
/// represent where a resource is available, or where it's required
|
/// represent where a resource is available, or where it's required
|
||||||
/// Resources are independent, so overlaps between the
|
/// Resources are independent, so overlaps between the
|
||||||
/// interval sets are possible.
|
/// interval sets are possible.
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct ResourceInterval(HashMap<Resource, IntervalSet>);
|
pub struct ResourceInterval(HashMap<Resource, IntervalSet>);
|
||||||
|
|
||||||
impl ResourceInterval {
|
impl ResourceInterval {
|
||||||
fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
ResourceInterval(HashMap::new())
|
ResourceInterval(HashMap::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, other: ResourceInterval) {
|
||||||
|
for (res, is) in other.iter() {
|
||||||
|
self.0
|
||||||
|
.entry(res.clone())
|
||||||
|
.or_insert(IntervalSet::new())
|
||||||
|
.merge(is);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, other: ResourceInterval) {
|
||||||
|
for (res, is) in other.iter() {
|
||||||
|
let avail = self.0.entry(res.clone()).or_insert(IntervalSet::new());
|
||||||
|
*avail = avail.difference(is);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for ResourceInterval {
|
impl Deref for ResourceInterval {
|
||||||
@@ -37,9 +54,9 @@ impl From<&HashMap<Resource, IntervalSet>> for ResourceInterval {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add for &ResourceInterval {
|
impl Add for ResourceInterval {
|
||||||
type Output = ResourceInterval;
|
type Output = ResourceInterval;
|
||||||
fn add(self, other: &ResourceInterval) -> Self::Output {
|
fn add(self, other: ResourceInterval) -> Self::Output {
|
||||||
let res: HashMap<Resource, IntervalSet> =
|
let res: HashMap<Resource, IntervalSet> =
|
||||||
other.0.iter().fold(self.0.clone(), |mut acc, (res, is)| {
|
other.0.iter().fold(self.0.clone(), |mut acc, (res, is)| {
|
||||||
acc.entry(res.clone())
|
acc.entry(res.clone())
|
||||||
@@ -51,16 +68,62 @@ impl Add for &ResourceInterval {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sub for &ResourceInterval {
|
impl Sub for ResourceInterval {
|
||||||
type Output = ResourceInterval;
|
type Output = ResourceInterval;
|
||||||
fn sub(self, other: &ResourceInterval) -> Self::Output {
|
fn sub(self, other: ResourceInterval) -> Self::Output {
|
||||||
let res: HashMap<Resource, IntervalSet> =
|
let res: HashMap<Resource, IntervalSet> = self
|
||||||
other.0.iter().fold(self.0.clone(), |mut acc, (res, is)| {
|
.0
|
||||||
acc.entry(res.clone())
|
.iter()
|
||||||
.or_insert(IntervalSet::new())
|
.map(|(res, is)| {
|
||||||
.difference(is);
|
(
|
||||||
acc
|
res.clone(),
|
||||||
});
|
is.difference(other.get(res).unwrap_or(&IntervalSet::new())),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
ResourceInterval(res)
|
ResourceInterval(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
macro_rules! intv {
|
||||||
|
( $x:literal, $y:literal ) => {
|
||||||
|
Interval::new(
|
||||||
|
Utc.ymd(2022, 1, 1).and_hms($x, 0, 0),
|
||||||
|
Utc.ymd(2022, 1, 1).and_hms($y, 0, 0),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! ri {
|
||||||
|
( $r:literal, $(($x:literal, $y:literal)),* ) => {
|
||||||
|
ResourceInterval::from(HashMap::from([(
|
||||||
|
$r.to_owned(),
|
||||||
|
IntervalSet::from(vec![$(intv!($x, $y)),*]),
|
||||||
|
)]))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_conversion() {
|
||||||
|
let ri = ResourceInterval::from(HashMap::from([("alpha".to_owned(), IntervalSet::new())]));
|
||||||
|
assert_eq!(ri.len(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_addition() {
|
||||||
|
let a = ri!("alpha", (13, 15));
|
||||||
|
|
||||||
|
assert_eq!(a + ri!("alpha", (15, 18)), ri!("alpha", (13, 18)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subtraction() {
|
||||||
|
let a = ri!("alpha", (13, 18));
|
||||||
|
|
||||||
|
assert_eq!(a - ri!("alpha", (15, 16)), ri!("alpha", (13, 15), (16, 18)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -157,7 +157,7 @@ impl Task {
|
|||||||
)]));
|
)]));
|
||||||
self.provides.iter().all(|res| {
|
self.provides.iter().all(|res| {
|
||||||
if let Some(is) = available.get(res) {
|
if let Some(is) = available.get(res) {
|
||||||
!(&horizon_is - is).is_empty()
|
!(horizon_is.difference(is)).is_empty()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user