Skip to content

Commit

Permalink
Merge pull request #687 from smeup/perf/clear_stmt
Browse files Browse the repository at this point in the history
Perf/clear stmt
  • Loading branch information
lanarimarco authored Dec 19, 2024
2 parents 6103b79 + 9df1d83 commit 4f05bcc
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 14 deletions.
18 changes: 17 additions & 1 deletion examples/src/main/kotlin/com/jariko/samples/RpgSamples.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* Copyright 2019 Sme.UP S.p.A.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.jariko.samples

import com.smeup.rpgparser.execution.Configuration
Expand Down Expand Up @@ -125,5 +141,5 @@ fun passDSToJariko() {
),
value = DecimalValue(BigDecimal.valueOf(12.12)))
// call program passing the string representation of dataStructValue
commandLineProgram.singleCall(arrayListOf(dataStructValue.value))
commandLineProgram.singleCall(arrayListOf(dataStructValue.value.toString()))
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ fun Value.stringRepresentation(format: String? = null): String {
is NumberValue -> render()
is ArrayValue -> "[${elements().joinToString(", ") { it.render() }}]"
is TimeStampValue -> timestampFormatting(format)
is DataStructValue -> value.trimEnd()
is DataStructValue -> value.toString().trimEnd()
is ZeroValue -> STRING_REPRESENTATION
is AllValue -> charsToRepeat
is OccurableDataStructValue -> value().value.trimEnd()
is OccurableDataStructValue -> value().value.toString().trimEnd()
is UnlimitedStringValue -> value.trimEnd()
else -> TODO("Unable to render value $this (${this.javaClass.canonicalName})")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.smeup.dspfparser.linesclassifier.DSPFValue
import com.smeup.rpgparser.interpreter.*
import com.smeup.rpgparser.serialization.BigDecimalSerializer
import com.smeup.rpgparser.serialization.LocalDateTimeSerializer
import com.smeup.rpgparser.serialization.StringBuilderSerializer
import kotlinx.serialization.*
import kotlinx.serialization.cbor.Cbor
import kotlinx.serialization.json.Json
Expand All @@ -32,6 +33,7 @@ import kotlinx.serialization.modules.subclass
private val module = SerializersModule {
contextual(BigDecimalSerializer)
contextual(LocalDateTimeSerializer)
contextual(StringBuilderSerializer)
polymorphic(Value::class) {
subclass(IntValue::class)
subclass(DecimalValue::class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* Copyright 2019 Sme.UP S.p.A.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.smeup.rpgparser.interpreter

import com.smeup.rpgparser.utils.EBCDICComparator
Expand Down Expand Up @@ -58,7 +74,7 @@ fun sortA(value: Value, arrayType: ArrayType) {
val resultList = elementsLeft + sortedElementsToSort + elementsRight

// return value
value.container.value = resultList.joinToString("")
value.container.value.clear().append(resultList.joinToString(""))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package com.smeup.rpgparser.interpreter
Expand Down Expand Up @@ -1098,7 +1097,10 @@ fun Type.blank(): Value {
* StringValue wrapper
*/
@Serializable
data class DataStructValue(var value: String, private val optionalExternalLen: Int? = null) : Value {
data class DataStructValue(@Contextual val value: StringBuilder, private val optionalExternalLen: Int? = null) : Value {

constructor(value: String) : this(StringBuilder(value))

// We can't serialize a class with a var computed from another one because of a bug in the serialization plugin
// See https://github.com/Kotlin/kotlinx.serialization/issues/133
val len by lazy { optionalExternalLen ?: value.length }
Expand All @@ -1115,7 +1117,7 @@ data class DataStructValue(var value: String, private val optionalExternalLen: I
}
}

override fun copy() = DataStructValue(value).apply {
override fun copy() = DataStructValue(value.toString()).apply {
unlimitedStringField.forEach { entry ->
this.unlimitedStringField[entry.key] = entry.value.copy()
}
Expand Down Expand Up @@ -1192,7 +1194,7 @@ data class DataStructValue(var value: String, private val optionalExternalLen: I
// changed to >= a small value fits in a bigger one
require(endOffset - startOffset >= substringValue.value.length) { "Setting value $substringValue, with length ${substringValue.value.length}, into field of length ${endOffset - startOffset}" }
substringValue.pad(endOffset - startOffset)
value = value.substring(0, startOffset) + substringValue.value + value.substring(endOffset)
value.replace(startOffset, endOffset, substringValue.value)
}

fun getSubstring(startOffset: Int, endOffset: Int): StringValue {
Expand Down Expand Up @@ -1257,7 +1259,7 @@ data class DataStructValue(var value: String, private val optionalExternalLen: I
return "DataStructureValue[${value.length}]($value)"
}

override fun asString() = StringValue(this.value)
override fun asString() = StringValue(this.value.toString())

// Use this method when need to compare to StringValue
fun asStringValue(): String {
Expand All @@ -1274,6 +1276,29 @@ data class DataStructValue(var value: String, private val optionalExternalLen: I
fun isBlank(): Boolean {
return this.value.isBlank()
}

override fun equals(other: Any?): Boolean {
// StringBuilder seems not implementing equals
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as DataStructValue

if (optionalExternalLen != other.optionalExternalLen) return false
if (len != other.len) return false
if (value.toString() != (value.toString())) return false
if (unlimitedStringField != other.unlimitedStringField) return false

return true
}

override fun hashCode(): Int {
var result = optionalExternalLen ?: 0
result = 31 * result + len
result = 31 * result + value.hashCode()
result = 31 * result + unlimitedStringField.hashCode()
return result
}
}

fun Int.asValue() = IntValue(this.toLong())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* Copyright 2019 Sme.UP S.p.A.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.smeup.rpgparser.serialization

import kotlinx.serialization.KSerializer
Expand All @@ -19,4 +35,10 @@ object LocalDateTimeSerializer : KSerializer<LocalDateTime> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: LocalDateTime) = encoder.encodeString(value.toString())
override fun deserialize(decoder: Decoder): LocalDateTime = LocalDateTime.parse(decoder.decodeString())
}

object StringBuilderSerializer : KSerializer<StringBuilder> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("StringBuilder", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: StringBuilder) = encoder.encodeString(value.toString())
override fun deserialize(decoder: Decoder): StringBuilder = StringBuilder(decoder.decodeString())
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@ package com.smeup.rpgparser.evaluation

import com.smeup.rpgparser.AbstractTest
import com.smeup.rpgparser.PerformanceTest
import com.smeup.rpgparser.execution.Configuration
import com.smeup.rpgparser.jvminterop.JavaSystemInterface
import org.junit.Test
import org.junit.experimental.categories.Category
import java.time.Duration
import java.util.*
import kotlin.test.assertTrue
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.DurationUnit

open class DSPerformanceTest : AbstractTest() {

Expand All @@ -32,8 +37,8 @@ open class DSPerformanceTest : AbstractTest() {
val regex = Regex(pattern = "PERFORMANCE RATIO: ((?:\\d+)?\\.\\d+)")
val systemInterface = JavaSystemInterface().apply {
onDisplay = { message, _ ->
println(message)
regex.matchEntire(message)?.let { mathResult ->
println(message.trim())
regex.matchEntire(message.trim())?.let { mathResult ->
mathResult.groups[1]?.value?.let { value ->
performanceRatio = value.toDouble()
}
Expand All @@ -42,7 +47,27 @@ open class DSPerformanceTest : AbstractTest() {
}
executePgm(programName = "DSPERF01", systemInterface = systemInterface)
require(performanceRatio != 0.0) { "performanceRatio must be initialized" }
assertTrue(performanceRatio > 100,
"performanceRatio must be at least 100")
assertTrue(performanceRatio > 10,
"performanceRatio must be at least 10")
}

@Test
@Category(PerformanceTest::class)
fun executeDSPERF02() {
lateinit var start: Date
lateinit var end: Date
val configuration = Configuration().apply {
jarikoCallback.onEnterPgm = { _, _ ->
start = Date()
}
jarikoCallback.onExitPgm = { _, _, _ ->
end = Date()
}
}
"DSPERF02".outputOf(configuration = configuration)
val duration = Duration.between(start.toInstant(), end.toInstant()).toMillis().milliseconds
println(duration)
// Currently the assertion is really empirical
assertTrue(duration.toLong(DurationUnit.SECONDS) < 2, "Duration must be less than 2 second")
}
}
15 changes: 15 additions & 0 deletions rpgJavaInterpreter-core/src/test/resources/DSPERF02.rpgle
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
D DS
D SMEP 200 DIM(10000)
D SMEP_G_P 02 0 OVERLAY(SMEP:01)
D SMEP_G_A 02 0 OVERLAY(SMEP:*NEXT)
D SMEP_P01 07 0 OVERLAY(SMEP:*NEXT)
D SMEP_P02 07 0 OVERLAY(SMEP:*NEXT)
D SMEP_TVA 20 OVERLAY(SMEP:*NEXT)
D SMEP_VAL 100 OVERLAY(SMEP:*NEXT)

C CLEAR SMEP_G_P
C CLEAR SMEP_G_A
C CLEAR SMEP_P01
C CLEAR SMEP_P02
C CLEAR SMEP_TVA
C CLEAR SMEP_VAL

0 comments on commit 4f05bcc

Please sign in to comment.