diff options
author | metamuffin <yvchraiqi@protonmail.com> | 2022-06-11 14:32:45 +0200 |
---|---|---|
committer | metamuffin <yvchraiqi@protonmail.com> | 2022-06-11 14:32:45 +0200 |
commit | c2699d114c921ab2ceb1f467b32a26257dddcf3d (patch) | |
tree | 0e886d333d944094c8c66905cac36a21cd010405 /karld/src/helper.rs | |
parent | 9769c17c0b4c271c1cfbe726b19a6d3f9250c7c8 (diff) | |
download | karlender-c2699d114c921ab2ceb1f467b32a26257dddcf3d.tar karlender-c2699d114c921ab2ceb1f467b32a26257dddcf3d.tar.bz2 karlender-c2699d114c921ab2ceb1f467b32a26257dddcf3d.tar.zst |
changing the protocol again
Diffstat (limited to 'karld/src/helper.rs')
-rw-r--r-- | karld/src/helper.rs | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/karld/src/helper.rs b/karld/src/helper.rs new file mode 100644 index 0000000..2e601b0 --- /dev/null +++ b/karld/src/helper.rs @@ -0,0 +1,98 @@ +use crate::condition::{ConditionFind, Direction, Edge}; +use chrono::{NaiveDate, NaiveDateTime}; +use karlcommon::{Schedule, Task}; +use std::{collections::HashMap, ops::Range}; + +pub struct DiscreteCache { + tasks: HashMap<u64, DiscreteCacheTask>, +} +pub struct DiscreteCacheTask { + inner: Task, + cached: Option<Range<NaiveDateTime>>, + cache: Vec<Range<NaiveDateTime>>, +} + +impl DiscreteCache { + pub fn new_for(tasks: HashMap<u64, Task>) -> Self { + Self { + tasks: HashMap::from_iter( + tasks + .into_iter() + .map(|(k, v)| (k, DiscreteCacheTask::new(v))), + ), + } + } +} + +impl DiscreteCacheTask { + pub fn new(inner: Task) -> Self { + Self { + inner, + cached: None, + cache: vec![], + } + } + + pub fn find(&mut self, from: NaiveDateTime, dir: Direction) -> Range<Option<NaiveDateTime>> { + assert_eq!(dir, Direction::Forward); + // TODO cache + // if let Some(c) = self.cached {} + match &self.inner.schedule { + Schedule::Condition(o) => { + let start = o.find(Edge::Start, dir, from); + let end = o.find(Edge::End, dir, from); + match (start, end) { + (Some(start), Some(end)) => { + if end < start { + if let Some(start) = o.find(Edge::Start, dir.invert(), from) { + assert!(start < end); + Some(start)..Some(end) + } else { + None..Some(end) + } + } else { + Some(start)..Some(end) + } + } + (None, Some(end)) => { + if let Some(start) = o.find(Edge::Start, dir.invert(), from) { + assert!(start < end); + Some(start)..Some(end) + } else { + None..Some(end) + } + } + (Some(start), None) => Some(start)..None, + (None, None) => None..None, + } + } + Schedule::Never => None..None, + Schedule::Static(_) => None..None, // TODO + Schedule::Dynamic { .. } => None..None, // TODO + } + } +} + +pub trait Overlaps<T> { + fn overlaps(&self, v: T) -> bool; +} +impl Overlaps<i64> for Range<i64> { + fn overlaps(&self, v: i64) -> bool { + self.start <= v && v < self.end + } +} +impl Overlaps<i64> for Range<Option<i64>> { + fn overlaps(&self, v: i64) -> bool { + match (self.start, self.end) { + (Some(s), Some(e)) => s <= v && v < e, + (Some(s), None) => s <= v, + (None, Some(e)) => v < e, + (None, None) => false, + } + } +} +impl Overlaps<Range<i64>> for Range<Option<i64>> { + fn overlaps(&self, v: Range<i64>) -> bool { + self.overlaps(v.start) || self.overlaps(v.end) + } +} |