Task and data input validation moved to JVM
This commit is contained in:
parent
030f3ed6fe
commit
8b1d5eb69e
@ -326,7 +326,3 @@ public final class hep/dataforge/provider/ProviderKt {
|
||||
public static final fun top (Lhep/dataforge/provider/Provider;Ljava/lang/String;Lkotlin/reflect/KClass;)Ljava/util/Map;
|
||||
}
|
||||
|
||||
public abstract interface annotation class hep/dataforge/provider/Type : java/lang/annotation/Annotation {
|
||||
public abstract fun id ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ import hep.dataforge.meta.MetaRepr
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.provider.Provider
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.type.Type
|
||||
|
||||
/**
|
||||
* The interface to define a Context plugin. A plugin stores all runtime features of a context.
|
||||
|
@ -1,6 +1,6 @@
|
||||
package hep.dataforge.context
|
||||
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.type.Type
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@Type(PluginFactory.TYPE)
|
||||
|
@ -4,6 +4,7 @@ import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.gather
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.type.Type
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
|
||||
|
@ -26,6 +26,24 @@ public final class hep/dataforge/data/ActionKt {
|
||||
public static final fun then (Lhep/dataforge/data/Action;Lhep/dataforge/data/Action;)Lhep/dataforge/data/Action;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/ComputationData : hep/dataforge/data/ComputationGoal, hep/dataforge/data/Data {
|
||||
public fun <init> (Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)V
|
||||
public synthetic fun <init> (Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun getMeta ()Lhep/dataforge/meta/Meta;
|
||||
public fun getType ()Lkotlin/reflect/KClass;
|
||||
public fun toMeta ()Lhep/dataforge/meta/Meta;
|
||||
}
|
||||
|
||||
public class hep/dataforge/data/ComputationGoal : hep/dataforge/data/Goal {
|
||||
public fun <init> (Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)V
|
||||
public synthetic fun <init> (Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun getBlock ()Lkotlin/jvm/functions/Function2;
|
||||
public fun getDependencies ()Ljava/util/Collection;
|
||||
public final fun getResult ()Lkotlinx/coroutines/Deferred;
|
||||
public fun reset ()V
|
||||
public fun startAsync (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Deferred;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/CoroutineMonitor : kotlin/coroutines/CoroutineContext$Element {
|
||||
public static final field Companion Lhep/dataforge/data/CoroutineMonitor$Companion;
|
||||
public fun <init> ()V
|
||||
@ -79,14 +97,6 @@ public final class hep/dataforge/data/Data$DefaultImpls {
|
||||
public static fun toMeta (Lhep/dataforge/data/Data;)Lhep/dataforge/meta/Meta;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/DataCastKt {
|
||||
public static final fun canCast (Lhep/dataforge/data/DataItem;Lkotlin/reflect/KClass;)Z
|
||||
public static final fun cast (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data;
|
||||
public static final fun cast (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataNode;
|
||||
public static final fun ensureType (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)V
|
||||
public static final fun upcast (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/DataFilter : hep/dataforge/meta/Scheme {
|
||||
public static final field Companion Lhep/dataforge/data/DataFilter$Companion;
|
||||
public fun <init> ()V
|
||||
@ -129,17 +139,22 @@ public final class hep/dataforge/data/DataItem$Node : hep/dataforge/data/DataIte
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/DataJVMKt {
|
||||
public static final fun canCast (Lhep/dataforge/data/DataItem;Lkotlin/reflect/KClass;)Z
|
||||
public static final fun cast (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data;
|
||||
public static final fun cast (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataNode;
|
||||
public static final fun ensureType (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)V
|
||||
public static final fun filterIsInstance (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data;
|
||||
public static final fun filterIsInstance (Lhep/dataforge/data/DataItem;Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataItem;
|
||||
public static final fun filterIsInstance (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataNode;
|
||||
public static final fun get (Lhep/dataforge/data/Data;)Ljava/lang/Object;
|
||||
public static final fun upcast (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/DataKt {
|
||||
public static final fun map (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/Data;
|
||||
public static synthetic fun map$default (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/Data;
|
||||
public static final fun reduce (Ljava/util/Map;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/DynamicData;
|
||||
public static synthetic fun reduce$default (Ljava/util/Map;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/DynamicData;
|
||||
public static final fun reduce (Ljava/util/Map;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/ComputationData;
|
||||
public static synthetic fun reduce$default (Ljava/util/Map;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/ComputationData;
|
||||
}
|
||||
|
||||
public abstract interface class hep/dataforge/data/DataNode : hep/dataforge/meta/MetaRepr {
|
||||
@ -164,27 +179,16 @@ public final class hep/dataforge/data/DataNode$DefaultImpls {
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/DataNodeKt {
|
||||
public static final fun asSequence (Lhep/dataforge/data/DataNode;)Lkotlin/sequences/Sequence;
|
||||
public static final fun builder (Lhep/dataforge/data/DataNode;)Lhep/dataforge/data/DataTreeBuilder;
|
||||
public static final fun dataSequence (Lhep/dataforge/data/DataNode;)Lkotlin/sequences/Sequence;
|
||||
public static final fun datum (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Lhep/dataforge/data/Data;)V
|
||||
public static final fun datum (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Lhep/dataforge/data/Data;)V
|
||||
public static final fun filter (Lhep/dataforge/data/DataNode;Lkotlin/jvm/functions/Function2;)Lhep/dataforge/data/DataNode;
|
||||
public static final fun first (Lhep/dataforge/data/DataNode;)Lhep/dataforge/data/Data;
|
||||
public static final fun get (Lhep/dataforge/data/DataNode;Lhep/dataforge/names/Name;)Lhep/dataforge/data/DataItem;
|
||||
public static final fun get (Lhep/dataforge/data/DataNode;Ljava/lang/String;)Lhep/dataforge/data/DataItem;
|
||||
public static final fun getData (Lhep/dataforge/data/DataItem;)Lhep/dataforge/data/Data;
|
||||
public static final fun getNode (Lhep/dataforge/data/DataItem;)Lhep/dataforge/data/DataNode;
|
||||
public static final fun itemSequence (Lhep/dataforge/data/DataNode;)Lkotlin/sequences/Sequence;
|
||||
public static final fun iterator (Lhep/dataforge/data/DataNode;)Ljava/util/Iterator;
|
||||
public static final fun join (Lhep/dataforge/data/DataNode;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static final fun node (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Lhep/dataforge/data/DataNode;)V
|
||||
public static final fun node (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Lhep/dataforge/data/DataNode;)V
|
||||
public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lhep/dataforge/meta/Meta;)V
|
||||
public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
|
||||
public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
|
||||
public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)V
|
||||
public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/DataTree : hep/dataforge/data/DataNode {
|
||||
@ -214,6 +218,20 @@ public final class hep/dataforge/data/DataTreeBuilder {
|
||||
public final fun update (Lhep/dataforge/data/DataNode;)V
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/DataTreeBuilderKt {
|
||||
public static final fun builder (Lhep/dataforge/data/DataNode;)Lhep/dataforge/data/DataTreeBuilder;
|
||||
public static final fun datum (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Lhep/dataforge/data/Data;)V
|
||||
public static final fun datum (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Lhep/dataforge/data/Data;)V
|
||||
public static final fun node (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Lhep/dataforge/data/DataNode;)V
|
||||
public static final fun node (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Lhep/dataforge/data/DataNode;)V
|
||||
public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lhep/dataforge/meta/Meta;)V
|
||||
public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
|
||||
public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
|
||||
public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)V
|
||||
public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/Dependencies : kotlin/coroutines/CoroutineContext$Element {
|
||||
public static final field Companion Lhep/dataforge/data/Dependencies$Companion;
|
||||
public fun <init> (Ljava/util/Collection;)V
|
||||
@ -228,24 +246,6 @@ public final class hep/dataforge/data/Dependencies : kotlin/coroutines/Coroutine
|
||||
public final class hep/dataforge/data/Dependencies$Companion : kotlin/coroutines/CoroutineContext$Key {
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/DynamicData : hep/dataforge/data/DynamicGoal, hep/dataforge/data/Data {
|
||||
public fun <init> (Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)V
|
||||
public synthetic fun <init> (Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun getMeta ()Lhep/dataforge/meta/Meta;
|
||||
public fun getType ()Lkotlin/reflect/KClass;
|
||||
public fun toMeta ()Lhep/dataforge/meta/Meta;
|
||||
}
|
||||
|
||||
public class hep/dataforge/data/DynamicGoal : hep/dataforge/data/Goal {
|
||||
public fun <init> (Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)V
|
||||
public synthetic fun <init> (Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun getBlock ()Lkotlin/jvm/functions/Function2;
|
||||
public fun getDependencies ()Ljava/util/Collection;
|
||||
public final fun getResult ()Lkotlinx/coroutines/Deferred;
|
||||
public fun reset ()V
|
||||
public fun startAsync (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Deferred;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/FragmentRule {
|
||||
public field result Lkotlin/jvm/functions/Function2;
|
||||
public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaBuilder;)V
|
||||
@ -302,8 +302,7 @@ public final class hep/dataforge/data/JoinGroup {
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/MapAction : hep/dataforge/data/Action {
|
||||
public fun <init> (Lkotlin/reflect/KClass;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun getInputType ()Lkotlin/reflect/KClass;
|
||||
public fun <init> (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun getOutputType ()Lkotlin/reflect/KClass;
|
||||
public fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode;
|
||||
public fun isTerminal ()Z
|
||||
@ -335,8 +334,7 @@ public final class hep/dataforge/data/NamedData : hep/dataforge/data/Data {
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/ReduceAction : hep/dataforge/data/Action {
|
||||
public fun <init> (Lkotlin/reflect/KClass;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun getInputType ()Lkotlin/reflect/KClass;
|
||||
public fun <init> (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun getOutputType ()Lkotlin/reflect/KClass;
|
||||
public fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode;
|
||||
public fun isTerminal ()Z
|
||||
@ -357,8 +355,7 @@ public final class hep/dataforge/data/ReduceGroupBuilder {
|
||||
}
|
||||
|
||||
public final class hep/dataforge/data/SplitAction : hep/dataforge/data/Action {
|
||||
public fun <init> (Lkotlin/reflect/KClass;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun getInputType ()Lkotlin/reflect/KClass;
|
||||
public fun <init> (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun getOutputType ()Lkotlin/reflect/KClass;
|
||||
public fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode;
|
||||
public fun isTerminal ()Z
|
||||
|
@ -3,6 +3,7 @@ package hep.dataforge.data
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaRepr
|
||||
import hep.dataforge.meta.isEmpty
|
||||
import hep.dataforge.type.Type
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
@ -11,7 +12,8 @@ import kotlin.reflect.KClass
|
||||
/**
|
||||
* A data element characterized by its meta
|
||||
*/
|
||||
public interface Data<out T : Any> : Goal<T>, MetaRepr{
|
||||
@Type(Data.TYPE)
|
||||
public interface Data<out T : Any> : Goal<T>, MetaRepr {
|
||||
/**
|
||||
* Type marker for the data. The type is known before the calculation takes place so it could be checked.
|
||||
*/
|
||||
@ -22,9 +24,9 @@ public interface Data<out T : Any> : Goal<T>, MetaRepr{
|
||||
*/
|
||||
public val meta: Meta
|
||||
|
||||
override fun toMeta(): Meta = Meta {
|
||||
"type" put (type.simpleName?:"undefined")
|
||||
if(!meta.isEmpty()) {
|
||||
override fun toMeta(): Meta = Meta {
|
||||
"type" put (type.simpleName ?: "undefined")
|
||||
if (!meta.isEmpty()) {
|
||||
"meta" put meta
|
||||
}
|
||||
}
|
||||
@ -37,14 +39,14 @@ public interface Data<out T : Any> : Goal<T>, MetaRepr{
|
||||
meta: Meta = Meta.EMPTY,
|
||||
context: CoroutineContext = EmptyCoroutineContext,
|
||||
dependencies: Collection<Data<*>> = emptyList(),
|
||||
block: suspend CoroutineScope.() -> T
|
||||
): Data<T> = DynamicData(type, meta, context, dependencies, block)
|
||||
block: suspend CoroutineScope.() -> T,
|
||||
): Data<T> = ComputationData(type, meta, context, dependencies, block)
|
||||
|
||||
public inline operator fun <reified T : Any> invoke(
|
||||
meta: Meta = Meta.EMPTY,
|
||||
context: CoroutineContext = EmptyCoroutineContext,
|
||||
dependencies: Collection<Data<*>> = emptyList(),
|
||||
noinline block: suspend CoroutineScope.() -> T
|
||||
noinline block: suspend CoroutineScope.() -> T,
|
||||
): Data<T> = invoke(T::class, meta, context, dependencies, block)
|
||||
|
||||
public operator fun <T : Any> invoke(
|
||||
@ -53,7 +55,7 @@ public interface Data<out T : Any> : Goal<T>, MetaRepr{
|
||||
meta: Meta = Meta.EMPTY,
|
||||
context: CoroutineContext = EmptyCoroutineContext,
|
||||
dependencies: Collection<Data<*>> = emptyList(),
|
||||
block: suspend CoroutineScope.() -> T
|
||||
block: suspend CoroutineScope.() -> T,
|
||||
): Data<T> = NamedData(name, invoke(type, meta, context, dependencies, block))
|
||||
|
||||
public inline operator fun <reified T : Any> invoke(
|
||||
@ -61,7 +63,7 @@ public interface Data<out T : Any> : Goal<T>, MetaRepr{
|
||||
meta: Meta = Meta.EMPTY,
|
||||
context: CoroutineContext = EmptyCoroutineContext,
|
||||
dependencies: Collection<Data<*>> = emptyList(),
|
||||
noinline block: suspend CoroutineScope.() -> T
|
||||
noinline block: suspend CoroutineScope.() -> T,
|
||||
): Data<T> =
|
||||
invoke(name, T::class, meta, context, dependencies, block)
|
||||
|
||||
@ -71,17 +73,17 @@ public interface Data<out T : Any> : Goal<T>, MetaRepr{
|
||||
}
|
||||
|
||||
|
||||
public class DynamicData<T : Any>(
|
||||
public class ComputationData<T : Any>(
|
||||
override val type: KClass<out T>,
|
||||
override val meta: Meta = Meta.EMPTY,
|
||||
context: CoroutineContext = EmptyCoroutineContext,
|
||||
dependencies: Collection<Data<*>> = emptyList(),
|
||||
block: suspend CoroutineScope.() -> T
|
||||
) : Data<T>, DynamicGoal<T>(context, dependencies, block)
|
||||
block: suspend CoroutineScope.() -> T,
|
||||
) : Data<T>, ComputationGoal<T>(context, dependencies, block)
|
||||
|
||||
public class StaticData<T : Any>(
|
||||
value: T,
|
||||
override val meta: Meta = Meta.EMPTY
|
||||
override val meta: Meta = Meta.EMPTY,
|
||||
) : Data<T>, StaticGoal<T>(value) {
|
||||
override val type: KClass<out T> get() = value::class
|
||||
}
|
||||
@ -92,8 +94,8 @@ public fun <T : Any, R : Any> Data<T>.map(
|
||||
outputType: KClass<out R>,
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
meta: Meta = this.meta,
|
||||
block: suspend CoroutineScope.(T) -> R
|
||||
): Data<R> = DynamicData(outputType, meta, coroutineContext, listOf(this)) {
|
||||
block: suspend CoroutineScope.(T) -> R,
|
||||
): Data<R> = ComputationData(outputType, meta, coroutineContext, listOf(this)) {
|
||||
block(await())
|
||||
}
|
||||
|
||||
@ -104,8 +106,8 @@ public fun <T : Any, R : Any> Data<T>.map(
|
||||
public inline fun <T : Any, reified R : Any> Data<T>.map(
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
meta: Meta = this.meta,
|
||||
noinline block: suspend CoroutineScope.(T) -> R
|
||||
): Data<R> = DynamicData(R::class, meta, coroutineContext, listOf(this)) {
|
||||
noinline block: suspend CoroutineScope.(T) -> R,
|
||||
): Data<R> = ComputationData(R::class, meta, coroutineContext, listOf(this)) {
|
||||
block(await())
|
||||
}
|
||||
|
||||
@ -115,8 +117,8 @@ public inline fun <T : Any, reified R : Any> Data<T>.map(
|
||||
public inline fun <T : Any, reified R : Any> Collection<Data<T>>.reduce(
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
meta: Meta,
|
||||
noinline block: suspend CoroutineScope.(Collection<T>) -> R
|
||||
): Data<R> = DynamicData(
|
||||
noinline block: suspend CoroutineScope.(Collection<T>) -> R,
|
||||
): Data<R> = ComputationData(
|
||||
R::class,
|
||||
meta,
|
||||
coroutineContext,
|
||||
@ -129,8 +131,8 @@ public fun <K, T : Any, R : Any> Map<K, Data<T>>.reduce(
|
||||
outputType: KClass<out R>,
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
meta: Meta,
|
||||
block: suspend CoroutineScope.(Map<K, T>) -> R
|
||||
): DynamicData<R> = DynamicData(
|
||||
block: suspend CoroutineScope.(Map<K, T>) -> R,
|
||||
): ComputationData<R> = ComputationData(
|
||||
outputType,
|
||||
meta,
|
||||
coroutineContext,
|
||||
@ -149,8 +151,8 @@ public fun <K, T : Any, R : Any> Map<K, Data<T>>.reduce(
|
||||
public inline fun <K, T : Any, reified R : Any> Map<K, Data<T>>.reduce(
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
meta: Meta,
|
||||
noinline block: suspend CoroutineScope.(Map<K, T>) -> R
|
||||
): DynamicData<R> = DynamicData(
|
||||
noinline block: suspend CoroutineScope.(Map<K, T>) -> R,
|
||||
): ComputationData<R> = ComputationData(
|
||||
R::class,
|
||||
meta,
|
||||
coroutineContext,
|
||||
|
@ -2,13 +2,13 @@ package hep.dataforge.data
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.type.Type
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.set
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public sealed class DataItem<out T : Any> : MetaRepr {
|
||||
@ -36,6 +36,7 @@ public sealed class DataItem<out T : Any> : MetaRepr {
|
||||
/**
|
||||
* A tree-like data structure grouped into the node. All data inside the node must inherit its type
|
||||
*/
|
||||
@Type(DataNode.TYPE)
|
||||
public interface DataNode<out T : Any> : MetaRepr {
|
||||
|
||||
/**
|
||||
@ -49,6 +50,7 @@ public interface DataNode<out T : Any> : MetaRepr {
|
||||
|
||||
override fun toMeta(): Meta = Meta {
|
||||
"type" put (type.simpleName ?: "undefined")
|
||||
"meta" put meta
|
||||
"items" put {
|
||||
this@DataNode.items.forEach {
|
||||
it.key.toString() put it.value.toMeta()
|
||||
@ -64,7 +66,7 @@ public interface DataNode<out T : Any> : MetaRepr {
|
||||
items.values.forEach {
|
||||
when (it) {
|
||||
is DataItem.Node<*> -> it.node.run { startAll() }
|
||||
is DataItem.Leaf<*> -> it.data.run { startAsync() }
|
||||
is DataItem.Leaf<*> -> it.data.run { startAsync(this@launch) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,11 +100,11 @@ public operator fun <T : Any> DataNode<T>.get(name: String): DataItem<T>? = get(
|
||||
/**
|
||||
* Sequence of all children including nodes
|
||||
*/
|
||||
public fun <T : Any> DataNode<T>.asSequence(): Sequence<Pair<Name, DataItem<T>>> = sequence {
|
||||
public fun <T : Any> DataNode<T>.itemSequence(): Sequence<Pair<Name, DataItem<T>>> = sequence {
|
||||
items.forEach { (head, item) ->
|
||||
yield(head.asName() to item)
|
||||
if (item is DataItem.Node) {
|
||||
val subSequence = item.node.asSequence()
|
||||
val subSequence = item.node.itemSequence()
|
||||
.map { (name, data) -> (head.asName() + name) to data }
|
||||
yieldAll(subSequence)
|
||||
}
|
||||
@ -125,166 +127,6 @@ public fun <T : Any> DataNode<T>.dataSequence(): Sequence<Pair<Name, Data<T>>> =
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun <T : Any> DataNode<T>.iterator(): Iterator<Pair<Name, DataItem<T>>> = asSequence().iterator()
|
||||
|
||||
public class DataTree<out T : Any> internal constructor(
|
||||
override val type: KClass<out T>,
|
||||
override val items: Map<NameToken, DataItem<T>>,
|
||||
override val meta: Meta
|
||||
) : DataNode<T>
|
||||
|
||||
private sealed class DataTreeBuilderItem<out T : Any> {
|
||||
class Node<T : Any>(val tree: DataTreeBuilder<T>) : DataTreeBuilderItem<T>()
|
||||
class Leaf<T : Any>(val value: Data<T>) : DataTreeBuilderItem<T>()
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for a DataTree.
|
||||
*/
|
||||
@DFBuilder
|
||||
public class DataTreeBuilder<T : Any>(public val type: KClass<out T>) {
|
||||
private val map = HashMap<NameToken, DataTreeBuilderItem<T>>()
|
||||
|
||||
private var meta = MetaBuilder()
|
||||
|
||||
public operator fun set(token: NameToken, node: DataTreeBuilder<out T>) {
|
||||
if (map.containsKey(token)) error("Tree entry with name $token is not empty")
|
||||
map[token] = DataTreeBuilderItem.Node(node)
|
||||
}
|
||||
|
||||
public operator fun set(token: NameToken, data: Data<T>) {
|
||||
if (map.containsKey(token)) error("Tree entry with name $token is not empty")
|
||||
map[token] = DataTreeBuilderItem.Leaf(data)
|
||||
}
|
||||
|
||||
private fun buildNode(token: NameToken): DataTreeBuilder<T> {
|
||||
return if (!map.containsKey(token)) {
|
||||
DataTreeBuilder(type).also { map[token] = DataTreeBuilderItem.Node(it) }
|
||||
} else {
|
||||
(map[token] as? DataTreeBuilderItem.Node<T> ?: error("The node with name $token is occupied by leaf")).tree
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildNode(name: Name): DataTreeBuilder<T> {
|
||||
return when (name.length) {
|
||||
0 -> this
|
||||
1 -> buildNode(name.firstOrNull()!!)
|
||||
else -> buildNode(name.firstOrNull()!!).buildNode(name.cutFirst())
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun set(name: Name, data: Data<T>) {
|
||||
when (name.length) {
|
||||
0 -> error("Can't add data with empty name")
|
||||
1 -> set(name.firstOrNull()!!, data)
|
||||
2 -> buildNode(name.cutLast())[name.lastOrNull()!!] = data
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun set(name: Name, node: DataTreeBuilder<out T>) {
|
||||
when (name.length) {
|
||||
0 -> error("Can't add data with empty name")
|
||||
1 -> set(name.firstOrNull()!!, node)
|
||||
2 -> buildNode(name.cutLast())[name.lastOrNull()!!] = node
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun set(name: Name, node: DataNode<T>): Unit = set(name, node.builder())
|
||||
|
||||
public operator fun set(name: Name, item: DataItem<T>): Unit = when (item) {
|
||||
is DataItem.Node<T> -> set(name, item.node.builder())
|
||||
is DataItem.Leaf<T> -> set(name, item.data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data to node
|
||||
*/
|
||||
public infix fun String.put(data: Data<T>): Unit = set(toName(), data)
|
||||
|
||||
/**
|
||||
* Append node
|
||||
*/
|
||||
public infix fun String.put(node: DataNode<T>): Unit = set(toName(), node)
|
||||
|
||||
public infix fun String.put(item: DataItem<T>): Unit = set(toName(), item)
|
||||
|
||||
/**
|
||||
* Build and append node
|
||||
*/
|
||||
public infix fun String.put(block: DataTreeBuilder<T>.() -> Unit): Unit = set(toName(), DataTreeBuilder(type).apply(block))
|
||||
|
||||
|
||||
/**
|
||||
* Update data with given node data and meta with node meta.
|
||||
*/
|
||||
public fun update(node: DataNode<T>) {
|
||||
node.dataSequence().forEach {
|
||||
//TODO check if the place is occupied
|
||||
this[it.first] = it.second
|
||||
}
|
||||
meta.update(node.meta)
|
||||
}
|
||||
|
||||
public fun meta(block: MetaBuilder.() -> Unit): MetaBuilder = meta.apply(block)
|
||||
|
||||
public fun meta(meta: Meta) {
|
||||
this.meta = meta.builder()
|
||||
}
|
||||
|
||||
public fun build(): DataTree<T> {
|
||||
val resMap = map.mapValues { (_, value) ->
|
||||
when (value) {
|
||||
is DataTreeBuilderItem.Leaf -> DataItem.Leaf(value.value)
|
||||
is DataTreeBuilderItem.Node -> DataItem.Node(value.tree.build())
|
||||
}
|
||||
}
|
||||
return DataTree(type, resMap, meta.seal())
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.datum(name: Name, data: Data<T>) {
|
||||
this[name] = data
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.datum(name: String, data: Data<T>) {
|
||||
this[name.toName()] = data
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.static(name: Name, data: T, meta: Meta = Meta.EMPTY) {
|
||||
this[name] = Data.static(data, meta)
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.static(name: Name, data: T, block: MetaBuilder.() -> Unit = {}) {
|
||||
this[name] = Data.static(data, Meta(block))
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.static(name: String, data: T, block: MetaBuilder.() -> Unit = {}) {
|
||||
this[name.toName()] = Data.static(data, Meta(block))
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.node(name: Name, node: DataNode<T>) {
|
||||
this[name] = node
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.node(name: String, node: DataNode<T>) {
|
||||
this[name.toName()] = node
|
||||
}
|
||||
|
||||
public inline fun <reified T : Any> DataTreeBuilder<T>.node(name: Name, noinline block: DataTreeBuilder<T>.() -> Unit) {
|
||||
this[name] = DataNode(T::class, block)
|
||||
}
|
||||
|
||||
public inline fun <reified T : Any> DataTreeBuilder<T>.node(name: String, noinline block: DataTreeBuilder<T>.() -> Unit) {
|
||||
this[name.toName()] = DataNode(T::class, block)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a mutable builder from this node. Node content is not changed
|
||||
*/
|
||||
public fun <T : Any> DataNode<T>.builder(): DataTreeBuilder<T> = DataTreeBuilder(type).apply {
|
||||
dataSequence().forEach { (name, data) -> this[name] = data }
|
||||
}
|
||||
|
||||
public fun <T : Any> DataNode<T>.filter(predicate: (Name, Data<T>) -> Boolean): DataNode<T> = DataNode.invoke(type) {
|
||||
dataSequence().forEach { (name, data) ->
|
||||
if (predicate(name, data)) {
|
||||
@ -293,4 +135,8 @@ public fun <T : Any> DataNode<T>.filter(predicate: (Name, Data<T>) -> Boolean):
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T : Any> DataNode<T>.first(): Data<T>? = dataSequence().first().second
|
||||
public fun <T : Any> DataNode<T>.first(): Data<T>? = dataSequence().firstOrNull()?.second
|
||||
|
||||
|
||||
public operator fun <T : Any> DataNode<T>.iterator(): Iterator<Pair<Name, DataItem<T>>> = itemSequence().iterator()
|
||||
|
||||
|
@ -0,0 +1,164 @@
|
||||
package hep.dataforge.data
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.*
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public class DataTree<out T : Any> internal constructor(
|
||||
override val type: KClass<out T>,
|
||||
override val items: Map<NameToken, DataItem<T>>,
|
||||
override val meta: Meta
|
||||
) : DataNode<T>
|
||||
|
||||
private sealed class DataTreeBuilderItem<out T : Any> {
|
||||
class Node<T : Any>(val tree: DataTreeBuilder<T>) : DataTreeBuilderItem<T>()
|
||||
class Leaf<T : Any>(val value: Data<T>) : DataTreeBuilderItem<T>()
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for a DataTree.
|
||||
*/
|
||||
@DFBuilder
|
||||
public class DataTreeBuilder<T : Any>(public val type: KClass<out T>) {
|
||||
private val map = HashMap<NameToken, DataTreeBuilderItem<T>>()
|
||||
|
||||
private var meta = MetaBuilder()
|
||||
|
||||
public operator fun set(token: NameToken, node: DataTreeBuilder<out T>) {
|
||||
if (map.containsKey(token)) error("Tree entry with name $token is not empty")
|
||||
map[token] = DataTreeBuilderItem.Node(node)
|
||||
}
|
||||
|
||||
public operator fun set(token: NameToken, data: Data<T>) {
|
||||
if (map.containsKey(token)) error("Tree entry with name $token is not empty")
|
||||
map[token] = DataTreeBuilderItem.Leaf(data)
|
||||
}
|
||||
|
||||
private fun buildNode(token: NameToken): DataTreeBuilder<T> {
|
||||
return if (!map.containsKey(token)) {
|
||||
DataTreeBuilder(type).also { map[token] = DataTreeBuilderItem.Node(it) }
|
||||
} else {
|
||||
(map[token] as? DataTreeBuilderItem.Node<T> ?: error("The node with name $token is occupied by leaf")).tree
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildNode(name: Name): DataTreeBuilder<T> {
|
||||
return when (name.length) {
|
||||
0 -> this
|
||||
1 -> buildNode(name.firstOrNull()!!)
|
||||
else -> buildNode(name.firstOrNull()!!).buildNode(name.cutFirst())
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun set(name: Name, data: Data<T>) {
|
||||
when (name.length) {
|
||||
0 -> error("Can't add data with empty name")
|
||||
1 -> set(name.firstOrNull()!!, data)
|
||||
2 -> buildNode(name.cutLast())[name.lastOrNull()!!] = data
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun set(name: Name, node: DataTreeBuilder<out T>) {
|
||||
when (name.length) {
|
||||
0 -> error("Can't add data with empty name")
|
||||
1 -> set(name.firstOrNull()!!, node)
|
||||
2 -> buildNode(name.cutLast())[name.lastOrNull()!!] = node
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun set(name: Name, node: DataNode<T>): Unit = set(name, node.builder())
|
||||
|
||||
public operator fun set(name: Name, item: DataItem<T>): Unit = when (item) {
|
||||
is DataItem.Node<T> -> set(name, item.node.builder())
|
||||
is DataItem.Leaf<T> -> set(name, item.data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data to node
|
||||
*/
|
||||
public infix fun String.put(data: Data<T>): Unit = set(toName(), data)
|
||||
|
||||
/**
|
||||
* Append node
|
||||
*/
|
||||
public infix fun String.put(node: DataNode<T>): Unit = set(toName(), node)
|
||||
|
||||
public infix fun String.put(item: DataItem<T>): Unit = set(toName(), item)
|
||||
|
||||
/**
|
||||
* Build and append node
|
||||
*/
|
||||
public infix fun String.put(block: DataTreeBuilder<T>.() -> Unit): Unit = set(toName(), DataTreeBuilder(type).apply(block))
|
||||
|
||||
|
||||
/**
|
||||
* Update data with given node data and meta with node meta.
|
||||
*/
|
||||
public fun update(node: DataNode<T>) {
|
||||
node.dataSequence().forEach {
|
||||
//TODO check if the place is occupied
|
||||
this[it.first] = it.second
|
||||
}
|
||||
meta.update(node.meta)
|
||||
}
|
||||
|
||||
public fun meta(block: MetaBuilder.() -> Unit): MetaBuilder = meta.apply(block)
|
||||
|
||||
public fun meta(meta: Meta) {
|
||||
this.meta = meta.builder()
|
||||
}
|
||||
|
||||
public fun build(): DataTree<T> {
|
||||
val resMap = map.mapValues { (_, value) ->
|
||||
when (value) {
|
||||
is DataTreeBuilderItem.Leaf -> DataItem.Leaf(value.value)
|
||||
is DataTreeBuilderItem.Node -> DataItem.Node(value.tree.build())
|
||||
}
|
||||
}
|
||||
return DataTree(type, resMap, meta.seal())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.datum(name: Name, data: Data<T>) {
|
||||
this[name] = data
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.datum(name: String, data: Data<T>) {
|
||||
this[name.toName()] = data
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.static(name: Name, data: T, meta: Meta = Meta.EMPTY) {
|
||||
this[name] = Data.static(data, meta)
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.static(name: Name, data: T, block: MetaBuilder.() -> Unit = {}) {
|
||||
this[name] = Data.static(data, Meta(block))
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.static(name: String, data: T, block: MetaBuilder.() -> Unit = {}) {
|
||||
this[name.toName()] = Data.static(data, Meta(block))
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.node(name: Name, node: DataNode<T>) {
|
||||
this[name] = node
|
||||
}
|
||||
|
||||
public fun <T : Any> DataTreeBuilder<T>.node(name: String, node: DataNode<T>) {
|
||||
this[name.toName()] = node
|
||||
}
|
||||
|
||||
public inline fun <reified T : Any> DataTreeBuilder<T>.node(name: Name, noinline block: DataTreeBuilder<T>.() -> Unit) {
|
||||
this[name] = DataNode(T::class, block)
|
||||
}
|
||||
|
||||
public inline fun <reified T : Any> DataTreeBuilder<T>.node(name: String, noinline block: DataTreeBuilder<T>.() -> Unit) {
|
||||
this[name.toName()] = DataNode(T::class, block)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a mutable builder from this node. Node content is not changed
|
||||
*/
|
||||
public fun <T : Any> DataNode<T>.builder(): DataTreeBuilder<T> = DataTreeBuilder(type).apply {
|
||||
dataSequence().forEach { (name, data) -> this[name] = data }
|
||||
}
|
@ -5,8 +5,12 @@ import kotlinx.coroutines.*
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
||||
/**
|
||||
* Lazy computation result with its dependencies to allowing to stat computing dependencies ahead of time
|
||||
*/
|
||||
public interface Goal<out T> {
|
||||
public val dependencies: Collection<Goal<*>>
|
||||
|
||||
/**
|
||||
* Returns current running coroutine if the goal is started
|
||||
*/
|
||||
@ -16,7 +20,7 @@ public interface Goal<out T> {
|
||||
* Get ongoing computation or start a new one.
|
||||
* Does not guarantee thread safety. In case of multi-thread access, could create orphan computations.
|
||||
*/
|
||||
public fun CoroutineScope.startAsync(): Deferred<T>
|
||||
public fun startAsync(coroutineScope: CoroutineScope): Deferred<T>
|
||||
|
||||
/**
|
||||
* Reset the computation
|
||||
@ -26,7 +30,7 @@ public interface Goal<out T> {
|
||||
public companion object
|
||||
}
|
||||
|
||||
public suspend fun <T> Goal<T>.await(): T = coroutineScope { startAsync().await() }
|
||||
public suspend fun <T> Goal<T>.await(): T = coroutineScope { startAsync(this).await() }
|
||||
|
||||
public val Goal<*>.isComplete: Boolean get() = result?.isCompleted ?: false
|
||||
|
||||
@ -34,17 +38,17 @@ public open class StaticGoal<T>(public val value: T) : Goal<T> {
|
||||
override val dependencies: Collection<Goal<*>> get() = emptyList()
|
||||
override val result: Deferred<T> = CompletableDeferred(value)
|
||||
|
||||
override fun CoroutineScope.startAsync(): Deferred<T> = result
|
||||
override fun startAsync(coroutineScope: CoroutineScope): Deferred<T> = result
|
||||
|
||||
override fun reset() {
|
||||
//doNothing
|
||||
}
|
||||
}
|
||||
|
||||
public open class DynamicGoal<T>(
|
||||
public open class ComputationGoal<T>(
|
||||
private val coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
override val dependencies: Collection<Goal<*>> = emptyList(),
|
||||
public val block: suspend CoroutineScope.() -> T
|
||||
public val block: suspend CoroutineScope.() -> T,
|
||||
) : Goal<T> {
|
||||
|
||||
final override var result: Deferred<T>? = null
|
||||
@ -55,19 +59,20 @@ public open class DynamicGoal<T>(
|
||||
* Does not guarantee thread safety. In case of multi-thread access, could create orphan computations.
|
||||
*/
|
||||
@DFExperimental
|
||||
override fun CoroutineScope.startAsync(): Deferred<T> {
|
||||
val startedDependencies = this@DynamicGoal.dependencies.map { goal ->
|
||||
goal.run { startAsync() }
|
||||
override fun startAsync(coroutineScope: CoroutineScope): Deferred<T> {
|
||||
val startedDependencies = this.dependencies.map { goal ->
|
||||
goal.run { startAsync(coroutineScope) }
|
||||
}
|
||||
return result
|
||||
?: async(this@DynamicGoal.coroutineContext + CoroutineMonitor() + Dependencies(startedDependencies)) {
|
||||
startedDependencies.forEach { deferred ->
|
||||
deferred.invokeOnCompletion { error ->
|
||||
if (error != null) cancel(CancellationException("Dependency $deferred failed with error: ${error.message}"))
|
||||
}
|
||||
return result ?: coroutineScope.async(
|
||||
this.coroutineContext + CoroutineMonitor() + Dependencies(startedDependencies)
|
||||
) {
|
||||
startedDependencies.forEach { deferred ->
|
||||
deferred.invokeOnCompletion { error ->
|
||||
if (error != null) this.cancel(CancellationException("Dependency $deferred failed with error: ${error.message}"))
|
||||
}
|
||||
block()
|
||||
}.also { result = it }
|
||||
}
|
||||
block()
|
||||
}.also { result = it }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,8 +89,8 @@ public open class DynamicGoal<T>(
|
||||
*/
|
||||
public fun <T, R> Goal<T>.map(
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
block: suspend CoroutineScope.(T) -> R
|
||||
): Goal<R> = DynamicGoal(coroutineContext, listOf(this)) {
|
||||
block: suspend CoroutineScope.(T) -> R,
|
||||
): Goal<R> = ComputationGoal(coroutineContext, listOf(this)) {
|
||||
block(await())
|
||||
}
|
||||
|
||||
@ -94,8 +99,8 @@ public fun <T, R> Goal<T>.map(
|
||||
*/
|
||||
public fun <T, R> Collection<Goal<T>>.reduce(
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
block: suspend CoroutineScope.(Collection<T>) -> R
|
||||
): Goal<R> = DynamicGoal(coroutineContext, this) {
|
||||
block: suspend CoroutineScope.(Collection<T>) -> R,
|
||||
): Goal<R> = ComputationGoal(coroutineContext, this) {
|
||||
block(map { run { it.await() } })
|
||||
}
|
||||
|
||||
@ -107,8 +112,8 @@ public fun <T, R> Collection<Goal<T>>.reduce(
|
||||
*/
|
||||
public fun <K, T, R> Map<K, Goal<T>>.reduce(
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
block: suspend CoroutineScope.(Map<K, T>) -> R
|
||||
): Goal<R> = DynamicGoal(coroutineContext, this.values) {
|
||||
block: suspend CoroutineScope.(Map<K, T>) -> R,
|
||||
): Goal<R> = ComputationGoal(coroutineContext, this.values) {
|
||||
block(mapValues { it.value.await() })
|
||||
}
|
||||
|
||||
|
@ -30,46 +30,41 @@ public class MapActionBuilder<T, R>(public var name: Name, public var meta: Meta
|
||||
|
||||
|
||||
public class MapAction<T : Any, out R : Any>(
|
||||
public val inputType: KClass<T>,
|
||||
public val outputType: KClass<out R>,
|
||||
private val block: MapActionBuilder<T, R>.() -> Unit
|
||||
) : Action<T, R> {
|
||||
|
||||
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> {
|
||||
node.ensureType(inputType)
|
||||
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> = DataNode(outputType) {
|
||||
node.dataSequence().forEach { (name, data) ->
|
||||
/*
|
||||
* Creating a new environment for action using **old** name, old meta and task meta
|
||||
*/
|
||||
val env = ActionEnv(name, data.meta, meta)
|
||||
|
||||
return DataNode.invoke(outputType) {
|
||||
node.dataSequence().forEach { (name, data) ->
|
||||
/*
|
||||
* Creating a new environment for action using **old** name, old meta and task meta
|
||||
*/
|
||||
val env = ActionEnv(name, data.meta, meta)
|
||||
//applying transformation from builder
|
||||
val builder = MapActionBuilder<T, R>(
|
||||
name,
|
||||
data.meta.builder(), // using data meta
|
||||
meta
|
||||
).apply(block)
|
||||
|
||||
//applying transformation from builder
|
||||
val builder = MapActionBuilder<T, R>(
|
||||
name,
|
||||
data.meta.builder(), // using data meta
|
||||
meta
|
||||
).apply(block)
|
||||
//getting new name
|
||||
val newName = builder.name
|
||||
|
||||
//getting new name
|
||||
val newName = builder.name
|
||||
//getting new meta
|
||||
val newMeta = builder.meta.seal()
|
||||
|
||||
//getting new meta
|
||||
val newMeta = builder.meta.seal()
|
||||
|
||||
val newData = data.map(outputType, meta = newMeta) { builder.result(env, it) }
|
||||
//setting the data node
|
||||
this[newName] = newData
|
||||
}
|
||||
val newData = data.map(outputType, meta = newMeta) { builder.result(env, it) }
|
||||
//setting the data node
|
||||
this[newName] = newData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public inline fun <reified T : Any, reified R : Any> DataNode<T>.map(
|
||||
public inline fun <T : Any, reified R : Any> DataNode<T>.map(
|
||||
meta: Meta,
|
||||
noinline action: MapActionBuilder<in T, out R>.() -> Unit
|
||||
): DataNode<R> = MapAction(T::class, R::class, action).invoke(this, meta)
|
||||
): DataNode<R> = MapAction(R::class, action).invoke(this, meta)
|
||||
|
||||
|
||||
|
||||
|
@ -72,35 +72,31 @@ public class ReduceGroupBuilder<T : Any, R : Any>(public val actionMeta: Meta) {
|
||||
* The same rules as for KPipe
|
||||
*/
|
||||
public class ReduceAction<T : Any, R : Any>(
|
||||
public val inputType: KClass<T>,
|
||||
public val outputType: KClass<out R>,
|
||||
private val action: ReduceGroupBuilder<T, R>.() -> Unit
|
||||
) : Action<T, R> {
|
||||
|
||||
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> {
|
||||
node.ensureType(inputType)
|
||||
return DataNode.invoke(outputType) {
|
||||
ReduceGroupBuilder<T, R>(meta).apply(action).buildGroups(node).forEach { group ->
|
||||
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> = DataNode(outputType) {
|
||||
ReduceGroupBuilder<T, R>(meta).apply(action).buildGroups(node).forEach { group ->
|
||||
|
||||
//val laminate = Laminate(group.meta, meta)
|
||||
//val laminate = Laminate(group.meta, meta)
|
||||
|
||||
val dataMap = group.node.dataSequence().associate { it }
|
||||
val dataMap = group.node.dataSequence().associate { it }
|
||||
|
||||
val groupName: String = group.name
|
||||
val groupName: String = group.name
|
||||
|
||||
val groupMeta = group.meta
|
||||
val groupMeta = group.meta
|
||||
|
||||
val env = ActionEnv(groupName.toName(), groupMeta, meta)
|
||||
val env = ActionEnv(groupName.toName(), groupMeta, meta)
|
||||
|
||||
val res: DynamicData<R> = dataMap.reduce(
|
||||
outputType,
|
||||
meta = groupMeta
|
||||
) { group.result.invoke(env, it) }
|
||||
|
||||
set(env.name, res)
|
||||
}
|
||||
val res: ComputationData<R> = dataMap.reduce(
|
||||
outputType,
|
||||
meta = groupMeta
|
||||
) { group.result.invoke(env, it) }
|
||||
|
||||
set(env.name, res)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,31 +33,26 @@ public class SplitBuilder<T : Any, R : Any>(public val name: Name, public val me
|
||||
}
|
||||
|
||||
public class SplitAction<T : Any, R : Any>(
|
||||
public val inputType: KClass<T>,
|
||||
public val outputType: KClass<out R>,
|
||||
private val action: SplitBuilder<T, R>.() -> Unit
|
||||
) : Action<T, R> {
|
||||
|
||||
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> {
|
||||
node.ensureType(inputType)
|
||||
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> = DataNode(outputType) {
|
||||
node.dataSequence().forEach { (name, data) ->
|
||||
|
||||
return DataNode.invoke(outputType) {
|
||||
node.dataSequence().forEach { (name, data) ->
|
||||
val laminate = Laminate(data.meta, meta)
|
||||
|
||||
val laminate = Laminate(data.meta, meta)
|
||||
|
||||
val split = SplitBuilder<T, R>(name, data.meta).apply(action)
|
||||
val split = SplitBuilder<T, R>(name, data.meta).apply(action)
|
||||
|
||||
|
||||
// apply individual fragment rules to result
|
||||
split.fragments.forEach { (fragmentName, rule) ->
|
||||
val env = FragmentRule<T, R>(fragmentName, laminate.builder())
|
||||
// apply individual fragment rules to result
|
||||
split.fragments.forEach { (fragmentName, rule) ->
|
||||
val env = FragmentRule<T, R>(fragmentName, laminate.builder())
|
||||
|
||||
rule(env)
|
||||
rule(env)
|
||||
|
||||
val res = data.map(outputType, meta = env.meta) { env.result(it) }
|
||||
set(env.name, res)
|
||||
}
|
||||
val res = data.map(outputType, meta = env.meta) { env.result(it) }
|
||||
set(env.name, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,73 +0,0 @@
|
||||
package hep.dataforge.data
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.NameToken
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public fun <R : Any, T : R> Data<T>.upcast(type: KClass<out R>): Data<R> {
|
||||
return object : Data<R> by this {
|
||||
override val type: KClass<out R> = type
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe upcast a [Data] to a supertype
|
||||
*/
|
||||
public inline fun <reified R : Any, T : R> Data<T>.upcast(): Data<R> = upcast(R::class)
|
||||
|
||||
/**
|
||||
* Check if node could be safely cast to given class
|
||||
*/
|
||||
internal expect fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean
|
||||
|
||||
/**
|
||||
* Check if data could be safely cast to given class
|
||||
*/
|
||||
internal expect fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean
|
||||
|
||||
public fun <R : Any> DataItem<*>.canCast(type: KClass<out R>): Boolean = when (this) {
|
||||
is DataItem.Node -> node.canCast(type)
|
||||
is DataItem.Leaf -> data.canCast(type)
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsafe cast of data node
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public fun <R : Any> Data<*>.cast(type: KClass<out R>): Data<R> {
|
||||
return object : Data<R> {
|
||||
override val meta: Meta get() = this@cast.meta
|
||||
override val dependencies: Collection<Goal<*>> get() = this@cast.dependencies
|
||||
override val result: Deferred<R>? get() = this@cast.result as Deferred<R>
|
||||
override fun CoroutineScope.startAsync(): Deferred<R> = this@cast.run { startAsync() as Deferred<R> }
|
||||
override fun reset() = this@cast.reset()
|
||||
override val type: KClass<out R> = type
|
||||
}
|
||||
}
|
||||
|
||||
public inline fun <reified R : Any> Data<*>.cast(): Data<R> = cast(R::class)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public fun <R : Any> DataNode<*>.cast(type: KClass<out R>): DataNode<R> {
|
||||
return object : DataNode<R> {
|
||||
override val meta: Meta get() = this@cast.meta
|
||||
override val type: KClass<out R> = type
|
||||
override val items: Map<NameToken, DataItem<R>> get() = this@cast.items as Map<NameToken, DataItem<R>>
|
||||
}
|
||||
}
|
||||
|
||||
public inline fun <reified R : Any> DataNode<*>.cast(): DataNode<R> = cast(R::class)
|
||||
|
||||
/**
|
||||
* Check that node is compatible with given type meaning that each element could be cast to the type
|
||||
*/
|
||||
public fun <T : Any> DataNode<*>.ensureType(type: KClass<out T>) {
|
||||
if (!canCast(type)) {
|
||||
error("$type expected, but $type received")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//expect fun <T : Any, R : Any> DataNode<T>.cast(type: KClass<out R>): DataNode<R>
|
@ -1,14 +0,0 @@
|
||||
package hep.dataforge.data
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Check that node is compatible with given type meaning that each element could be cast to the type
|
||||
*/
|
||||
internal actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean {
|
||||
return this.type == type
|
||||
}
|
||||
|
||||
internal actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean {
|
||||
return this.type == type
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
package hep.dataforge.data
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.NameToken
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.isSubclassOf
|
||||
@ -12,12 +16,72 @@ public fun <T : Any> Data<T>.get(): T = runBlocking { await() }
|
||||
/**
|
||||
* Check that node is compatible with given type meaning that each element could be cast to the type
|
||||
*/
|
||||
internal actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean =
|
||||
internal fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean =
|
||||
type.isSubclassOf(this.type)
|
||||
|
||||
internal actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean =
|
||||
/**
|
||||
* Check if data could be safely cast to given class
|
||||
*/
|
||||
internal fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean =
|
||||
this.type.isSubclassOf(type)
|
||||
|
||||
|
||||
public fun <R : Any, T : R> Data<T>.upcast(type: KClass<out R>): Data<R> {
|
||||
return object : Data<R> by this {
|
||||
override val type: KClass<out R> = type
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe upcast a [Data] to a supertype
|
||||
*/
|
||||
public inline fun <reified R : Any, T : R> Data<T>.upcast(): Data<R> = upcast(R::class)
|
||||
|
||||
public fun <R : Any> DataItem<*>.canCast(type: KClass<out R>): Boolean = when (this) {
|
||||
is DataItem.Node -> node.canCast(type)
|
||||
is DataItem.Leaf -> data.canCast(type)
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsafe cast of data node
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public fun <R : Any> Data<*>.cast(type: KClass<out R>): Data<R> {
|
||||
if(!canCast(type)) error("Can't cast ${this.type} to $type")
|
||||
return object : Data<R> {
|
||||
override val meta: Meta get() = this@cast.meta
|
||||
override val dependencies: Collection<Goal<*>> get() = this@cast.dependencies
|
||||
override val result: Deferred<R>? get() = this@cast.result as Deferred<R>?
|
||||
override fun startAsync(coroutineScope: CoroutineScope): Deferred<R> = this@cast.run {
|
||||
startAsync(coroutineScope) as Deferred<R>
|
||||
}
|
||||
|
||||
override fun reset() = this@cast.reset()
|
||||
override val type: KClass<out R> = type
|
||||
}
|
||||
}
|
||||
|
||||
public inline fun <reified R : Any> Data<*>.cast(): Data<R> = cast(R::class)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public fun <R : Any> DataNode<*>.cast(type: KClass<out R>): DataNode<R> {
|
||||
return object : DataNode<R> {
|
||||
override val meta: Meta get() = this@cast.meta
|
||||
override val type: KClass<out R> = type
|
||||
override val items: Map<NameToken, DataItem<R>> get() = this@cast.items as Map<NameToken, DataItem<R>>
|
||||
}
|
||||
}
|
||||
|
||||
public inline fun <reified R : Any> DataNode<*>.cast(): DataNode<R> = cast(R::class)
|
||||
|
||||
/**
|
||||
* Check that node is compatible with given type meaning that each element could be cast to the type
|
||||
*/
|
||||
public fun <T : Any> DataNode<*>.ensureType(type: KClass<out T>) {
|
||||
if (!canCast(type)) {
|
||||
error("$type expected, but $type received")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast the node to given type if the cast is possible or return null
|
||||
*/
|
||||
|
@ -1,14 +0,0 @@
|
||||
package hep.dataforge.data
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Check that node is compatible with given type meaning that each element could be cast to the type
|
||||
*/
|
||||
internal actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean {
|
||||
return this.type == type
|
||||
}
|
||||
|
||||
internal actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean {
|
||||
return this.type == type
|
||||
}
|
@ -5,7 +5,7 @@ import hep.dataforge.io.EnvelopeFormatFactory.Companion.ENVELOPE_FORMAT_TYPE
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.type.Type
|
||||
import kotlinx.io.Input
|
||||
import kotlinx.io.Output
|
||||
import kotlin.reflect.KClass
|
||||
|
@ -10,7 +10,7 @@ import hep.dataforge.meta.MetaRepr
|
||||
import hep.dataforge.meta.ValueItem
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.type.Type
|
||||
import hep.dataforge.values.Value
|
||||
import kotlinx.io.*
|
||||
import kotlinx.io.buffer.Buffer
|
||||
|
@ -7,7 +7,7 @@ import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.type.Type
|
||||
import kotlinx.io.ByteArrayInput
|
||||
import kotlinx.io.Input
|
||||
import kotlinx.io.Output
|
||||
|
@ -812,6 +812,10 @@ public final class hep/dataforge/names/NameTokenKt {
|
||||
public static final fun withIndex (Lhep/dataforge/names/NameToken;Ljava/lang/String;)Lhep/dataforge/names/NameToken;
|
||||
}
|
||||
|
||||
public abstract interface annotation class hep/dataforge/type/Type : java/lang/annotation/Annotation {
|
||||
public abstract fun id ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/values/DoubleArrayValue : hep/dataforge/values/Value, java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker {
|
||||
public fun <init> ([D)V
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
|
@ -1,4 +1,4 @@
|
||||
package hep.dataforge.provider
|
||||
package hep.dataforge.type
|
||||
|
||||
/**
|
||||
* A text label for internal DataForge type classification. Alternative for mime container type.
|
@ -210,8 +210,6 @@ public abstract interface class hep/dataforge/workspace/Workspace : hep/dataforg
|
||||
|
||||
public final class hep/dataforge/workspace/Workspace$Companion {
|
||||
public static final field TYPE Ljava/lang/String;
|
||||
public final fun invoke (Lhep/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/workspace/SimpleWorkspace;
|
||||
public static synthetic fun invoke$default (Lhep/dataforge/workspace/Workspace$Companion;Lhep/dataforge/context/Context;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/workspace/SimpleWorkspace;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/workspace/Workspace$DefaultImpls {
|
||||
@ -235,6 +233,8 @@ public abstract interface class hep/dataforge/workspace/WorkspaceBuilder {
|
||||
}
|
||||
|
||||
public final class hep/dataforge/workspace/WorkspaceBuilderKt {
|
||||
public static final fun Workspace (Lhep/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/workspace/Workspace;
|
||||
public static synthetic fun Workspace$default (Lhep/dataforge/context/Context;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/workspace/Workspace;
|
||||
public static final fun context (Lhep/dataforge/workspace/WorkspaceBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
|
||||
public static synthetic fun context$default (Lhep/dataforge/workspace/WorkspaceBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public static final fun rawData (Lhep/dataforge/workspace/WorkspaceBuilder;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/data/DataNode;
|
||||
|
@ -4,7 +4,7 @@ import hep.dataforge.context.Named
|
||||
import hep.dataforge.data.DataNode
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.descriptors.Described
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.type.Type
|
||||
import hep.dataforge.workspace.Task.Companion.TYPE
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package hep.dataforge.workspace
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.ContextAware
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.data.Data
|
||||
import hep.dataforge.data.DataNode
|
||||
import hep.dataforge.data.dataSequence
|
||||
@ -11,7 +9,7 @@ import hep.dataforge.meta.MetaBuilder
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.provider.Provider
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.type.Type
|
||||
|
||||
|
||||
@Type(Workspace.TYPE)
|
||||
@ -52,11 +50,6 @@ public interface Workspace : ContextAware, Provider {
|
||||
|
||||
public companion object {
|
||||
public const val TYPE: String = "workspace"
|
||||
public operator fun invoke(
|
||||
parent: Context = Global,
|
||||
block: SimpleWorkspaceBuilder.() -> Unit,
|
||||
): SimpleWorkspace =
|
||||
SimpleWorkspaceBuilder(parent).apply(block).build()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import hep.dataforge.meta.string
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.names.toName
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@DFBuilder
|
||||
@ -28,7 +27,7 @@ public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass
|
||||
private inner class DataTransformation(
|
||||
val from: String = "",
|
||||
val to: String = "",
|
||||
val transform: (Context, TaskModel, DataNode<Any>) -> DataNode<R>
|
||||
val transform: (Context, TaskModel, DataNode<Any>) -> DataNode<R>,
|
||||
) {
|
||||
operator fun invoke(workspace: Workspace, model: TaskModel, node: DataNode<Any>): DataNode<R>? {
|
||||
val localData = if (from.isEmpty()) {
|
||||
@ -55,7 +54,7 @@ public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass
|
||||
public fun transform(
|
||||
from: String = "",
|
||||
to: String = "",
|
||||
block: TaskEnv.(DataNode<*>) -> DataNode<R>
|
||||
block: TaskEnv.(DataNode<*>) -> DataNode<R>,
|
||||
) {
|
||||
dataTransforms += DataTransformation(from, to) { context, model, data ->
|
||||
val env = TaskEnv(Name.EMPTY, model.meta, context, data)
|
||||
@ -67,7 +66,7 @@ public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass
|
||||
inputType: KClass<out T>,
|
||||
from: String = "",
|
||||
to: String = "",
|
||||
block: TaskEnv.(DataNode<T>) -> DataNode<R>
|
||||
block: TaskEnv.(DataNode<T>) -> DataNode<R>,
|
||||
) {
|
||||
dataTransforms += DataTransformation(from, to) { context, model, data ->
|
||||
data.ensureType(inputType)
|
||||
@ -79,7 +78,7 @@ public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass
|
||||
public inline fun <reified T : Any> transform(
|
||||
from: String = "",
|
||||
to: String = "",
|
||||
noinline block: TaskEnv.(DataNode<T>) -> DataNode<R>
|
||||
noinline block: TaskEnv.(DataNode<T>) -> DataNode<R>,
|
||||
) {
|
||||
transform(T::class, from, to, block)
|
||||
}
|
||||
@ -90,14 +89,19 @@ public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass
|
||||
public inline fun <reified T : Any> action(
|
||||
from: String = "",
|
||||
to: String = "",
|
||||
crossinline block: TaskEnv.() -> Action<T, R>
|
||||
crossinline block: TaskEnv.() -> Action<T, R>,
|
||||
) {
|
||||
transform(from, to) { data: DataNode<T> ->
|
||||
block().invoke(data, meta)
|
||||
}
|
||||
}
|
||||
|
||||
public class TaskEnv(public val name: Name, public val meta: Meta, public val context: Context, public val data: DataNode<Any>) {
|
||||
public class TaskEnv(
|
||||
public val name: Name,
|
||||
public val meta: Meta,
|
||||
public val context: Context,
|
||||
public val data: DataNode<Any>,
|
||||
) {
|
||||
public operator fun <T : Any> DirectTaskDependency<T>.invoke(): DataNode<T> = if (placement.isEmpty()) {
|
||||
data.cast(task.type)
|
||||
} else {
|
||||
@ -112,14 +116,11 @@ public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass
|
||||
public inline fun <reified T : Any> mapAction(
|
||||
from: String = "",
|
||||
to: String = "",
|
||||
crossinline block: MapActionBuilder<T, R>.(TaskEnv) -> Unit
|
||||
crossinline block: MapActionBuilder<T, R>.(TaskEnv) -> Unit,
|
||||
) {
|
||||
action(from, to) {
|
||||
val env = this
|
||||
MapAction(
|
||||
inputType = T::class,
|
||||
outputType = type
|
||||
) {
|
||||
MapAction<T, R>(type) {
|
||||
block(env)
|
||||
}
|
||||
}
|
||||
@ -131,13 +132,10 @@ public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass
|
||||
public inline fun <reified T : Any> map(
|
||||
from: String = "",
|
||||
to: String = "",
|
||||
crossinline block: suspend TaskEnv.(T) -> R
|
||||
crossinline block: suspend TaskEnv.(T) -> R,
|
||||
) {
|
||||
action(from, to) {
|
||||
MapAction(
|
||||
inputType = T::class,
|
||||
outputType = type
|
||||
) {
|
||||
MapAction<T,R>(type) {
|
||||
//TODO automatically append task meta
|
||||
result = { data ->
|
||||
block(data)
|
||||
@ -152,14 +150,11 @@ public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass
|
||||
public inline fun <reified T : Any> reduceByGroup(
|
||||
from: String = "",
|
||||
to: String = "",
|
||||
crossinline block: ReduceGroupBuilder<T, R>.(TaskEnv) -> Unit //TODO needs KEEP-176
|
||||
crossinline block: ReduceGroupBuilder<T, R>.(TaskEnv) -> Unit, //TODO needs KEEP-176
|
||||
) {
|
||||
action(from, to) {
|
||||
val env = this
|
||||
ReduceAction(
|
||||
inputType = T::class,
|
||||
outputType = type
|
||||
) { block(env) }
|
||||
ReduceAction<T, R>(type) { block(env) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,20 +164,16 @@ public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass
|
||||
public inline fun <reified T : Any> reduce(
|
||||
from: String = "",
|
||||
to: String = "",
|
||||
crossinline block: suspend TaskEnv.(Map<Name, T>) -> R
|
||||
crossinline block: suspend TaskEnv.(Map<Name, T>) -> R,
|
||||
) {
|
||||
action(from, to) {
|
||||
ReduceAction(
|
||||
inputType = T::class,
|
||||
outputType = type,
|
||||
action = {
|
||||
result(
|
||||
actionMeta[TaskModel.MODEL_TARGET_KEY]?.string ?: "@anonymous"
|
||||
) { data ->
|
||||
block(data)
|
||||
}
|
||||
ReduceAction<T, R>(type) {
|
||||
result(
|
||||
actionMeta[TaskModel.MODEL_TARGET_KEY]?.string ?: "@anonymous"
|
||||
) { data ->
|
||||
block(data)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,14 +183,11 @@ public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass
|
||||
public inline fun <reified T : Any> split(
|
||||
from: String = "",
|
||||
to: String = "",
|
||||
crossinline block: SplitBuilder<T, R>.(TaskEnv) -> Unit //TODO needs KEEP-176
|
||||
crossinline block: SplitBuilder<T, R>.(TaskEnv) -> Unit, //TODO needs KEEP-176
|
||||
) {
|
||||
action(from, to) {
|
||||
val env = this
|
||||
SplitAction(
|
||||
inputType = T::class,
|
||||
outputType = type
|
||||
) { block(env) }
|
||||
SplitAction<T, R>(type) { block(this, env) }
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,13 @@ package hep.dataforge.workspace
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.ContextBuilder
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.data.DataNode
|
||||
import hep.dataforge.data.DataTreeBuilder
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.names.toName
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@DFBuilder
|
||||
@ -95,4 +95,9 @@ public class SimpleWorkspaceBuilder(override val parentContext: Context) : Works
|
||||
override fun build(): SimpleWorkspace {
|
||||
return SimpleWorkspace(context, data.build(), targets, tasks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun Workspace(
|
||||
parent: Context = Global,
|
||||
block: SimpleWorkspaceBuilder.() -> Unit,
|
||||
): Workspace = SimpleWorkspaceBuilder(parent).apply(block).build()
|
Loading…
Reference in New Issue
Block a user