Skip to content

Commit

Permalink
add accumulator, first impl and its test
Browse files Browse the repository at this point in the history
  • Loading branch information
3cham committed May 11, 2024
1 parent a99e2f7 commit 1eed5d8
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 2 deletions.
11 changes: 11 additions & 0 deletions physical-plan/src/main/kotlin/expressions/AggregateExpression.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.hqew.kquery.physical.expressions

interface AggregateExpression {
fun inputExpression(): Expression
fun createAccumulator(): Accumulator
}

interface Accumulator{
fun accumulate(value: Any?)
fun finalValue() : Any?
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ private fun toString(v: Any?): String {

private fun toBool(v: Any?): Boolean {
when (v) {
is Boolean -> v == true
is Number -> v == 1
is Boolean -> return v == true
is Number -> return v == 1
else -> throw IllegalStateException()
}
}
42 changes: 42 additions & 0 deletions physical-plan/src/main/kotlin/expressions/MaxExpression.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.hqew.kquery.physical.expressions

class MaxExpression(private val expr: Expression) : AggregateExpression {
override fun inputExpression(): Expression {
return expr
}

override fun createAccumulator(): Accumulator {
return MaxAccumulator()
}

override fun toString(): String {
return "MAX($expr)"
}
}

class MaxAccumulator : Accumulator {
var value: Any? = null
override fun accumulate(value: Any?) {
if (value != null) {
if (this.value == null) {
this.value = value
} else {
val isMax = when(value) {
is Byte -> value > this.value as Byte
is Short -> value > this.value as Short
is Int -> value > this.value as Int
is Long -> value > this.value as Long
is Float -> value > this.value as Float
is Double -> value > this.value as Double
is String -> value > this.value as String
else -> throw UnsupportedOperationException("MAX does not support type of ${value.javaClass.name} ")
}
if (isMax) this.value = value
}
}
}

override fun finalValue(): Any? {
return this.value
}
}
28 changes: 28 additions & 0 deletions physical-plan/src/test/kotlin/AccumulatorTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import io.hqew.kquery.physical.expressions.MaxAccumulator
import org.junit.Test
import org.junit.jupiter.api.TestInstance
import kotlin.test.assertEquals

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class AccumulatorTest {

@Test
fun `max accumulator should accumulate value`() {
val numbers = listOf(1, 2, 3, 5, 4)
val maxAcc = MaxAccumulator()

numbers.forEach { maxAcc.accumulate(it) }

assertEquals(5, maxAcc.finalValue())
}

@Test
fun `max accumulator should accumulate string value`() {
val numbers = listOf("10", "2", "3", "5", "4", "a")
val maxAcc = MaxAccumulator()

numbers.forEach { maxAcc.accumulate(it) }

assertEquals("a", maxAcc.finalValue())
}
}

0 comments on commit 1eed5d8

Please sign in to comment.