vortex_layout/layouts/dict/
mod.rs1mod reader;
5pub mod writer;
6
7use std::sync::Arc;
8
9use reader::DictReader;
10use vortex_array::DeserializeMetadata;
11use vortex_array::ProstMetadata;
12use vortex_array::dtype::DType;
13use vortex_array::dtype::Nullability;
14use vortex_array::dtype::PType;
15use vortex_error::VortexExpect;
16use vortex_error::VortexResult;
17use vortex_error::vortex_bail;
18use vortex_error::vortex_ensure;
19use vortex_error::vortex_err;
20use vortex_error::vortex_panic;
21use vortex_session::VortexSession;
22use vortex_session::registry::CachedId;
23
24use crate::LayoutBuildContext;
25use crate::LayoutChildType;
26use crate::LayoutEncodingRef;
27use crate::LayoutId;
28use crate::LayoutReaderRef;
29use crate::LayoutRef;
30use crate::VTable;
31use crate::children::LayoutChildren;
32use crate::segments::SegmentId;
33use crate::segments::SegmentSource;
34use crate::vtable;
35
36vtable!(Dict);
37
38impl VTable for Dict {
39 type Layout = DictLayout;
40 type Encoding = DictLayoutEncoding;
41 type Metadata = ProstMetadata<DictLayoutMetadata>;
42
43 fn id(_encoding: &Self::Encoding) -> LayoutId {
44 static ID: CachedId = CachedId::new("vortex.dict");
45 *ID
46 }
47
48 fn encoding(_layout: &Self::Layout) -> LayoutEncodingRef {
49 LayoutEncodingRef::new_ref(DictLayoutEncoding.as_ref())
50 }
51
52 fn row_count(layout: &Self::Layout) -> u64 {
53 layout.codes.row_count()
54 }
55
56 fn dtype(layout: &Self::Layout) -> &DType {
57 layout.values.dtype()
58 }
59
60 fn metadata(layout: &Self::Layout) -> Self::Metadata {
61 let mut metadata =
62 DictLayoutMetadata::new(PType::try_from(layout.codes.dtype()).vortex_expect("ptype"));
63 metadata.is_nullable_codes = Some(layout.codes.dtype().is_nullable());
64 metadata.all_values_referenced = Some(layout.all_values_referenced);
65 ProstMetadata(metadata)
66 }
67
68 fn segment_ids(_layout: &Self::Layout) -> Vec<SegmentId> {
69 vec![]
70 }
71
72 fn nchildren(_layout: &Self::Layout) -> usize {
73 2
74 }
75
76 fn child(layout: &Self::Layout, idx: usize) -> VortexResult<LayoutRef> {
77 match idx {
78 0 => Ok(Arc::clone(&layout.values)),
79 1 => Ok(Arc::clone(&layout.codes)),
80 _ => vortex_bail!("Unreachable child index: {}", idx),
81 }
82 }
83
84 fn child_type(_layout: &Self::Layout, idx: usize) -> LayoutChildType {
85 match idx {
86 0 => LayoutChildType::Auxiliary("values".into()),
87 1 => LayoutChildType::Transparent("codes".into()),
88 _ => vortex_panic!("Unreachable child index: {}", idx),
89 }
90 }
91
92 fn new_reader(
93 layout: &Self::Layout,
94 name: Arc<str>,
95 segment_source: Arc<dyn SegmentSource>,
96 session: &VortexSession,
97 ctx: &crate::LayoutReaderContext,
98 ) -> VortexResult<LayoutReaderRef> {
99 Ok(Arc::new(DictReader::try_new(
100 layout.clone(),
101 name,
102 segment_source,
103 session.clone(),
104 ctx.clone(),
105 )?))
106 }
107
108 fn build(
109 _encoding: &Self::Encoding,
110 dtype: &DType,
111 _row_count: u64,
112 metadata: &<Self::Metadata as DeserializeMetadata>::Output,
113 _segment_ids: Vec<SegmentId>,
114 children: &dyn LayoutChildren,
115 _build_ctx: &LayoutBuildContext<'_>,
116 ) -> VortexResult<Self::Layout> {
117 let values = children.child(0, dtype)?;
118 let codes_nullable = metadata
119 .is_nullable_codes
120 .map(Nullability::from)
121 .unwrap_or_else(|| dtype.nullability());
125 let codes = children.child(1, &DType::Primitive(metadata.codes_ptype(), codes_nullable))?;
126 Ok(unsafe {
127 DictLayout::new(values, codes)
128 .set_all_values_referenced(metadata.all_values_referenced.unwrap_or(false))
129 })
130 }
131
132 fn with_children(layout: &mut Self::Layout, children: Vec<LayoutRef>) -> VortexResult<()> {
133 vortex_ensure!(
134 children.len() == 2,
135 "DictLayout expects exactly 2 children (values, codes), got {}",
136 children.len()
137 );
138 let mut children_iter = children.into_iter();
139 layout.values = children_iter
140 .next()
141 .ok_or_else(|| vortex_err!("Missing values child"))?;
142 layout.codes = children_iter
143 .next()
144 .ok_or_else(|| vortex_err!("Missing codes child"))?;
145 Ok(())
146 }
147}
148
149#[derive(Debug)]
150pub struct DictLayoutEncoding;
151
152#[derive(Clone, Debug)]
157pub struct DictLayout {
158 values: LayoutRef,
159 codes: LayoutRef,
160 all_values_referenced: bool,
164}
165
166impl DictLayout {
167 pub(crate) fn new(values: LayoutRef, codes: LayoutRef) -> Self {
168 Self {
169 values,
170 codes,
171 all_values_referenced: false,
172 }
173 }
174
175 pub unsafe fn set_all_values_referenced(mut self, all_values_referenced: bool) -> Self {
186 self.all_values_referenced = all_values_referenced;
187 self
188 }
189
190 pub fn has_all_values_referenced(&self) -> bool {
191 self.all_values_referenced
192 }
193}
194
195#[derive(prost::Message)]
196pub struct DictLayoutMetadata {
197 #[prost(enumeration = "PType", tag = "1")]
198 codes_ptype: i32,
200 #[prost(optional, bool, tag = "2")]
202 is_nullable_codes: Option<bool>,
203 #[prost(optional, bool, tag = "3")]
208 pub(crate) all_values_referenced: Option<bool>,
209}
210
211impl DictLayoutMetadata {
212 pub fn new(codes_ptype: PType) -> Self {
213 let mut metadata = Self::default();
214 metadata.set_codes_ptype(codes_ptype);
215 metadata
216 }
217}