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