Commit 913cf92f authored by Kevin Cianfarini's avatar Kevin Cianfarini

Avoid excessive calls to buildBinaryString in Encoder

Prior to this commit, encoding values was handled more functionally. A small
optimization to avoid GC churn passes a single `BinaryStringBuilder` reference around
which should avoid unnecessary memory allocations.
parent 3cc04ebc
Pipeline #160989400 passed with stages
in 5 minutes and 43 seconds
package com.corbit.bencoding
import com.corbit.binary.BinaryString
import com.corbit.binary.BinaryStringBuilder
import com.corbit.binary.asBinaryString
import com.corbit.binary.buildBinaryString
internal class Encoder(private val source: BencodedData) {
fun encode(): BinaryString = encodeValue(source)
fun encode(): BinaryString = buildBinaryString {
encodeValue(source, this)
}
private fun encodeValue(value: BencodedData): BinaryString = when (value) {
is BencodedInt -> encodeInt(value)
is BencodedString -> encodeString(value)
is BencodedList -> encodeList(value)
is BencodedDict -> encodeDict(value)
private fun encodeValue(value: BencodedData, builder: BinaryStringBuilder) {
when (value) {
is BencodedInt -> encodeInt(value, builder)
is BencodedString -> encodeString(value, builder)
is BencodedList -> encodeList(value, builder)
is BencodedDict -> encodeDict(value, builder)
}
}
private fun encodeInt(data: BencodedInt) = buildBinaryString {
private fun encodeInt(data: BencodedInt, builder: BinaryStringBuilder) = with(builder) {
append(BencoderToken.INTEGER.token)
append(data.value.toString().asBinaryString())
append(BencoderToken.END.token)
}
private fun encodeString(data: BencodedString) = buildBinaryString {
private fun encodeString(data: BencodedString, builder: BinaryStringBuilder) = with(builder) {
append(data.value.size.toString().asBinaryString())
append(BencoderToken.STRING_SEPARATOR.token)
append(data.value)
}
private fun encodeList(data: BencodedList) = buildBinaryString {
private fun encodeList(data: BencodedList, builder: BinaryStringBuilder) = with(builder) {
append(BencoderToken.LIST.token)
data.forEach { append(encodeValue(it)) }
data.forEach { encodeValue(it, builder) }
append(BencoderToken.END.token)
}
private fun encodeDict(data: BencodedDict) = buildBinaryString {
private fun encodeDict(data: BencodedDict, builder: BinaryStringBuilder) = with(builder) {
append(BencoderToken.DICT.token)
data.forEach { (key, value) ->
append(encodeValue(key))
append(encodeValue(value))
encodeValue(key, builder)
encodeValue(value, builder)
}
append(BencoderToken.END.token)
......
plugins {
kotlin("multiplatform")
}
group = "com.corbit.core"
version = "0.0.1"
repositories {
mavenCentral()
}
kotlin {
/* Targets configuration omitted.
* To find out how to configure the targets, please follow the link:
* https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#setting-up-targets */
sourceSets {
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
implementation(project(":corbit-binary"))
implementation(project(":corbit-bencoding"))
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
}
}
......@@ -10,3 +10,4 @@
rootProject.name = "corbit"
include("corbit-bencoding")
include("corbit-binary")
include("corbit-core")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment