raphtory_api/core/storage/
timeindex.rs

1use crate::iter::BoxedLIter;
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use std::{fmt, ops::Range};
5
6#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Ord, PartialOrd, Eq, Hash)]
7pub struct TimeIndexEntry(pub i64, pub usize);
8
9pub trait AsTime: fmt::Debug + Copy + Ord + Eq + Send + Sync + 'static {
10    fn t(&self) -> i64;
11
12    fn dt(&self) -> Option<DateTime<Utc>> {
13        let t = self.t();
14        DateTime::from_timestamp_millis(t)
15    }
16
17    fn range(w: Range<i64>) -> Range<Self>;
18
19    fn i(&self) -> usize {
20        0
21    }
22
23    fn new(t: i64, s: usize) -> Self;
24}
25
26pub trait TimeIndexLike: TimeIndexOps {
27    fn range_iter(&self, w: Range<Self::IndexType>) -> BoxedLIter<Self::IndexType>;
28
29    fn first_range(&self, w: Range<Self::IndexType>) -> Option<Self::IndexType> {
30        self.range_iter(w).next()
31    }
32
33    fn last_range(&self, w: Range<Self::IndexType>) -> Option<Self::IndexType>;
34}
35
36pub trait TimeIndexIntoOps: Sized {
37    type IndexType: AsTime;
38    type RangeType: TimeIndexIntoOps<IndexType = Self::IndexType>;
39
40    fn into_range(self, w: Range<Self::IndexType>) -> Self::RangeType;
41
42    fn into_range_t(self, w: Range<i64>) -> Self::RangeType {
43        self.into_range(Self::IndexType::range(w))
44    }
45
46    fn into_iter(self) -> impl Iterator<Item = Self::IndexType> + Send + Sync;
47
48    fn into_iter_t(self) -> impl Iterator<Item = i64> + Send {
49        self.into_iter().map(|time| time.t())
50    }
51}
52
53pub trait TimeIndexOps: Send + Sync {
54    type IndexType: AsTime;
55    type RangeType<'a>: TimeIndexOps<IndexType = Self::IndexType> + 'a
56    where
57        Self: 'a;
58
59    fn active(&self, w: Range<Self::IndexType>) -> bool;
60
61    fn active_t(&self, w: Range<i64>) -> bool {
62        self.active(Self::IndexType::range(w))
63    }
64
65    fn range(&self, w: Range<Self::IndexType>) -> Self::RangeType<'_>;
66
67    fn range_t(&self, w: Range<i64>) -> Self::RangeType<'_> {
68        self.range(Self::IndexType::range(w))
69    }
70
71    fn first_t(&self) -> Option<i64> {
72        self.first().map(|ti| ti.t())
73    }
74
75    fn first(&self) -> Option<Self::IndexType>;
76
77    fn last_t(&self) -> Option<i64> {
78        self.last().map(|ti| ti.t())
79    }
80
81    fn last(&self) -> Option<Self::IndexType>;
82
83    fn iter(&self) -> BoxedLIter<Self::IndexType>;
84
85    fn iter_t(&self) -> BoxedLIter<i64> {
86        Box::new(self.iter().map(|time| time.t()))
87    }
88
89    fn len(&self) -> usize;
90}
91
92impl From<i64> for TimeIndexEntry {
93    fn from(value: i64) -> Self {
94        Self::start(value)
95    }
96}
97
98impl TimeIndexEntry {
99    pub const MIN: TimeIndexEntry = TimeIndexEntry(i64::MIN, 0);
100
101    pub const MAX: TimeIndexEntry = TimeIndexEntry(i64::MAX, usize::MAX);
102    pub fn new(t: i64, s: usize) -> Self {
103        Self(t, s)
104    }
105
106    pub fn start(t: i64) -> Self {
107        Self(t, 0)
108    }
109
110    pub fn next(&self) -> Self {
111        if self.1 < usize::MAX {
112            Self(self.0, self.1 + 1)
113        } else if self.0 < i64::MAX {
114            Self(self.0 + 1, 0)
115        } else {
116            *self
117        }
118    }
119
120    pub fn previous(&self) -> Self {
121        if self.1 > 0 {
122            Self(self.0, self.1 - 1)
123        } else if self.0 > i64::MIN {
124            Self(self.0 - 1, 0)
125        } else {
126            *self
127        }
128    }
129
130    pub fn end(t: i64) -> Self {
131        Self(t, usize::MAX)
132    }
133}
134
135impl AsTime for i64 {
136    fn t(&self) -> i64 {
137        *self
138    }
139
140    fn range(w: Range<i64>) -> Range<Self> {
141        w
142    }
143
144    fn new(t: i64, _s: usize) -> Self {
145        t
146    }
147}
148
149impl AsTime for TimeIndexEntry {
150    fn t(&self) -> i64 {
151        self.0
152    }
153    fn range(w: Range<i64>) -> Range<Self> {
154        Self::start(w.start)..Self::start(w.end)
155    }
156
157    fn i(&self) -> usize {
158        self.1
159    }
160
161    fn new(t: i64, s: usize) -> Self {
162        Self(t, s)
163    }
164}