raphtory_api/core/storage/
timeindex.rs

1use std::{fmt, ops::Range};
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
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 TimeIndexIntoOps: Sized {
27    type IndexType: AsTime;
28    type RangeType: TimeIndexIntoOps<IndexType = Self::IndexType>;
29
30    fn into_range(self, w: Range<Self::IndexType>) -> Self::RangeType;
31
32    fn into_range_t(self, w: Range<i64>) -> Self::RangeType {
33        self.into_range(Self::IndexType::range(w))
34    }
35
36    fn into_iter(self) -> impl Iterator<Item = Self::IndexType> + Send;
37
38    fn into_iter_t(self) -> impl Iterator<Item = i64> + Send {
39        self.into_iter().map(|time| time.t())
40    }
41}
42
43pub trait TimeIndexOps: Send + Sync {
44    type IndexType: AsTime;
45    type RangeType<'a>: TimeIndexOps<IndexType = Self::IndexType> + 'a
46    where
47        Self: 'a;
48
49    fn active(&self, w: Range<Self::IndexType>) -> bool;
50
51    fn active_t(&self, w: Range<i64>) -> bool {
52        self.active(Self::IndexType::range(w))
53    }
54
55    fn range(&self, w: Range<Self::IndexType>) -> Self::RangeType<'_>;
56
57    fn range_t(&self, w: Range<i64>) -> Self::RangeType<'_> {
58        self.range(Self::IndexType::range(w))
59    }
60
61    fn first_t(&self) -> Option<i64> {
62        self.first().map(|ti| ti.t())
63    }
64
65    fn first(&self) -> Option<Self::IndexType>;
66
67    fn last_t(&self) -> Option<i64> {
68        self.last().map(|ti| ti.t())
69    }
70
71    fn last(&self) -> Option<Self::IndexType>;
72
73    fn iter(&self) -> Box<dyn Iterator<Item = Self::IndexType> + Send + '_>;
74
75    fn iter_t(&self) -> Box<dyn Iterator<Item = i64> + Send + '_> {
76        Box::new(self.iter().map(|time| time.t()))
77    }
78
79    fn len(&self) -> usize;
80}
81
82impl From<i64> for TimeIndexEntry {
83    fn from(value: i64) -> Self {
84        Self::start(value)
85    }
86}
87
88impl TimeIndexEntry {
89    pub const MIN: TimeIndexEntry = TimeIndexEntry(i64::MIN, 0);
90
91    pub const MAX: TimeIndexEntry = TimeIndexEntry(i64::MAX, usize::MAX);
92    pub fn new(t: i64, s: usize) -> Self {
93        Self(t, s)
94    }
95
96    pub fn start(t: i64) -> Self {
97        Self(t, 0)
98    }
99
100    pub fn next(&self) -> Self {
101        if self.1 < usize::MAX {
102            Self(self.0, self.1 + 1)
103        } else if self.0 < i64::MAX {
104            Self(self.0 + 1, 0)
105        } else {
106            *self
107        }
108    }
109
110    pub fn previous(&self) -> Self {
111        if self.1 > 0 {
112            Self(self.0, self.1 - 1)
113        } else if self.0 > i64::MIN {
114            Self(self.0 - 1, 0)
115        } else {
116            *self
117        }
118    }
119
120    pub fn end(t: i64) -> Self {
121        Self(t, usize::MAX)
122    }
123}
124
125impl AsTime for i64 {
126    fn t(&self) -> i64 {
127        *self
128    }
129
130    fn range(w: Range<i64>) -> Range<Self> {
131        w
132    }
133
134    fn new(t: i64, _s: usize) -> Self {
135        t
136    }
137}
138
139impl AsTime for TimeIndexEntry {
140    fn t(&self) -> i64 {
141        self.0
142    }
143    fn range(w: Range<i64>) -> Range<Self> {
144        Self::start(w.start)..Self::start(w.end)
145    }
146
147    fn i(&self) -> usize {
148        self.1
149    }
150
151    fn new(t: i64, s: usize) -> Self {
152        Self(t, s)
153    }
154}