1use std::ptr;
5
6use reifydb_type::{Time, Type};
7
8use crate::value::encoded::{EncodedValues, EncodedValuesLayout};
9
10impl EncodedValuesLayout {
11 pub fn set_time(&self, row: &mut EncodedValues, index: usize, value: Time) {
12 let field = &self.fields[index];
13 debug_assert!(row.len() >= self.total_static_size());
14 debug_assert_eq!(field.r#type, Type::Time);
15 row.set_valid(index, true);
16 unsafe {
17 ptr::write_unaligned(
18 row.make_mut().as_mut_ptr().add(field.offset) as *mut u64,
19 value.to_nanos_since_midnight(),
20 )
21 }
22 }
23
24 pub fn get_time(&self, row: &EncodedValues, index: usize) -> Time {
25 let field = &self.fields[index];
26 debug_assert!(row.len() >= self.total_static_size());
27 debug_assert_eq!(field.r#type, Type::Time);
28 unsafe {
29 Time::from_nanos_since_midnight((row.as_ptr().add(field.offset) as *const u64).read_unaligned())
30 .unwrap()
31 }
32 }
33
34 pub fn try_get_time(&self, row: &EncodedValues, index: usize) -> Option<Time> {
35 if row.is_defined(index) {
36 Some(self.get_time(row, index))
37 } else {
38 None
39 }
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use reifydb_type::{Time, Type};
46
47 use crate::value::encoded::EncodedValuesLayout;
48
49 #[test]
50 fn test_set_get_time() {
51 let layout = EncodedValuesLayout::new(&[Type::Time]);
52 let mut row = layout.allocate();
53
54 let value = Time::new(20, 50, 0, 0).unwrap();
55 layout.set_time(&mut row, 0, value.clone());
56 assert_eq!(layout.get_time(&row, 0), value);
57 }
58
59 #[test]
60 fn test_try_get_time() {
61 let layout = EncodedValuesLayout::new(&[Type::Time]);
62 let mut row = layout.allocate();
63
64 assert_eq!(layout.try_get_time(&row, 0), None);
65
66 let test_time = Time::from_hms(14, 30, 45).unwrap();
67 layout.set_time(&mut row, 0, test_time.clone());
68 assert_eq!(layout.try_get_time(&row, 0), Some(test_time));
69 }
70
71 #[test]
72 fn test_time_midnight() {
73 let layout = EncodedValuesLayout::new(&[Type::Time]);
74 let mut row = layout.allocate();
75
76 let midnight = Time::default(); layout.set_time(&mut row, 0, midnight.clone());
78 assert_eq!(layout.get_time(&row, 0), midnight);
79 }
80
81 #[test]
82 fn test_time_with_nanoseconds() {
83 let layout = EncodedValuesLayout::new(&[Type::Time]);
84 let mut row = layout.allocate();
85
86 let precise_time = Time::new(15, 30, 45, 123456789).unwrap();
88 layout.set_time(&mut row, 0, precise_time.clone());
89 assert_eq!(layout.get_time(&row, 0), precise_time);
90 }
91
92 #[test]
93 fn test_time_various_times() {
94 let layout = EncodedValuesLayout::new(&[Type::Time]);
95
96 let test_times = [
97 Time::new(0, 0, 0, 0).unwrap(), Time::new(12, 0, 0, 0).unwrap(), Time::new(23, 59, 59, 999999999).unwrap(), Time::new(6, 30, 15, 500000000).unwrap(), Time::new(18, 45, 30, 750000000).unwrap(), ];
103
104 for time in test_times {
105 let mut row = layout.allocate();
106 layout.set_time(&mut row, 0, time.clone());
107 assert_eq!(layout.get_time(&row, 0), time);
108 }
109 }
110
111 #[test]
112 fn test_time_boundary_cases() {
113 let layout = EncodedValuesLayout::new(&[Type::Time]);
114
115 let boundary_times = [
116 Time::new(0, 0, 0, 0).unwrap(), Time::new(0, 0, 0, 1).unwrap(), Time::new(23, 59, 59, 999999998).unwrap(), Time::new(23, 59, 59, 999999999).unwrap(), ];
122
123 for time in boundary_times {
124 let mut row = layout.allocate();
125 layout.set_time(&mut row, 0, time.clone());
126 assert_eq!(layout.get_time(&row, 0), time);
127 }
128 }
129
130 #[test]
131 fn test_time_mixed_with_other_types() {
132 let layout = EncodedValuesLayout::new(&[Type::Time, Type::Boolean, Type::Time, Type::Int4]);
133 let mut row = layout.allocate();
134
135 let time1 = Time::new(9, 15, 30, 0).unwrap();
136 let time2 = Time::new(21, 45, 0, 250000000).unwrap();
137
138 layout.set_time(&mut row, 0, time1.clone());
139 layout.set_bool(&mut row, 1, false);
140 layout.set_time(&mut row, 2, time2.clone());
141 layout.set_i32(&mut row, 3, -999);
142
143 assert_eq!(layout.get_time(&row, 0), time1);
144 assert_eq!(layout.get_bool(&row, 1), false);
145 assert_eq!(layout.get_time(&row, 2), time2);
146 assert_eq!(layout.get_i32(&row, 3), -999);
147 }
148
149 #[test]
150 fn test_time_undefined_handling() {
151 let layout = EncodedValuesLayout::new(&[Type::Time, Type::Time]);
152 let mut row = layout.allocate();
153
154 let time = Time::new(16, 20, 45, 333000000).unwrap();
155 layout.set_time(&mut row, 0, time.clone());
156
157 assert_eq!(layout.try_get_time(&row, 0), Some(time));
158 assert_eq!(layout.try_get_time(&row, 1), None);
159
160 layout.set_undefined(&mut row, 0);
161 assert_eq!(layout.try_get_time(&row, 0), None);
162 }
163
164 #[test]
165 fn test_time_precision_preservation() {
166 let layout = EncodedValuesLayout::new(&[Type::Time]);
167 let mut row = layout.allocate();
168
169 let high_precision = Time::new(12, 34, 56, 987654321).unwrap();
171 layout.set_time(&mut row, 0, high_precision.clone());
172
173 let retrieved = layout.get_time(&row, 0);
174 assert_eq!(retrieved, high_precision);
175 assert_eq!(retrieved.to_nanos_since_midnight(), high_precision.to_nanos_since_midnight());
176 }
177
178 #[test]
179 fn test_time_microsecond_precision() {
180 let layout = EncodedValuesLayout::new(&[Type::Time]);
181 let mut row = layout.allocate();
182
183 let microsecond_precision = Time::new(14, 25, 30, 123456000).unwrap();
185 layout.set_time(&mut row, 0, microsecond_precision.clone());
186 assert_eq!(layout.get_time(&row, 0), microsecond_precision);
187 }
188
189 #[test]
190 fn test_time_millisecond_precision() {
191 let layout = EncodedValuesLayout::new(&[Type::Time]);
192 let mut row = layout.allocate();
193
194 let millisecond_precision = Time::new(8, 15, 42, 123000000).unwrap();
196 layout.set_time(&mut row, 0, millisecond_precision.clone());
197 assert_eq!(layout.get_time(&row, 0), millisecond_precision);
198 }
199
200 #[test]
201 fn test_time_common_times() {
202 let layout = EncodedValuesLayout::new(&[Type::Time]);
203
204 let common_times = [
206 Time::new(9, 0, 0, 0).unwrap(), Time::new(12, 0, 0, 0).unwrap(), Time::new(17, 0, 0, 0).unwrap(), Time::new(0, 0, 1, 0).unwrap(), Time::new(23, 59, 0, 0).unwrap(), ];
212
213 for time in common_times {
214 let mut row = layout.allocate();
215 layout.set_time(&mut row, 0, time.clone());
216 assert_eq!(layout.get_time(&row, 0), time);
217 }
218 }
219}