raphtory_api/core/storage/
timeindex.rs1use 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}