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