reifydb_core/interface/catalog/
series.rs1use reifydb_type::value::{Value, datetime::DateTime, sumtype::SumTypeId, r#type::Type};
5use serde::{Deserialize, Serialize};
6
7use crate::{
8 interface::catalog::{
9 column::Column,
10 id::{NamespaceId, SeriesId},
11 key::PrimaryKey,
12 },
13 value::column::data::ColumnData,
14};
15
16#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
17#[serde(rename_all = "lowercase")]
18pub enum TimestampPrecision {
19 Millisecond = 0,
20 Microsecond = 1,
21 Nanosecond = 2,
22 Second = 3,
23}
24
25impl Default for TimestampPrecision {
26 fn default() -> Self {
27 TimestampPrecision::Millisecond
28 }
29}
30
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32pub enum SeriesKey {
33 DateTime {
34 column: String,
35 precision: TimestampPrecision,
36 },
37 Integer {
38 column: String,
39 },
40}
41
42impl SeriesKey {
43 pub fn column(&self) -> &str {
44 match self {
45 SeriesKey::DateTime {
46 column,
47 ..
48 } => column,
49 SeriesKey::Integer {
50 column,
51 } => column,
52 }
53 }
54
55 pub fn decode(key_kind: u8, precision_raw: u8, column: String) -> Self {
60 match key_kind {
61 1 => SeriesKey::Integer {
62 column,
63 },
64 _ => {
65 let precision = match precision_raw {
66 1 => TimestampPrecision::Microsecond,
67 2 => TimestampPrecision::Nanosecond,
68 3 => TimestampPrecision::Second,
69 _ => TimestampPrecision::Millisecond,
70 };
71 SeriesKey::DateTime {
72 column,
73 precision,
74 }
75 }
76 }
77 }
78}
79
80#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
81pub struct Series {
82 pub id: SeriesId,
83 pub namespace: NamespaceId,
84 pub name: String,
85 pub columns: Vec<Column>,
86 pub tag: Option<SumTypeId>,
87 pub key: SeriesKey,
88 pub primary_key: Option<PrimaryKey>,
89}
90
91impl Series {
92 pub fn name(&self) -> &str {
93 &self.name
94 }
95
96 pub fn key_column_type(&self) -> Option<Type> {
98 let key_col_name = self.key.column();
99 self.columns.iter().find(|c| c.name == key_col_name).map(|c| c.constraint.get_type())
100 }
101
102 pub fn key_to_u64(&self, value: Value) -> Option<u64> {
108 match value {
109 Value::Int1(v) => u64::try_from(v).ok(),
110 Value::Int2(v) => u64::try_from(v).ok(),
111 Value::Int4(v) => u64::try_from(v).ok(),
112 Value::Int8(v) => u64::try_from(v).ok(),
113 Value::Int16(v) => u64::try_from(v).ok(),
114 Value::Uint1(v) => Some(v as u64),
115 Value::Uint2(v) => Some(v as u64),
116 Value::Uint4(v) => Some(v as u64),
117 Value::Uint8(v) => Some(v),
118 Value::Uint16(v) => u64::try_from(v).ok(),
119 Value::DateTime(dt) => {
120 let nanos = dt.to_nanos();
121 match &self.key {
122 SeriesKey::DateTime {
123 precision,
124 ..
125 } => Some(match precision {
126 TimestampPrecision::Second => nanos / 1_000_000_000,
127 TimestampPrecision::Millisecond => nanos / 1_000_000,
128 TimestampPrecision::Microsecond => nanos / 1_000,
129 TimestampPrecision::Nanosecond => nanos,
130 }),
131 _ => Some(nanos),
132 }
133 }
134 _ => None,
135 }
136 }
137
138 pub fn key_from_u64(&self, v: u64) -> Value {
140 let ty = self.key_column_type();
141 match ty.as_ref() {
142 Some(Type::Int1) => Value::Int1(v as i8),
143 Some(Type::Int2) => Value::Int2(v as i16),
144 Some(Type::Int4) => Value::Int4(v as i32),
145 Some(Type::Int8) => Value::Int8(v as i64),
146 Some(Type::Uint1) => Value::Uint1(v as u8),
147 Some(Type::Uint2) => Value::Uint2(v as u16),
148 Some(Type::Uint4) => Value::Uint4(v as u32),
149 Some(Type::Uint8) => Value::Uint8(v),
150 Some(Type::Uint16) => Value::Uint16(v as u128),
151 Some(Type::Int16) => Value::Int16(v as i128),
152 Some(Type::DateTime) => {
153 let nanos: u64 = match &self.key {
154 SeriesKey::DateTime {
155 precision,
156 ..
157 } => match precision {
158 TimestampPrecision::Second => v * 1_000_000_000,
159 TimestampPrecision::Millisecond => v * 1_000_000,
160 TimestampPrecision::Microsecond => v * 1_000,
161 TimestampPrecision::Nanosecond => v,
162 },
163 _ => v,
164 };
165 Value::DateTime(DateTime::from_nanos(nanos))
166 }
167 _ => Value::Uint8(v),
168 }
169 }
170
171 pub fn key_column_data(&self, keys: Vec<u64>) -> ColumnData {
173 let key_type = self.key_column_type();
174 match &key_type {
175 Some(ty) => {
176 let mut data = ColumnData::with_capacity(ty.clone(), keys.len());
177 for k in keys {
178 data.push_value(self.key_from_u64(k));
179 }
180 data
181 }
182 None => ColumnData::uint8(keys),
183 }
184 }
185
186 pub fn data_columns(&self) -> impl Iterator<Item = &Column> {
188 let key_column = self.key.column().to_string();
189 self.columns.iter().filter(move |c| c.name != key_column)
190 }
191}
192
193#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
194pub struct SeriesMetadata {
195 pub id: SeriesId,
196 pub row_count: u64,
197 pub oldest_key: u64,
198 pub newest_key: u64,
199 pub sequence_counter: u64,
200}
201
202impl SeriesMetadata {
203 pub fn new(series_id: SeriesId) -> Self {
204 Self {
205 id: series_id,
206 row_count: 0,
207 oldest_key: 0,
208 newest_key: 0,
209 sequence_counter: 0,
210 }
211 }
212}