Skip to content

Commit 339bd05

Browse files
committed
Reduces computation by determining scope index at compilation
1 parent fa83338 commit 339bd05

File tree

3 files changed

+58
-22
lines changed

3 files changed

+58
-22
lines changed

partiql-eval/src/main/kotlin/org/partiql/eval/internal/Compiler.kt

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,20 @@ internal class Compiler(
5656
private val symbols: Symbols
5757
) : PlanBaseVisitor<Operator, StaticType?>() {
5858

59+
/**
60+
* The variables environment
61+
*/
5962
private val env: Environment = Environment()
6063

64+
/**
65+
* Aids in determining the index by which we will query [Environment.get] for [Rex.Op.Var.depth].
66+
*
67+
* @see scope
68+
* @see Environment
69+
* @see Rex.Op.Var
70+
*/
71+
private var scopeSize = 0
72+
6173
fun compile(): Operator.Expr {
6274
return visitPartiQLPlan(plan, null)
6375
}
@@ -108,28 +120,34 @@ internal class Compiler(
108120
}
109121

110122
override fun visitRexOpSelect(node: Rex.Op.Select, ctx: StaticType?): Operator.Expr {
111-
val rel = visitRel(node.rel, ctx)
112-
val ordered = node.rel.type.props.contains(Rel.Prop.ORDERED)
113-
val constructor = visitRex(node.constructor, ctx).modeHandled()
114-
return ExprSelect(rel, constructor, ordered, env)
123+
return scope {
124+
val rel = visitRel(node.rel, ctx)
125+
val ordered = node.rel.type.props.contains(Rel.Prop.ORDERED)
126+
val constructor = visitRex(node.constructor, ctx).modeHandled()
127+
ExprSelect(rel, constructor, ordered, env)
128+
}
115129
}
116130

117131
override fun visitRexOpSubquery(node: Rex.Op.Subquery, ctx: StaticType?): Operator {
118-
val constructor = visitRex(node.constructor, ctx)
119-
val input = visitRel(node.rel, ctx)
120-
return when (node.coercion) {
121-
Rex.Op.Subquery.Coercion.SCALAR -> ExprSubquery.Scalar(constructor, input, env)
122-
Rex.Op.Subquery.Coercion.ROW -> ExprSubquery.Row(constructor, input, env)
132+
return scope {
133+
val constructor = visitRex(node.constructor, ctx)
134+
val input = visitRel(node.rel, ctx)
135+
when (node.coercion) {
136+
Rex.Op.Subquery.Coercion.SCALAR -> ExprSubquery.Scalar(constructor, input, env)
137+
Rex.Op.Subquery.Coercion.ROW -> ExprSubquery.Row(constructor, input, env)
138+
}
123139
}
124140
}
125141

126142
override fun visitRexOpPivot(node: Rex.Op.Pivot, ctx: StaticType?): Operator {
127-
val rel = visitRel(node.rel, ctx)
128-
val key = visitRex(node.key, ctx)
129-
val value = visitRex(node.value, ctx)
130-
return when (session.mode) {
131-
PartiQLEngine.Mode.PERMISSIVE -> ExprPivotPermissive(rel, key, value)
132-
PartiQLEngine.Mode.STRICT -> ExprPivot(rel, key, value)
143+
return scope {
144+
val rel = visitRel(node.rel, ctx)
145+
val key = visitRex(node.key, ctx)
146+
val value = visitRex(node.value, ctx)
147+
when (session.mode) {
148+
PartiQLEngine.Mode.PERMISSIVE -> ExprPivotPermissive(rel, key, value)
149+
PartiQLEngine.Mode.STRICT -> ExprPivot(rel, key, value)
150+
}
133151
}
134152
}
135153

@@ -142,7 +160,10 @@ internal class Compiler(
142160
override fun visitRexOpVar(node: Rex.Op.Var, ctx: StaticType?): Operator {
143161
return when (node.depth) {
144162
0 -> ExprVarLocal(node.ref)
145-
else -> ExprVarOuter(node.depth - 1, node.ref, env)
163+
else -> {
164+
val index = scopeSize - node.depth
165+
ExprVarOuter(index, node.ref, env)
166+
}
146167
}
147168
}
148169

@@ -249,7 +270,7 @@ internal class Compiler(
249270

250271
override fun visitRelOpJoin(node: Rel.Op.Join, ctx: StaticType?): Operator {
251272
val lhs = visitRel(node.lhs, ctx)
252-
val rhs = visitRel(node.rhs, ctx)
273+
val rhs = scope { visitRel(node.rhs, ctx) }
253274
val condition = visitRex(node.rex, ctx)
254275
return when (node.type) {
255276
Rel.Op.Join.Type.INNER -> RelJoinInner(lhs, rhs, condition, env)
@@ -320,4 +341,20 @@ internal class Compiler(
320341
}
321342
return item
322343
}
344+
345+
/**
346+
* Figuratively creates a new scope by incrementing/decrementing the [scopeSize] before/after the [block] invocation.
347+
*
348+
* @see scopeSize
349+
* @see Environment
350+
* @see Rex.Op.Var
351+
*/
352+
private inline fun <T> scope(block: () -> T): T {
353+
scopeSize++
354+
try {
355+
return block.invoke()
356+
} finally {
357+
scopeSize--
358+
}
359+
}
323360
}

partiql-eval/src/main/kotlin/org/partiql/eval/internal/Environment.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,9 @@ internal class Environment {
2929
}
3030

3131
/**
32-
* Gets the scope/record/variables-environment at the requested [depth].
32+
* Gets the scope/record/variables-environment at the requested [index].
3333
*/
34-
operator fun get(depth: Int): Record {
35-
val index = scopes.lastIndex - depth
34+
operator fun get(index: Int): Record {
3635
return scopes[index]
3736
}
3837
}

partiql-eval/src/main/kotlin/org/partiql/eval/internal/operator/rex/ExprVarOuter.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import org.partiql.value.PartiQLValueExperimental
1010
* Returns the appropriate value from the stack.
1111
*/
1212
internal class ExprVarOuter(
13-
private val depth: Int,
13+
private val scope: Int,
1414
private val reference: Int,
1515
private val env: Environment
1616
) : Operator.Expr {
1717

1818
@PartiQLValueExperimental
1919
override fun eval(record: Record): PartiQLValue {
20-
return env[depth][reference]
20+
return env[scope][reference]
2121
}
2222
}

0 commit comments

Comments
 (0)