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