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