How to transform partitioned tables
This guide will show you how to transform partitioned tables via the transform
method. Transforming partitioned tables applies specified changes to all constituent tables to produce a new partitioned table. If the underlying table changes, the transform is immediately propagated.
This guide assumes you know how to partition a table into subtables. If you don't, read How to use partitionBy
.
Examples
The first example is broken into steps, whereas the second example is contained in a single block of code.
Partition a table
To show how to modify all constituents of a partitioned table, we'll first partition a table into subtables.
source = emptyTable(5).update("IntCol = i", "StrCol = `value`")
result = source.partitionBy("IntCol")
- source
Apply a tranformation
A partitioned table transform uses a unary operator that takes a table as input and returns a table. The operator is applied to all constituent tables to produce a new partitioned table.
When performing table operations that will be applied via a partitioned table transform, they must be done from within an execution context. This is because a transform can produce deferred results; the context ensures that the deferred results are evaluated safely. In the example below, the systemic execution context is used.
The results of the transform aren't visible until a constituent table is retrieved.
import io.deephaven.engine.context.ExecutionContext
import io.deephaven.util.SafeCloseable
ctx = ExecutionContext.getContext()
addOne = { t ->
try (SafeCloseable ignored = ctx.open()) {
return t.update("IntCol2 = IntCol + 1")
}
}
result2 = result.transform(addOne)
Retrieve a constituent table
To retrieve a constituent table, use constituentFor
. Constituent tables are retrieved by their key. In this example, the key is 3
. If a partitioned table was created with more than one key, the keys must be comma-separated.
newConstituent = result2.constituentFor(3)
- newConstituent
Putting it all together
import static io.deephaven.api.agg.Aggregation.AggCount
import static io.deephaven.api.agg.Aggregation.AggAvg
import static io.deephaven.api.agg.Aggregation.AggSum
import io.deephaven.engine.context.ExecutionContext
import io.deephaven.util.SafeCloseable
import org.apache.commons.lang.RandomStringUtils
Random random = new Random()
randSymbol = { ->
return RandomStringUtils.random(1, 'ABCDE')
}
source = emptyTable(100).update("Sym = (String)randSymbol()", "X = randomInt(0, 100)", "Y = randomDouble(-50.0, 50.0)")
ctx = ExecutionContext.getContext()
applyAggs = { t ->
try (SafeCloseable ignored = ctx.open()) {
return t.update("Z = X % 5").aggBy([AggSum("SumX = X"), AggCount("Z"), AggAvg("AvgY = Y")], "Sym")
}
}
partitionedSource = source.partitionBy("Sym")
partitionedResult = partitionedSource.transform(applyAggs)
resultA = partitionedResult.constituentFor("A")
- source
- resultA
The following example is identical to the one above, except that the overloaded transform
is used, which takes the execution context as input. Thus, the table operation in the closure does not need to be performed inside of a try-with-resources block.
import static io.deephaven.api.agg.Aggregation.AggCount
import static io.deephaven.api.agg.Aggregation.AggAvg
import static io.deephaven.api.agg.Aggregation.AggSum
import io.deephaven.engine.context.ExecutionContext
import org.apache.commons.lang.RandomStringUtils
Random random = new Random()
randSymbol = { ->
return RandomStringUtils.random(1, 'ABCDE')
}
source = emptyTable(100).update("Sym = (String)randSymbol()", "X = randomInt(0, 100)", "Y = randomDouble(-50.0, 50.0)")
ctx = ExecutionContext.getContext()
applyAggs = { t ->
return t.update("Z = X % 5").aggBy([AggSum("SumX = X"), AggCount("Z"), AggAvg("AvgY = Y")], "Sym")
}
partitionedSource = source.partitionBy("Sym")
partitionedResult = partitionedSource.transform(ctx, applyAggs, false)
resultA = partitionedResult.constituentFor("A")
- source
- resultA