Skip to main content

reifydb_codec/primitive/
dictionary_id.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use std::ptr;
5
6use reifydb_value::{
7	reifydb_assertions,
8	value::{constraint::Constraint, dictionary::DictionaryEntryId, value_type::ValueType},
9};
10
11use crate::row::{bytes::RowBuilder, shape::RowShape};
12
13impl RowShape {
14	pub fn set_dictionary_id(&self, row: &mut impl RowBuilder, index: usize, entry: &DictionaryEntryId) {
15		let field = &self.fields()[index];
16		reifydb_assertions! {
17			assert!(
18				row.len() >= self.total_static_size(),
19				"row/shape size mismatch: row.len()={} < total_static_size()={}",
20				row.len(),
21				self.total_static_size()
22			);
23			assert_eq!(*field.constraint.get_type().inner_type(), ValueType::DictionaryId);
24		}
25		let id_type = match field.constraint.constraint() {
26			Some(Constraint::Dictionary(_, id_type)) => id_type.clone(),
27			_ => ValueType::Uint4,
28		};
29		let raw = entry.to_u128();
30		self.set_valid(row, index, true);
31		// SAFETY: row.len() >= total_static_size() puts the slot at field.offset inside the uniquely-owned
32		// buffer; each arm writes the slot's read width, which the shape allocated;
33		// write_unaligned needs no alignment.
34		let written = unsafe {
35			let ptr = row.as_mut_slice().as_mut_ptr().add(field.offset as usize);
36			match id_type {
37				ValueType::Uint1 => u8::try_from(raw).map(|v| ptr.write_unaligned(v)),
38				ValueType::Uint2 => {
39					u16::try_from(raw).map(|v| ptr::write_unaligned(ptr as *mut u16, v))
40				}
41				ValueType::Uint8 => {
42					u64::try_from(raw).map(|v| ptr::write_unaligned(ptr as *mut u64, v))
43				}
44				ValueType::Uint16 => {
45					ptr::write_unaligned(ptr as *mut u128, raw);
46					Ok(())
47				}
48				_ => u32::try_from(raw).map(|v| ptr::write_unaligned(ptr as *mut u32, v)),
49			}
50		};
51		if written.is_err() {
52			panic!("dictionary id {raw} does not fit the {id_type} id slot of field {index}");
53		}
54	}
55
56	pub fn get_dictionary_id(&self, row: &[u8], index: usize) -> DictionaryEntryId {
57		let field = &self.fields()[index];
58		reifydb_assertions! {
59			assert!(
60				row.len() >= self.total_static_size(),
61				"row/shape size mismatch: row.len()={} < total_static_size()={}",
62				row.len(),
63				self.total_static_size()
64			);
65			assert_eq!(*field.constraint.get_type().inner_type(), ValueType::DictionaryId);
66		}
67		let id_type = match field.constraint.constraint() {
68			Some(Constraint::Dictionary(_, id_type)) => id_type.clone(),
69			_ => ValueType::Uint4,
70		};
71		// SAFETY: row.len() >= total_static_size() puts the slot at field.offset inside the row and it is at
72		// least as wide as the id type read; the unsigned targets have no invalid bit patterns.
73		unsafe {
74			let ptr = row.as_ptr().add(field.offset as usize);
75			let raw: u128 = match id_type {
76				ValueType::Uint1 => ptr.read_unaligned() as u128,
77				ValueType::Uint2 => (ptr as *const u16).read_unaligned() as u128,
78				ValueType::Uint4 => (ptr as *const u32).read_unaligned() as u128,
79				ValueType::Uint8 => (ptr as *const u64).read_unaligned() as u128,
80				ValueType::Uint16 => (ptr as *const u128).read_unaligned(),
81				_ => (ptr as *const u32).read_unaligned() as u128,
82			};
83			DictionaryEntryId::from_u128(raw, id_type).unwrap()
84		}
85	}
86
87	pub fn try_get_dictionary_id(&self, row: &[u8], index: usize) -> Option<DictionaryEntryId> {
88		if self.is_defined(row, index) && self.fields()[index].constraint.get_type() == ValueType::DictionaryId
89		{
90			Some(self.get_dictionary_id(row, index))
91		} else {
92			None
93		}
94	}
95}