add type checks for inMemoryCache

This commit is contained in:
Alexander Nozik 2023-03-20 18:34:03 +03:00
parent f3afb5e9fe
commit 29fa30fb51
3 changed files with 12 additions and 6 deletions

View File

@ -4,6 +4,7 @@ import io.ktor.utils.io.core.Input
import io.ktor.utils.io.core.Output import io.ktor.utils.io.core.Output
import io.ktor.utils.io.core.readBytes import io.ktor.utils.io.core.readBytes
import io.ktor.utils.io.core.writeFully import io.ktor.utils.io.core.writeFully
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
@ -26,6 +27,7 @@ import kotlin.reflect.KType
public class JsonIOFormat<T : Any>(override val type: KType) : IOFormat<T> { public class JsonIOFormat<T : Any>(override val type: KType) : IOFormat<T> {
@Suppress("UNCHECKED_CAST")
private val serializer: KSerializer<T> = serializer(type) as KSerializer<T> private val serializer: KSerializer<T> = serializer(type) as KSerializer<T>
override fun readObject(input: Input): T = Json.decodeFromString(serializer, input.readUtf8String()) override fun readObject(input: Input): T = Json.decodeFromString(serializer, input.readUtf8String())
@ -35,8 +37,10 @@ public class JsonIOFormat<T : Any>(override val type: KType) : IOFormat<T> {
} }
} }
@OptIn(ExperimentalSerializationApi::class)
public class ProtobufIOFormat<T : Any>(override val type: KType) : IOFormat<T> { public class ProtobufIOFormat<T : Any>(override val type: KType) : IOFormat<T> {
@Suppress("UNCHECKED_CAST")
private val serializer: KSerializer<T> = serializer(type) as KSerializer<T> private val serializer: KSerializer<T> = serializer(type) as KSerializer<T>
override fun readObject(input: Input): T = ProtoBuf.decodeFromByteArray(serializer, input.readBytes()) override fun readObject(input: Input): T = ProtoBuf.decodeFromByteArray(serializer, input.readBytes())
@ -51,7 +55,6 @@ public class FileWorkspaceCache(public val cacheDirectory: Path) : WorkspaceCach
// private fun <T : Any> TaskData<*>.checkType(taskType: KType): TaskData<T> = this as TaskData<T> // private fun <T : Any> TaskData<*>.checkType(taskType: KType): TaskData<T> = this as TaskData<T>
@OptIn(DFExperimental::class, DFInternal::class) @OptIn(DFExperimental::class, DFInternal::class)
override suspend fun <T : Any> evaluate(result: TaskResult<T>): TaskResult<T> { override suspend fun <T : Any> evaluate(result: TaskResult<T>): TaskResult<T> {
val io = result.workspace.context.request(IOPlugin) val io = result.workspace.context.request(IOPlugin)

View File

@ -3,6 +3,7 @@ package space.kscience.dataforge.workspace
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import kotlin.reflect.KType import kotlin.reflect.KType
import kotlin.reflect.full.isSubtypeOf
private typealias TaskResultId = Pair<Name, Meta> private typealias TaskResultId = Pair<Name, Meta>
@ -12,9 +13,10 @@ public class InMemoryWorkspaceCache : WorkspaceCache {
// never do that at home! // never do that at home!
private val cache = HashMap<TaskResultId, HashMap<Name, TaskData<*>>>() private val cache = HashMap<TaskResultId, HashMap<Name, TaskData<*>>>()
//TODO do actual check @Suppress("UNCHECKED_CAST")
@Suppress("UNUSED_PARAMETER") private fun <T : Any> TaskData<*>.checkType(taskType: KType): TaskData<T> =
private fun <T : Any> TaskData<*>.checkType(taskType: KType): TaskData<T> = this as TaskData<T> if (type.isSubtypeOf(taskType)) this as TaskData<T>
else error("Cached data type mismatch: expected $taskType but got $type")
override suspend fun <T : Any> evaluate(result: TaskResult<T>): TaskResult<T> { override suspend fun <T : Any> evaluate(result: TaskResult<T>): TaskResult<T> {
for (d: TaskData<T> in result) { for (d: TaskData<T> in result) {

View File

@ -22,7 +22,8 @@ class FileWorkspaceCacheTest {
} }
fileCache(Files.createTempDirectory("dataforge-temporary-cache")) fileCache(Files.createTempDirectory("dataforge-temporary-cache"))
task<String> { @Suppress("UNUSED_VARIABLE")
val echo by task<String> {
pipeFrom(dataByType<String>()) { arg, _, _ -> arg } pipeFrom(dataByType<String>()) { arg, _, _ -> arg }
} }
} }