@@ -12,32 +12,30 @@ import kotlin.reflect.KType
12
12
import kotlin.reflect.full.withNullability
13
13
14
14
/* *
15
- * Base interface for all aggregators .
15
+ * This class is the main entry-point for creating an aggregator .
16
16
*
17
- * Aggregators are used to compute a single value from an [Iterable ] of values, a single [DataColumn] ,
18
- * or multiple [DataColumns][DataColumn].
17
+ * Aggregators are used to compute a single value from a [Sequence ] of values,
18
+ * a single [DataColumn], or multiple [DataColumns][DataColumn].
19
19
*
20
20
* [Aggregator] follows a dependency injection pattern:
21
21
*
22
22
* Using the constructor or [Aggregator.invoke] function, you can create an [Aggregator] instance with a choice of:
23
- * - [AggregatorAggregationHandler] - the base functionality of the aggregator,
24
- * which computes the result from the input values.
23
+ * - [AggregatorInputHandler] - {@include [AggregatorInputHandler]}
25
24
*
26
- * Options: [ReducingAggregationHandler ], [SelectingAggregationHandler ]
25
+ * Options: [NumberInputHandler ], [AnyInputHandler ]
27
26
*
28
- * - [AggregatorInputHandler] - the input handler,
29
- * which handles specific type checks, conversion, and preprocessing of the input values.
27
+ * - [AggregatorAggregationHandler] - {@include [AggregatorAggregationHandler]}
30
28
*
31
- * Options: [NumberInputHandler ], [AnyInputHandler ]
29
+ * Options: [ReducingAggregationHandler ], [SelectingAggregationHandler ]
32
30
*
33
- * - [AggregatorMultipleColumnsHandler] - the multiple columns handler, which specifies how to aggregate multiple columns.
31
+ * - [AggregatorMultipleColumnsHandler] - {@include [AggregatorMultipleColumnsHandler]}
34
32
*
35
33
* Options: [FlatteningMultipleColumnsHandler], [TwoStepMultipleColumnsHandler], [NoMultipleColumnsHandler]
36
34
*
37
- *
38
- * @param Value The type of the values to be aggregated.
35
+ * @param Value The non-null type of the values to be aggregated.
39
36
* The input can always have nulls, they are filtered out.
40
37
* @param Return The type of the resulting value. Can optionally be nullable.
38
+ * @see [invoke]
41
39
*/
42
40
@PublishedApi
43
41
internal class Aggregator <in Value : Any , out Return : Any ?>(
@@ -49,13 +47,6 @@ internal class Aggregator<in Value : Any, out Return : Any?>(
49
47
AggregatorMultipleColumnsHandler <Value , Return > by multipleColumnsHandler,
50
48
AggregatorAggregationHandler <Value , Return > by aggregationHandler {
51
49
52
- constructor (other: Aggregator <Value , Return >) : this (
53
- name = other.name,
54
- aggregationHandler = other,
55
- inputHandler = other,
56
- multipleColumnsHandler = other,
57
- )
58
-
59
50
// Set the aggregator reference in all handlers to this instance
60
51
init {
61
52
aggregationHandler.init (this )
@@ -73,8 +64,15 @@ internal class Aggregator<in Value : Any, out Return : Any?>(
73
64
override fun toString (): String =
74
65
" Aggregator(name='$name ', aggregationHandler=$aggregationHandler , inputHandler=$inputHandler , multipleColumnsHandler=$multipleColumnsHandler )"
75
66
76
- companion object {
77
- operator fun <Value : Any , Return : Any ?> invoke (
67
+ internal companion object {
68
+
69
+ /* *
70
+ * Factory function for creating an [Aggregator] instance given a name.
71
+ *
72
+ * @see AggregatorProvider
73
+ * @see Aggregator
74
+ */
75
+ internal operator fun <Value : Any , Return : Any ?> invoke (
78
76
aggregationHandler : AggregatorAggregationHandler <Value , Return >,
79
77
inputHandler : AggregatorInputHandler <Value , Return >,
80
78
multipleColumnsHandler : AggregatorMultipleColumnsHandler <Value , Return >,
@@ -90,18 +88,36 @@ internal class Aggregator<in Value : Any, out Return : Any?>(
90
88
}
91
89
}
92
90
91
+ /* *
92
+ * Performs aggregation on the given [values], taking [valueType] into account.
93
+ * If [valueType] is unknown, see [calculateValueType] or [aggregateCalculatingValueType].
94
+ */
93
95
@PublishedApi
94
96
internal fun <Value : Any , Return : Any ?> Aggregator <Value , Return >.aggregate (
95
97
values : Sequence <Value ?>,
96
98
valueType : ValueType ,
97
- ) = aggregateSingleSequence (values, valueType)
99
+ ) = aggregateSequence (values, valueType)
98
100
101
+ /* *
102
+ * Performs aggregation on the given [values], taking [valueType] into account.
103
+ * If [valueType] is unknown, see [calculateValueType] or [aggregateCalculatingValueType].
104
+ */
99
105
@PublishedApi
100
106
internal fun <Value : Any , Return : Any ?> Aggregator <Value , Return >.aggregate (
101
107
values : Sequence <Value ?>,
102
108
valueType : KType ,
103
- ) = aggregate(values, valueType.toValueType())
109
+ ) = aggregate(values, valueType.toValueType(needsFullConversion = false ))
104
110
111
+ /* *
112
+ * If the specific [ValueType] of the input is not known, but you still want to call [aggregate],
113
+ * this function can be called to calculate it by combining the set of known [valueTypes] or
114
+ * by gathering the types from [values].
115
+ *
116
+ * This is a helper function that calls the correct
117
+ * [AggregatorInputHandler.calculateValueType] based on the given input.
118
+ *
119
+ * Giving [valueTypes] is preferred because of efficiency, as it allows for avoiding runtime type checks.
120
+ */
105
121
internal fun <Value : Any , Return : Any ?> Aggregator <Value , Return >.calculateValueType (
106
122
values : Sequence <Value ?>,
107
123
valueTypes : Set <KType >? = null,
@@ -111,31 +127,66 @@ internal fun <Value : Any, Return : Any?> Aggregator<Value, Return>.calculateVal
111
127
calculateValueType(values)
112
128
}
113
129
130
+ /* *
131
+ * If the specific [ValueType] of the input is not known, but you still want to call [aggregate],
132
+ * this function can be called to calculate it by combining the set of known [valueTypes] or
133
+ * by gathering the types from [values] and then aggregating them.
134
+ *
135
+ * Giving [valueTypes] is preferred because of efficiency, as it allows for avoiding runtime type checks.
136
+ */
114
137
internal fun <Value : Any , Return : Any ?> Aggregator <Value , Return >.aggregateCalculatingValueType (
115
138
values : Sequence <Value ?>,
116
139
valueTypes : Set <KType >? = null,
117
- ) = aggregateSingleSequence (
140
+ ) = aggregateSequence (
118
141
values = values,
119
142
valueType = calculateValueType(values, valueTypes),
120
143
)
121
144
145
+ /* *
146
+ * Aggregates the data in the given column and computes a single resulting value.
147
+ */
122
148
internal fun <Value : Any , Return : Any ?> Aggregator <Value , Return >.aggregate (column : DataColumn <Value ?>) =
123
149
aggregateSingleColumn(column)
124
150
151
+ /* *
152
+ * Aggregates the data in the given columns and computes a single resulting value.
153
+ */
125
154
internal fun <Value : Any , Return : Any ?> Aggregator <Value , Return >.aggregate (columns : Sequence <DataColumn <Value ?>>) =
126
155
aggregateMultipleColumns(columns)
127
156
157
+ /* *
158
+ * Gives the index of the aggregation result in the input [values], if it applies.
159
+ * This is used for aggregators with an [AggregatorAggregationHandler] where
160
+ * [Value][Value]` == `[Return][Return], and where the result exists in the input.
161
+ *
162
+ * Like for [SelectingAggregationHandler].
163
+ *
164
+ * Defaults to `-1`.
165
+ *
166
+ * If [valueType] is unknown, see [calculateValueType]
167
+ */
128
168
@PublishedApi
129
169
internal fun <Value : Return & Any , Return : Any ?> Aggregator <Value , Return >.indexOfAggregationResult (
130
170
values : Sequence <Value ?>,
131
171
valueType : ValueType ,
132
172
): Int = indexOfAggregationResultSingleSequence(values, valueType)
133
173
174
+ /* *
175
+ * Gives the index of the aggregation result in the input [values], if it applies.
176
+ * This is used for aggregators with an [AggregatorAggregationHandler] where
177
+ * [Value][Value]` == `[Return][Return], and where the result exists in the input.
178
+ *
179
+ * Like for [SelectingAggregationHandler].
180
+ *
181
+ * Defaults to `-1`.
182
+ *
183
+ * If [valueType] is unknown, see [calculateValueType]
184
+ */
134
185
@PublishedApi
135
186
internal fun <Value : Return & Any , Return : Any ?> Aggregator <Value , Return >.indexOfAggregationResult (
136
187
values : Sequence <Value ?>,
137
188
valueType : KType ,
138
- ): Int = indexOfAggregationResultSingleSequence(values, valueType.toValueType())
189
+ ): Int = indexOfAggregationResultSingleSequence(values, valueType.toValueType(needsFullConversion = false ))
139
190
140
191
@Suppress(" UNCHECKED_CAST" )
141
192
@PublishedApi
@@ -146,20 +197,35 @@ internal fun <Type : Any?> Aggregator<*, *>.cast(): Aggregator<Type & Any, Type>
146
197
internal fun <Value : Any , Return : Any ?> Aggregator <* , * >.cast2 (): Aggregator <Value , Return > =
147
198
this as Aggregator <Value , Return >
148
199
149
- /* * Type alias for [Aggregator.calculateReturnTypeMultipleColumnsOrNull] */
150
- internal typealias CalculateReturnTypeOrNull = (type: KType , emptyInput: Boolean ) -> KType ?
200
+ /* *
201
+ * Type alias for a function that gives the return type of a [Reducer] or [Selector]
202
+ * given some input type and whether the input is empty.
203
+ */
204
+ internal typealias CalculateReturnType = (type: KType , emptyInput: Boolean ) -> KType
151
205
152
206
/* *
153
- * Type alias for the argument for [Aggregator.aggregateSingleSequence ].
154
- * Nulls have already been filtered out when this argument is called.
207
+ * Type alias for a reducer function where the type of the values is provided as [KType ].
208
+ * Nulls have already been filtered out when this function is called.
155
209
*/
156
- internal typealias Reducer <Value , Return > = Sequence <Value & Any >.(type : KType ) -> Return
210
+ internal typealias Reducer <Value , Return > = Sequence <Value & Any >.(valueType : KType ) -> Return
157
211
158
- internal typealias IndexOfResult <Value > = Sequence <Value ?>.(type: KType ) -> Int
212
+ /* *
213
+ * Type alias for a selector function where the type of the values is provided as [KType].
214
+ *
215
+ * It is expected that [Value][Value]` : `[Return][Return]` & `[Any][Any], and [Return][Return]` : `[Any?][Any].
216
+ *
217
+ * Nulls have already been filtered out when this function is called.
218
+ */
219
+ internal typealias Selector <Value , Return > = Sequence <Value & Any >.(type: KType ) -> Return
159
220
160
- internal typealias IsBetterThanSelector <Value > = (Value & Any ).(other: Value & Any , valueType: KType ) -> Boolean
221
+ /* *
222
+ * Type alias for a function that returns the index of the result of [Selector] in this sequence.
223
+ * If the result is not in the sequence, it returns -1.
224
+ * The type of the values is provided as [KType] and the sequence can contain nulls.
225
+ */
226
+ internal typealias IndexOfResult <Value > = Sequence <Value ?>.(type: KType ) -> Int
161
227
162
- /* * Common case for [CalculateReturnTypeOrNull ], preserves return type, but makes it nullable for empty inputs. */
163
- internal val preserveReturnTypeNullIfEmpty: CalculateReturnTypeOrNull = { type, emptyInput ->
228
+ /* * Common case for [CalculateReturnType ], preserves return type, but makes it nullable for empty inputs. */
229
+ internal val preserveReturnTypeNullIfEmpty: CalculateReturnType = { type, emptyInput ->
164
230
type.withNullability(emptyInput)
165
231
}
0 commit comments