diff --git a/dataforge-io/build.gradle.kts b/dataforge-io/build.gradle.kts index 5be52e61..16a6fbfc 100644 --- a/dataforge-io/build.gradle.kts +++ b/dataforge-io/build.gradle.kts @@ -4,7 +4,7 @@ plugins { description = "IO module" -val ioVersion = "0.3.1" +val ioVersion = "0.4.0" kscience { jvm() diff --git a/dataforge-io/dataforge-io-proto/src/jvmMain/kotlin/performanceComparison.kt b/dataforge-io/dataforge-io-proto/src/jvmMain/kotlin/performanceComparison.kt new file mode 100644 index 00000000..74939882 --- /dev/null +++ b/dataforge-io/dataforge-io-proto/src/jvmMain/kotlin/performanceComparison.kt @@ -0,0 +1,51 @@ +package pace.kscience.dataforge.io.proto + +import kotlinx.io.writeString +import space.kscience.dataforge.io.Envelope +import space.kscience.dataforge.meta.asValue +import kotlin.concurrent.thread +import kotlin.time.measureTime + +public fun main() { + val envelope = Envelope { + meta { + "a" put 22 + "node" put { + "b" put "DDD" + "c" put 11.1 + "d" put { + "d1" put { + "d11" put "aaa" + "d12" put "bbb" + } + "d2" put 2 + } + "array" put doubleArrayOf(1.0, 2.0, 3.0) + "array2d" put listOf( + doubleArrayOf(1.0, 2.0, 3.0).asValue(), + doubleArrayOf(1.0, 2.0, 3.0).asValue() + ).asValue() + } + } + data { + writeString("Hello world!") + } + } + + val format = ProtoEnvelopeFormat + + measureTime { + val threads = List(100) { + thread { + repeat(100000) { + val buffer = kotlinx.io.Buffer() + format.writeTo(buffer, envelope) +// println(buffer.size) + val r = format.readFrom(buffer) + } + } + } + + threads.forEach { it.join() } + }.also { println(it) } +} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaRef.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaSpec.kt similarity index 73% rename from dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaRef.kt rename to dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaSpec.kt index 413fe404..7af7594c 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaRef.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaSpec.kt @@ -11,7 +11,7 @@ import kotlin.properties.ReadOnlyProperty /** - * A reference to a read-only value of type [T] inside [MetaProvider] + * A reference to a read-only value of type [T] inside [MetaProvider] or writable value in [MutableMetaProvider] */ @DFExperimental public data class MetaRef( @@ -20,21 +20,36 @@ public data class MetaRef( override val descriptor: MetaDescriptor? = converter.descriptor, ) : Described +/** + * Get a value from provider by [ref] or return null if node with given name is missing + */ @DFExperimental public operator fun MetaProvider.get(ref: MetaRef): T? = get(ref.name)?.let { ref.converter.readOrNull(it) } +/** + * Set a value in a mutable provider by [ref] + */ @DFExperimental public operator fun MutableMetaProvider.set(ref: MetaRef, value: T) { set(ref.name, ref.converter.convert(value)) } +/** + * Remove a node corresponding to [ref] from a mutable provider if it exists + */ @DFExperimental -public class MetaSpec( - private val configuration: MetaDescriptorBuilder.() -> Unit = {}, -) : Described { +public fun MutableMetaProvider.remove(ref: MetaRef<*>) { + remove(ref.name) +} + +/** + * A base class for [Meta] specification that stores references to meta nodes + */ +@DFExperimental +public abstract class MetaSpec : Described { private val refs: MutableList> = mutableListOf() - private fun registerRef(ref: MetaRef<*>) { + protected fun registerRef(ref: MetaRef<*>) { refs.add(ref) } @@ -51,6 +66,8 @@ public class MetaSpec( } } + protected open fun MetaDescriptorBuilder.buildDescriptor(): Unit = Unit + override val descriptor: MetaDescriptor by lazy { MetaDescriptor { refs.forEach { ref -> @@ -58,7 +75,7 @@ public class MetaSpec( node(ref.name, ref.descriptor) } } - configuration() + buildDescriptor() } } } \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ValueSerializer.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ValueSerializer.kt index dc13ef4c..0379187f 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ValueSerializer.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ValueSerializer.kt @@ -8,6 +8,9 @@ import kotlinx.serialization.descriptors.element import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +/** + * A serializer for [Value] + */ public object ValueSerializer : KSerializer { private val listSerializer by lazy { ListSerializer(ValueSerializer) } diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/exoticValues.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/exoticValues.kt index eb39e985..91811390 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/exoticValues.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/exoticValues.kt @@ -21,6 +21,9 @@ public class LazyParsedValue(public val string: String) : Value { override fun hashCode(): Int = string.hashCode() } +/** + * Read this string as lazily parsed value + */ public fun String.lazyParseValue(): LazyParsedValue = LazyParsedValue(this) /** @@ -47,6 +50,9 @@ public class DoubleArrayValue(override val value: DoubleArray) : Value, Iterable override fun iterator(): Iterator = value.iterator() } +/** + * A zero-copy wrapping of this [DoubleArray] in a [Value] + */ public fun DoubleArray.asValue(): Value = if (isEmpty()) Null else DoubleArrayValue(this) public val Value.doubleArray: DoubleArray @@ -75,7 +81,9 @@ public fun MutableMetaProvider.doubleArray( reader = { it?.doubleArray ?: doubleArrayOf(*default) }, ) - +/** + * A [Value] wrapping a [ByteArray] + */ public class ByteArrayValue(override val value: ByteArray) : Value, Iterable { override val type: ValueType get() = ValueType.LIST override val list: List get() = value.map { NumberValue(it) }