All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.wavebeans.execution.distributed.Serializer.kt Maven / Gradle / Ivy

package io.wavebeans.execution.distributed

import io.wavebeans.execution.config.ExecutionConfig.serializationCompression
import io.wavebeans.execution.config.ExecutionConfig.serializationCompressionLevel
import io.wavebeans.execution.config.ExecutionConfig.serializationLogTracing
import kotlinx.serialization.KSerializer
import kotlinx.serialization.protobuf.ProtoBuf
import mu.KotlinLogging
import java.io.ByteArrayOutputStream
import java.util.zip.Deflater
import java.util.zip.Inflater


private val log = KotlinLogging.logger {}

internal fun  T.asByteArray(serializer: KSerializer): ByteArray =
        try {
            val buf = ProtoBuf { this.encodeDefaults = false }.encodeToByteArray(serializer, this)
            val result = if (serializationCompression) {
                val baos = ByteArrayOutputStream()
                try {
                    val dfl = Deflater()
                    dfl.setLevel(serializationCompressionLevel)
                    dfl.setInput(buf)
                    dfl.finish()
                    val tmp = ByteArray(4096)
                    while (!dfl.finished()) {
                        val size = dfl.deflate(tmp)
                        baos.write(tmp, 0, size)
                    }
                } finally {
                    baos.close()
                }
                baos.toByteArray()
            } else {
                buf
            }
            log.trace {
                "[serializer=$serializer,serializationCompression=$serializationCompression," +
                        "serializationCompressionLevel=$serializationCompressionLevel] ${this::class}" +
                        " serialized (${result.size}bytes)" +
                        if (serializationLogTracing)
                            ", as hex:\n" + result.asSequence()
                                    .windowed(40, 40, true)
                                    .joinToString("\n") {
                                        it.joinToString(" ") {
                                            (it.toInt().and(0xFF)).toString(16).padStart(2, '0')
                                        }
                                    }
                        else ""
            }
            result

        } catch (e: Throwable) {
            if (e is OutOfMemoryError) throw e // most likely no resources to handle. Just fail as is
            throw IllegalStateException("Can't serialize with `$serializer` object: $this", e)
        }

internal fun  ByteArray.asObj(serializer: KSerializer): T =
        try {
            val buf = if (serializationCompression) {
                val baos = ByteArrayOutputStream()
                val inflater = Inflater()
                inflater.setInput(this)
                val tmp = ByteArray(4096)
                while (!inflater.finished()) {
                    val size = inflater.inflate(tmp)
                    baos.write(tmp, 0, size)
                }
                baos.toByteArray()
            } else {
                this
            }
            ProtoBuf { encodeDefaults = false }.decodeFromByteArray(serializer, buf)
        } catch (e: Throwable) {
            if (e is OutOfMemoryError) throw e // most likely no resources to handle. Just fail
            throw IllegalStateException("Can't deserialize with `$serializer` the buffer " +
                    "as hex (${this.size}bytes):\n${
                        this.asSequence()
                                .windowed(40, 40, true)
                                .joinToString("\n") {
                                    it.joinToString(" ") {
                                        (it.toInt().and(0xFF)).toString(16).padStart(2, '0')
                                    }
                                }
                    }", e)
        }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy