Skip to main content

reifydb_codec/encoded/
u64.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use std::ptr;
5
6use reifydb_value::{reifydb_assertions, value::value_type::ValueType};
7
8use crate::encoded::{row::EncodedRow, shape::RowShape};
9
10impl RowShape {
11	pub fn set_u64(&self, row: &mut EncodedRow, index: usize, value: impl Into<u64>) {
12		let field = &self.fields()[index];
13		reifydb_assertions! {
14			assert!(
15				row.len() >= self.total_static_size(),
16				"row/shape size mismatch: row.len()={} < total_static_size()={}",
17				row.len(),
18				self.total_static_size()
19			);
20			assert_eq!(*field.constraint.get_type().inner_type(), ValueType::Uint8);
21		}
22		row.set_valid(index, true);
23		unsafe {
24			ptr::write_unaligned(
25				row.make_mut().as_mut_ptr().add(field.offset as usize) as *mut u64,
26				value.into(),
27			)
28		}
29	}
30
31	pub fn get_u64(&self, row: &EncodedRow, index: usize) -> u64 {
32		let field = &self.fields()[index];
33		reifydb_assertions! {
34			assert!(
35				row.len() >= self.total_static_size(),
36				"row/shape size mismatch: row.len()={} < total_static_size()={}",
37				row.len(),
38				self.total_static_size()
39			);
40			assert_eq!(*field.constraint.get_type().inner_type(), ValueType::Uint8);
41		}
42		unsafe { (row.as_ptr().add(field.offset as usize) as *const u64).read_unaligned() }
43	}
44
45	pub fn try_get_u64(&self, row: &EncodedRow, index: usize) -> Option<u64> {
46		if row.is_defined(index) && self.fields()[index].constraint.get_type() == ValueType::Uint8 {
47			Some(self.get_u64(row, index))
48		} else {
49			None
50		}
51	}
52}
53
54#[cfg(test)]
55pub mod tests {
56	use reifydb_value::value::value_type::ValueType;
57
58	use crate::encoded::shape::RowShape;
59
60	#[test]
61	fn test_set_get_u64() {
62		let shape = RowShape::testing(&[ValueType::Uint8]);
63		let mut row = shape.allocate();
64		shape.set_u64(&mut row, 0, 18446744073709551615u64);
65		assert_eq!(shape.get_u64(&row, 0), 18446744073709551615u64);
66	}
67
68	#[test]
69	fn test_try_get_u64() {
70		let shape = RowShape::testing(&[ValueType::Uint8]);
71		let mut row = shape.allocate();
72
73		assert_eq!(shape.try_get_u64(&row, 0), None);
74
75		shape.set_u64(&mut row, 0, 18446744073709551615u64);
76		assert_eq!(shape.try_get_u64(&row, 0), Some(18446744073709551615u64));
77	}
78
79	#[test]
80	fn test_extremes() {
81		let shape = RowShape::testing(&[ValueType::Uint8]);
82		let mut row = shape.allocate();
83
84		shape.set_u64(&mut row, 0, u64::MAX);
85		assert_eq!(shape.get_u64(&row, 0), u64::MAX);
86
87		let mut row2 = shape.allocate();
88		shape.set_u64(&mut row2, 0, u64::MIN);
89		assert_eq!(shape.get_u64(&row2, 0), u64::MIN);
90
91		let mut row3 = shape.allocate();
92		shape.set_u64(&mut row3, 0, 0u64);
93		assert_eq!(shape.get_u64(&row3, 0), 0u64);
94	}
95
96	#[test]
97	fn test_large_values() {
98		let shape = RowShape::testing(&[ValueType::Uint8]);
99
100		let test_values = [
101			0u64,
102			1u64,
103			1_000_000_000u64,
104			1_000_000_000_000_000_000u64,
105			9_223_372_036_854_775_807u64, // i64::MAX
106			9_223_372_036_854_775_808u64, // i64::MAX + 1
107			18_000_000_000_000_000_000u64,
108			18_446_744_073_709_551_614u64,
109			18_446_744_073_709_551_615u64, // u64::MAX
110		];
111
112		for value in test_values {
113			let mut row = shape.allocate();
114			shape.set_u64(&mut row, 0, value);
115			assert_eq!(shape.get_u64(&row, 0), value);
116		}
117	}
118
119	#[test]
120	fn test_memory_sizes() {
121		let shape = RowShape::testing(&[ValueType::Uint8]);
122
123		// Test values representing memory sizes in bytes
124		let memory_sizes = [
125			1024u64,                // 1 KB
126			1048576u64,             // 1 MB
127			1073741824u64,          // 1 GB
128			1099511627776u64,       // 1 TB
129			1125899906842624u64,    // 1 PB
130			1152921504606846976u64, // 1 EB
131		];
132
133		for size in memory_sizes {
134			let mut row = shape.allocate();
135			shape.set_u64(&mut row, 0, size);
136			assert_eq!(shape.get_u64(&row, 0), size);
137		}
138	}
139
140	#[test]
141	fn test_nanosecond_timestamps() {
142		let shape = RowShape::testing(&[ValueType::Uint8]);
143
144		// Test nanosecond precision timestamps
145		let ns_timestamps = [
146			0u64,                   // Unix epoch in ns
147			946684800000000000u64,  // 2000-01-01 in ns
148			1640995200000000000u64, // 2022-01-01 in ns
149			1735689600000000000u64, // 2025-01-01 in ns
150		];
151
152		for timestamp in ns_timestamps {
153			let mut row = shape.allocate();
154			shape.set_u64(&mut row, 0, timestamp);
155			assert_eq!(shape.get_u64(&row, 0), timestamp);
156		}
157	}
158
159	#[test]
160	fn test_mixed_with_other_types() {
161		let shape = RowShape::testing(&[ValueType::Uint8, ValueType::Float8, ValueType::Uint8]);
162		let mut row = shape.allocate();
163
164		shape.set_u64(&mut row, 0, 15_000_000_000_000_000_000u64);
165		shape.set_f64(&mut row, 1, 3.14159265359);
166		shape.set_u64(&mut row, 2, 12_000_000_000_000_000_000u64);
167
168		assert_eq!(shape.get_u64(&row, 0), 15_000_000_000_000_000_000u64);
169		assert_eq!(shape.get_f64(&row, 1), 3.14159265359);
170		assert_eq!(shape.get_u64(&row, 2), 12_000_000_000_000_000_000u64);
171	}
172
173	#[test]
174	fn test_undefined_handling() {
175		let shape = RowShape::testing(&[ValueType::Uint8, ValueType::Uint8]);
176		let mut row = shape.allocate();
177
178		shape.set_u64(&mut row, 0, 1234567890123456789u64);
179
180		assert_eq!(shape.try_get_u64(&row, 0), Some(1234567890123456789));
181		assert_eq!(shape.try_get_u64(&row, 1), None);
182
183		shape.set_none(&mut row, 0);
184		assert_eq!(shape.try_get_u64(&row, 0), None);
185	}
186
187	#[test]
188	fn test_try_get_u64_wrong_type() {
189		let shape = RowShape::testing(&[ValueType::Boolean]);
190		let mut row = shape.allocate();
191
192		shape.set_bool(&mut row, 0, true);
193
194		assert_eq!(shape.try_get_u64(&row, 0), None);
195	}
196}