vortex_array/arrays/map/
array.rs1use std::fmt::Display;
5use std::fmt::Formatter;
6use std::hash::Hasher;
7use std::sync::Arc;
8
9use vortex_error::VortexExpect;
10use vortex_error::VortexResult;
11use vortex_error::vortex_ensure;
12use vortex_error::vortex_ensure_eq;
13
14use crate::ArrayEq;
15use crate::ArrayHash;
16use crate::ArrayRef;
17use crate::ArraySlots;
18use crate::EqMode;
19use crate::ExecutionCtx;
20use crate::IntoArray;
21use crate::array::Array;
22use crate::array::ArrayParts;
23use crate::array::TypedArrayRef;
24use crate::array_slots;
25use crate::arrays::ListView;
26use crate::arrays::ListViewArray;
27use crate::arrays::listview::ListViewArrayExt;
28use crate::arrays::map::Map;
29use crate::dtype::DType;
30use crate::dtype::MapDType;
31use crate::validity::Validity;
32
33#[array_slots(Map)]
34pub struct MapSlots {
35 #[slot(0)]
37 pub entries: ArrayRef,
38}
39
40#[derive(Clone, Debug, Default)]
45pub struct MapData;
46
47impl Display for MapData {
48 fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result {
49 Ok(())
50 }
51}
52
53impl ArrayEq for MapData {
54 fn array_eq(&self, _other: &Self, _accuracy: EqMode) -> bool {
55 true
56 }
57}
58
59impl ArrayHash for MapData {
60 fn array_hash<H: Hasher>(&self, _state: &mut H, _accuracy: EqMode) {}
61}
62
63impl MapData {
64 pub(crate) fn make_slots(entries: ArrayRef) -> ArraySlots {
65 MapSlots { entries }.into_slots()
66 }
67}
68
69pub struct MapDataParts {
71 pub map_dtype: MapDType,
73 pub entries: ListViewArray,
75}
76
77pub trait MapArrayExt: MapArraySlotsExt {
79 fn entries_at(&self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult<ArrayRef> {
81 self.entries()
82 .as_::<ListView>()
83 .list_elements_at(index, ctx)
84 }
85
86 fn entry_count_at(&self, index: usize, ctx: &mut ExecutionCtx) -> usize {
88 self.entries().as_::<ListView>().size_at(index, ctx)
89 }
90
91 fn map_validity(&self) -> Validity {
93 self.entries().as_::<ListView>().listview_validity()
94 }
95
96 fn map_dtype(&self) -> &MapDType {
98 self.dtype()
99 .as_map_opt()
100 .vortex_expect("MapArray requires a map dtype")
101 }
102
103 fn keys_sorted(&self) -> bool {
105 self.map_dtype().keys_sorted()
106 }
107}
108impl<T: TypedArrayRef<Map>> MapArrayExt for T {}
109
110impl Array<Map> {
111 pub fn new(map_dtype: MapDType, entries: ListViewArray) -> Self {
118 Self::try_new(map_dtype, entries).vortex_expect("MapArray construction failed")
119 }
120
121 pub fn try_new(map_dtype: MapDType, entries: ListViewArray) -> VortexResult<Self> {
128 let nullability = entries.nullability();
129 let dtype = DType::Map(map_dtype, nullability);
130 let len = entries.len();
131 let slots = MapData::make_slots(entries.into_array());
132 let parts = ArrayParts::new(Map, dtype, len, MapData, slots);
133 Self::try_from_parts(parts)
134 }
135
136 pub unsafe fn new_unchecked(map_dtype: MapDType, entries: ListViewArray) -> Self {
144 let nullability = entries.nullability();
145 let dtype = DType::Map(map_dtype, nullability);
146 let len = entries.len();
147 let slots = MapData::make_slots(entries.into_array());
148 let parts = ArrayParts::new(Map, dtype, len, MapData, slots);
149 unsafe { Self::from_parts_unchecked(parts) }
150 }
151
152 pub fn into_data_parts(self) -> MapDataParts {
154 let map_dtype = self
155 .dtype()
156 .as_map_opt()
157 .vortex_expect("MapArray requires a map dtype")
158 .clone();
159 let entries = self.entries().clone().downcast::<ListView>();
160 MapDataParts { map_dtype, entries }
161 }
162}
163
164fn expected_entries_dtype(map_dtype: &MapDType, nullability: crate::dtype::Nullability) -> DType {
165 DType::List(Arc::new(map_dtype.entries_dtype()), nullability)
166}
167
168pub(super) fn validate_entries(
169 map_dtype: &MapDType,
170 nullability: crate::dtype::Nullability,
171 len: usize,
172 entries: &ArrayRef,
173) -> VortexResult<()> {
174 vortex_ensure!(
175 entries.is::<ListView>(),
176 "MapArray entries must use vortex.listview encoding, got {}",
177 entries.encoding_id()
178 );
179 vortex_ensure_eq!(
180 entries.len(),
181 len,
182 "MapArray entries length does not match outer length",
183 );
184
185 let expected_dtype = expected_entries_dtype(map_dtype, nullability);
186 vortex_ensure_eq!(
187 entries.dtype(),
188 &expected_dtype,
189 "MapArray entries dtype does not match expected dtype",
190 );
191
192 Ok(())
193}