vortex_array/aggregate_fn/
session.rs1use std::any::Any;
5use std::sync::Arc;
6
7use vortex_session::SessionExt;
8use vortex_session::SessionGuard;
9use vortex_session::SessionVar;
10
11use crate::aggregate_fn::AggregateFnId;
12use crate::aggregate_fn::AggregateFnPluginRef;
13use crate::aggregate_fn::AggregateFnRef;
14use crate::aggregate_fn::AggregateFnVTable;
15use crate::aggregate_fn::fns::all_nan::AllNan;
16use crate::aggregate_fn::fns::all_non_distinct::AllNonDistinct;
17use crate::aggregate_fn::fns::all_non_nan::AllNonNan;
18use crate::aggregate_fn::fns::all_non_null::AllNonNull;
19use crate::aggregate_fn::fns::all_null::AllNull;
20use crate::aggregate_fn::fns::bounded_max::BoundedMax;
21use crate::aggregate_fn::fns::bounded_min::BoundedMin;
22use crate::aggregate_fn::fns::count::Count;
23use crate::aggregate_fn::fns::count::CountGroupedKernel;
24use crate::aggregate_fn::fns::first::First;
25use crate::aggregate_fn::fns::is_constant::IsConstant;
26use crate::aggregate_fn::fns::is_sorted::IsSorted;
27use crate::aggregate_fn::fns::last::Last;
28use crate::aggregate_fn::fns::max::Max;
29use crate::aggregate_fn::fns::min::Min;
30use crate::aggregate_fn::fns::min_max::MinMax;
31use crate::aggregate_fn::fns::nan_count::NanCount;
32use crate::aggregate_fn::fns::null_count::NullCount;
33use crate::aggregate_fn::fns::sum::PrimitiveGroupedSumEncodingKernel;
34use crate::aggregate_fn::fns::sum::Sum;
35use crate::aggregate_fn::fns::uncompressed_size_in_bytes::UncompressedSizeInBytes;
36use crate::aggregate_fn::kernels::DynAggregateKernel;
37use crate::aggregate_fn::kernels::DynGroupedAggregateKernel;
38use crate::arc_swap_map::ArcSwapMap;
39use crate::array::ArrayId;
40use crate::array::VTable;
41use crate::arrays::Chunked;
42use crate::arrays::Dict;
43use crate::arrays::Primitive;
44use crate::arrays::chunked::compute::aggregate::ChunkedArrayAggregate;
45use crate::arrays::dict::compute::is_constant::DictIsConstantKernel;
46use crate::arrays::dict::compute::is_sorted::DictIsSortedKernel;
47use crate::arrays::dict::compute::min_max::DictMinMaxKernel;
48use crate::dtype::DType;
49
50#[derive(Clone, Debug)]
56pub struct AggregateFnSession {
57 registry: ArcSwapMap<AggregateFnId, AggregateFnPluginRef>,
58
59 kernels: ArcSwapMap<AggregateKernelKey, &'static dyn DynAggregateKernel>,
60 grouped_kernels: ArcSwapMap<AggregateFnId, &'static dyn DynGroupedAggregateKernel>,
61 grouped_encoding_kernels:
62 ArcSwapMap<GroupedEncodingKernelKey, &'static dyn DynGroupedAggregateKernel>,
63}
64
65impl SessionVar for AggregateFnSession {
66 fn as_any(&self) -> &dyn Any {
67 self
68 }
69
70 fn as_any_mut(&mut self) -> &mut dyn Any {
71 self
72 }
73}
74
75type AggregateKernelKey = (ArrayId, Option<AggregateFnId>);
76type GroupedEncodingKernelKey = (ArrayId, AggregateFnId);
77
78impl Default for AggregateFnSession {
79 fn default() -> Self {
80 let this = Self {
81 registry: ArcSwapMap::default(),
82 kernels: ArcSwapMap::default(),
83 grouped_kernels: ArcSwapMap::default(),
84 grouped_encoding_kernels: ArcSwapMap::default(),
85 };
86
87 this.register(AllNonDistinct);
89 this.register(AllNonNan);
90 this.register(AllNonNull);
91 this.register(AllNan);
92 this.register(AllNull);
93 this.register(BoundedMax);
94 this.register(BoundedMin);
95 this.register(First);
96 this.register(IsConstant);
97 this.register(IsSorted);
98 this.register(Last);
99 this.register(Max);
100 this.register(Min);
101 this.register(MinMax);
102 this.register(NanCount);
103 this.register(NullCount);
104 this.register(Sum);
105 this.register(UncompressedSizeInBytes);
106
107 this.register_aggregate_kernel(Chunked.id(), None::<AggregateFnId>, &ChunkedArrayAggregate);
109 this.register_aggregate_kernel(Dict.id(), Some(MinMax.id()), &DictMinMaxKernel);
110 this.register_aggregate_kernel(Dict.id(), Some(IsConstant.id()), &DictIsConstantKernel);
111 this.register_aggregate_kernel(Dict.id(), Some(IsSorted.id()), &DictIsSortedKernel);
112
113 this.register_grouped_kernel(Count.id(), &CountGroupedKernel);
115 this.register_grouped_encoding_kernel(
116 Primitive.id(),
117 Sum.id(),
118 &PrimitiveGroupedSumEncodingKernel,
119 );
120
121 this
122 }
123}
124
125impl AggregateFnSession {
126 pub fn find_plugin(&self, id: &AggregateFnId) -> Option<AggregateFnPluginRef> {
128 self.registry.get(id)
129 }
130
131 pub fn register<V: AggregateFnVTable>(&self, vtable: V) {
134 let id = vtable.id();
135 let pluginref = Arc::new(vtable) as AggregateFnPluginRef;
136 self.registry.insert(id, pluginref);
137 }
138
139 pub fn zone_stat_defaults(&self, input_dtype: &DType) -> Vec<AggregateFnRef> {
145 self.registry.read(|registry| {
146 let mut fns: Vec<AggregateFnRef> = registry
147 .values()
148 .filter_map(|plugin| plugin.zone_stat_default(input_dtype))
149 .collect();
150 fns.sort_by_key(|f| f.id());
151 fns
152 })
153 }
154
155 pub fn find_aggregate_kernel(
160 &self,
161 array_id: impl Into<ArrayId>,
162 agg_fn_id: impl Into<AggregateFnId>,
163 ) -> Option<&'static dyn DynAggregateKernel> {
164 let id = array_id.into();
165 let fn_id = agg_fn_id.into();
166 self.kernels.read(|kernels| {
167 kernels
168 .get(&(id, Some(fn_id)))
169 .or_else(|| kernels.get(&(id, None)))
170 .copied()
171 })
172 }
173
174 pub fn register_aggregate_kernel(
180 &self,
181 array_id: impl Into<ArrayId>,
182 agg_fn_id: Option<impl Into<AggregateFnId>>,
183 kernel: &'static dyn DynAggregateKernel,
184 ) {
185 let id = (array_id.into(), agg_fn_id.map(|id| id.into()));
186 self.kernels.insert(id, kernel);
187 }
188
189 pub fn find_grouped_kernel(
194 &self,
195 agg_fn_id: impl Into<AggregateFnId>,
196 ) -> Option<&'static dyn DynGroupedAggregateKernel> {
197 let fn_id = agg_fn_id.into();
198 self.grouped_kernels
199 .read(|kernels| kernels.get(&fn_id).copied())
200 }
201
202 pub fn register_grouped_kernel(
204 &self,
205 agg_fn_id: impl Into<AggregateFnId>,
206 kernel: &'static dyn DynGroupedAggregateKernel,
207 ) {
208 let fn_id = agg_fn_id.into();
209 self.grouped_kernels.insert(fn_id, kernel)
210 }
211
212 pub fn find_grouped_encoding_kernel(
217 &self,
218 array_id: impl Into<ArrayId>,
219 agg_fn_id: impl Into<AggregateFnId>,
220 ) -> Option<&'static dyn DynGroupedAggregateKernel> {
221 let id = array_id.into();
222 let fn_id = agg_fn_id.into();
223 self.grouped_encoding_kernels
224 .read(|kernels| kernels.get(&(id, fn_id)).copied())
225 }
226
227 pub fn register_grouped_encoding_kernel(
229 &self,
230 array_id: impl Into<ArrayId>,
231 agg_fn_id: impl Into<AggregateFnId>,
232 kernel: &'static dyn DynGroupedAggregateKernel,
233 ) {
234 let id = array_id.into();
235 let fn_id = agg_fn_id.into();
236 self.grouped_encoding_kernels.insert((id, fn_id), kernel)
237 }
238}
239
240pub trait AggregateFnSessionExt: SessionExt {
242 fn aggregate_fns(&self) -> SessionGuard<'_, AggregateFnSession> {
244 self.get::<AggregateFnSession>()
245 }
246}
247impl<S: SessionExt> AggregateFnSessionExt for S {}