Skip to content

Commit a47f67e

Browse files
committed
TransformableColumnSet and TransformableSingleColumn are now generalized versions on which transformers like "recursively" can be called.
1 parent 2dddcc0 commit a47f67e

File tree

20 files changed

+440
-392
lines changed

20 files changed

+440
-392
lines changed

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt

Lines changed: 52 additions & 52 deletions
Large diffs are not rendered by default.

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/columns/ColumnSet.kt

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ import org.jetbrains.kotlinx.dataframe.DataFrame
66
import org.jetbrains.kotlinx.dataframe.impl.columns.*
77

88
/**
9+
* ## ColumnSet
910
* Entity that can be resolved into a list of [columns][DataColumn].
1011
*
1112
* Used as a return type of [ColumnsSelector].
1213
* @param C common type of resolved columns
14+
* @see [SingleColumn]
15+
* @see [TransformableColumnSet]
16+
* @see [TransformableSingleColumn]
1317
*/
1418
public interface ColumnSet<out C> {
1519

@@ -21,36 +25,6 @@ public interface ColumnSet<out C> {
2125
public fun resolve(context: ColumnResolutionContext): List<ColumnWithPath<C>>
2226
}
2327

24-
public interface ColumnSetWithRecursively<out C> : ColumnSet<C> {
25-
26-
public fun resolveRecursively(
27-
context: ColumnResolutionContext,
28-
includeGroups: Boolean = true,
29-
includeTopLevel: Boolean = true,
30-
): List<ColumnWithPath<C>>
31-
}
32-
33-
internal fun <C> ColumnSetWithRecursively<C>.recursivelyImpl(
34-
includeGroups: Boolean = true,
35-
includeTopLevel: Boolean = true,
36-
): ColumnSet<C> = object : ColumnSet<C> {
37-
38-
override fun resolve(context: ColumnResolutionContext): List<ColumnWithPath<C>> =
39-
this@recursivelyImpl.resolveRecursively(
40-
context = context,
41-
includeGroups = includeGroups,
42-
includeTopLevel = includeTopLevel,
43-
)
44-
}
45-
46-
47-
public fun interface ColumnSetTransformer {
48-
49-
public fun transform(columnSet: ColumnSet<*>): ColumnSet<*>
50-
}
51-
52-
public operator fun ColumnSetTransformer.invoke(columnSet: ColumnSet<*>): ColumnSet<*> = transform(columnSet)
53-
5428
public class ColumnResolutionContext internal constructor(
5529
internal val df: DataFrame<*>,
5630
internal val unresolvedColumnsPolicy: UnresolvedColumnsPolicy,

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/columns/SingleColumn.kt

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ package org.jetbrains.kotlinx.dataframe.columns
22

33
import org.jetbrains.kotlinx.dataframe.DataColumn
44
import org.jetbrains.kotlinx.dataframe.api.isColumnGroup
5+
import org.jetbrains.kotlinx.dataframe.impl.columns.*
56
import kotlin.contracts.ExperimentalContracts
67
import kotlin.contracts.contract
78

89
/**
910
* Entity that can be [resolved][resolveSingle] into [DataColumn].
1011
*
1112
* @param C Column [type][BaseColumn.type] of resolved column.
13+
* @see [ColumnSet]
14+
* @see [TransformableColumnSet]
15+
* @see [TransformableSingleColumn]
1216
*/
1317
public interface SingleColumn<out C> : ColumnSet<C> {
1418

@@ -19,29 +23,6 @@ public interface SingleColumn<out C> : ColumnSet<C> {
1923
public fun resolveSingle(context: ColumnResolutionContext): ColumnWithPath<C>?
2024
}
2125

22-
internal fun <C> SingleColumnWithRecursively<C>.recursivelyImpl(
23-
includeGroups: Boolean = true,
24-
includeTopLevel: Boolean = true,
25-
): SingleColumn<C> = object : SingleColumn<C> {
26-
27-
override fun resolveSingle(context: ColumnResolutionContext): ColumnWithPath<C>? =
28-
this@recursivelyImpl.resolveSingleRecursively(
29-
context = context,
30-
includeGroups = includeGroups,
31-
includeTopLevel = includeTopLevel,
32-
)
33-
}
34-
35-
public interface SingleColumnWithRecursively<out C> : SingleColumn<C> {
36-
37-
public fun resolveSingleRecursively(
38-
context: ColumnResolutionContext,
39-
includeGroups: Boolean = true,
40-
includeTopLevel: Boolean = true,
41-
): ColumnWithPath<C>?
42-
}
43-
44-
4526
@OptIn(ExperimentalContracts::class)
4627
public fun ColumnSet<*>.isSingleColumn(): Boolean {
4728
contract {

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/pivot.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import org.jetbrains.kotlinx.dataframe.api.forEach
99
import org.jetbrains.kotlinx.dataframe.api.groupBy
1010
import org.jetbrains.kotlinx.dataframe.api.toPath
1111
import org.jetbrains.kotlinx.dataframe.columns.*
12-
import org.jetbrains.kotlinx.dataframe.columns.ColumnSetTransformer
1312
import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy
1413
import org.jetbrains.kotlinx.dataframe.impl.aggregation.GroupByReceiverImpl
1514
import org.jetbrains.kotlinx.dataframe.impl.aggregation.receivers.AggregateInternalDsl

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/sort.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import org.jetbrains.kotlinx.dataframe.api.getFrameColumn
1010
import org.jetbrains.kotlinx.dataframe.api.update
1111
import org.jetbrains.kotlinx.dataframe.api.with
1212
import org.jetbrains.kotlinx.dataframe.columns.*
13-
import org.jetbrains.kotlinx.dataframe.columns.ColumnSetTransformer
1413
import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy
1514
import org.jetbrains.kotlinx.dataframe.impl.columns.addPath
1615
import org.jetbrains.kotlinx.dataframe.impl.columns.assertIsComparable

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/ColumnsList.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package org.jetbrains.kotlinx.dataframe.impl.columns
22

33
import org.jetbrains.kotlinx.dataframe.columns.ColumnResolutionContext
44
import org.jetbrains.kotlinx.dataframe.columns.ColumnSet
5-
import org.jetbrains.kotlinx.dataframe.columns.ColumnSetTransformer
6-
import org.jetbrains.kotlinx.dataframe.columns.ColumnWithPath
75

86
internal class ColumnsList<C>(val columns: List<ColumnSet<C>>) : ColumnSet<C> {
97
constructor(vararg columns: ColumnSet<C>) : this(columns.toList())

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/DistinctColumnSet.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package org.jetbrains.kotlinx.dataframe.impl.columns
22

33
import org.jetbrains.kotlinx.dataframe.columns.ColumnResolutionContext
44
import org.jetbrains.kotlinx.dataframe.columns.ColumnSet
5-
import org.jetbrains.kotlinx.dataframe.columns.ColumnSetTransformer
65
import org.jetbrains.kotlinx.dataframe.columns.ColumnWithPath
76

87
internal class DistinctColumnSet<T>(val src: ColumnSet<T>) : ColumnSet<T> {
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package org.jetbrains.kotlinx.dataframe.impl.columns
2+
3+
import org.jetbrains.kotlinx.dataframe.api.isColumnGroup
4+
import org.jetbrains.kotlinx.dataframe.columns.*
5+
import org.jetbrains.kotlinx.dataframe.impl.columns.tree.flattenRecursively
6+
7+
internal fun <C> TransformableColumnSet<C>.recursivelyImpl(
8+
includeGroups: Boolean = true,
9+
includeTopLevel: Boolean = true,
10+
): ColumnSet<C> = object : ColumnSet<C> {
11+
12+
override fun resolve(context: ColumnResolutionContext): List<ColumnWithPath<C>> =
13+
this@recursivelyImpl.transformResolve(
14+
context = context,
15+
transformer = RecursivelyTransformer(
16+
includeGroups = includeGroups,
17+
includeTopLevel = includeTopLevel,
18+
),
19+
)
20+
}
21+
22+
internal fun <C> TransformableSingleColumn<C>.recursivelyImpl(
23+
includeGroups: Boolean = true,
24+
includeTopLevel: Boolean = true,
25+
): SingleColumn<C> = object : SingleColumn<C> {
26+
27+
override fun resolveSingle(context: ColumnResolutionContext): ColumnWithPath<C>? =
28+
this@recursivelyImpl.transformResolveSingle(
29+
context = context,
30+
transformer = RecursivelyTransformer(
31+
includeGroups = includeGroups,
32+
includeTopLevel = includeTopLevel,
33+
),
34+
)
35+
}
36+
37+
private class RecursivelyTransformer(
38+
val includeGroups: Boolean = true,
39+
val includeTopLevel: Boolean = true,
40+
) : ColumnSetTransformer {
41+
42+
override fun transform(columnSet: ColumnSet<*>): ColumnSet<*> =
43+
columnSet.flattenRecursively(
44+
includeGroups = includeGroups,
45+
includeTopLevel = includeTopLevel,
46+
)
47+
48+
override fun transformSingle(singleColumn: SingleColumn<*>): ColumnSet<*> =
49+
singleColumn.flattenRecursivelySingle(
50+
includeGroups = includeGroups,
51+
includeTopLevel = includeTopLevel,
52+
)
53+
}
54+
55+
internal fun ColumnSet<*>.flattenRecursively(
56+
includeGroups: Boolean = true,
57+
includeTopLevel: Boolean = true,
58+
): ColumnSet<*> = transform { list ->
59+
val cols =
60+
if (isSingleColumnGroup(list)) {
61+
list.single().children()
62+
} else {
63+
list
64+
}
65+
66+
if (includeTopLevel) {
67+
cols.flattenRecursively()
68+
} else {
69+
cols
70+
.filter { it.isColumnGroup() }
71+
.flatMap { it.children().flattenRecursively() }
72+
}.filter { includeGroups || !it.isColumnGroup() }
73+
}
74+
75+
internal fun SingleColumn<*>.flattenRecursivelySingle(
76+
includeGroups: Boolean = true,
77+
includeTopLevel: Boolean = true,
78+
): ColumnSet<*> = transformSingle {
79+
val cols =
80+
if (isSingleColumnGroup(listOf(it))) {
81+
it.children()
82+
} else {
83+
listOf(it)
84+
}
85+
86+
if (includeTopLevel) {
87+
cols.flattenRecursively()
88+
} else {
89+
cols
90+
.filter { it.isColumnGroup() }
91+
.flatMap { it.children().flattenRecursively() }
92+
}.filter { includeGroups || !it.isColumnGroup() }
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.jetbrains.kotlinx.dataframe.impl.columns
2+
3+
import org.jetbrains.kotlinx.dataframe.columns.*
4+
import org.jetbrains.kotlinx.dataframe.api.*
5+
6+
/**
7+
* ## Transformable ColumnSet
8+
* This type of [ColumnSet] can be [transformed][transformResolve] before being resolved.
9+
*
10+
* This is especially useful for calls like
11+
* [cols { }][ColumnsSelectionDsl.cols].[recursively()][ColumnsSelectionDsl.recursively],
12+
* where [recursively][ColumnsSelectionDsl.recursively] modifies the [ColumnSet][ColumnSet]
13+
* that [cols { }][ColumnsSelectionDsl.cols] operates on before it's evaluated.
14+
*
15+
* @see [ColumnSet]
16+
* @see [TransformableSingleColumn]
17+
* @see [SingleColumn]
18+
*/
19+
public interface TransformableColumnSet<out C> : ColumnSet<C> {
20+
21+
public fun transformResolve(
22+
context: ColumnResolutionContext,
23+
transformer: ColumnSetTransformer,
24+
): List<ColumnWithPath<C>>
25+
}
26+
27+
/**
28+
* ## Transformable SingleColumn
29+
* This type of [SingleColumn] can be [transformed][transformResolveSingle] before being resolved.
30+
*
31+
* This is especially useful for calls like
32+
* [first { }][ColumnsSelectionDsl.first].[recursively()][ColumnsSelectionDsl.recursively],
33+
* where [recursively][ColumnsSelectionDsl.recursively] modifies the [ColumnSet][ColumnSet]
34+
* that [first { }][ColumnsSelectionDsl.first] operates on before it's evaluated.
35+
*
36+
* @see [SingleColumn]
37+
* @see [TransformableColumnSet]
38+
* @see [ColumnSet]
39+
*/
40+
public interface TransformableSingleColumn<out C> : SingleColumn<C> {
41+
42+
public fun transformResolveSingle(
43+
context: ColumnResolutionContext,
44+
transformer: ColumnSetTransformer,
45+
): ColumnWithPath<C>?
46+
}
47+
48+
public interface ColumnSetTransformer {
49+
50+
public fun transform(columnSet: ColumnSet<*>): ColumnSet<*>
51+
52+
public fun transformSingle(singleColumn: SingleColumn<*>): ColumnSet<*>
53+
}

0 commit comments

Comments
 (0)