Compare commits
2 Commits
4197b4bb61
...
aa4c745819
Author | SHA1 | Date | |
---|---|---|---|
aa4c745819 | |||
e850ca4145 |
@ -21,7 +21,7 @@ internal fun MutableMap<Name, *>.removeWhatStartsWith(name: Name) {
|
|||||||
/**
|
/**
|
||||||
* An action that caches results on-demand and recalculates them on source push
|
* An action that caches results on-demand and recalculates them on source push
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractAction<T : Any, R : Any>(
|
public abstract class AbstractAction<T, R>(
|
||||||
public val outputType: KType,
|
public val outputType: KType,
|
||||||
) : Action<T, R> {
|
) : Action<T, R> {
|
||||||
|
|
||||||
@ -37,21 +37,23 @@ public abstract class AbstractAction<T : Any, R : Any>(
|
|||||||
* Update part of the data set using provided data
|
* Update part of the data set using provided data
|
||||||
*
|
*
|
||||||
* @param source the source data tree in case we need several data items to update
|
* @param source the source data tree in case we need several data items to update
|
||||||
|
* @param meta the metadata used for the whole data tree
|
||||||
|
* @param updatedData an updated item
|
||||||
*/
|
*/
|
||||||
protected open fun DataSink<R>.update(
|
protected open fun DataSink<R>.update(
|
||||||
source: DataTree<T>,
|
source: DataTree<T>,
|
||||||
meta: Meta,
|
meta: Meta,
|
||||||
namedData: NamedData<T>,
|
updatedData: NamedData<T>,
|
||||||
){
|
) {
|
||||||
//by default regenerate the whole data set
|
//by default regenerate the whole data set
|
||||||
generate(source,meta)
|
generate(source, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(DFInternal::class)
|
@OptIn(DFInternal::class)
|
||||||
override fun execute(
|
override fun execute(
|
||||||
dataSet: DataTree<T>,
|
dataSet: DataTree<T>,
|
||||||
meta: Meta,
|
meta: Meta,
|
||||||
): DataTree<R> = if(dataSet.isObservable()) {
|
): DataTree<R> = if (dataSet.isObservable()) {
|
||||||
MutableDataTree<R>(outputType, dataSet.updatesScope).apply {
|
MutableDataTree<R>(outputType, dataSet.updatesScope).apply {
|
||||||
generate(dataSet, meta)
|
generate(dataSet, meta)
|
||||||
dataSet.updates().onEach {
|
dataSet.updates().onEach {
|
||||||
@ -64,8 +66,8 @@ public abstract class AbstractAction<T : Any, R : Any>(
|
|||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else{
|
} else {
|
||||||
DataTree(outputType){
|
DataTree(outputType) {
|
||||||
generate(dataSet, meta)
|
generate(dataSet, meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public class MapActionBuilder<T, R>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal class MapAction<T : Any, R : Any>(
|
internal class MapAction<T, R>(
|
||||||
outputType: KType,
|
outputType: KType,
|
||||||
private val block: MapActionBuilder<T, R>.() -> Unit,
|
private val block: MapActionBuilder<T, R>.() -> Unit,
|
||||||
) : AbstractAction<T, R>(outputType) {
|
) : AbstractAction<T, R>(outputType) {
|
||||||
@ -86,8 +86,8 @@ internal class MapAction<T : Any, R : Any>(
|
|||||||
data.forEach { mapOne(it.name, it.data, meta) }
|
data.forEach { mapOne(it.name, it.data, meta) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun DataSink<R>.update(source: DataTree<T>, meta: Meta, namedData: NamedData<T>) {
|
override fun DataSink<R>.update(source: DataTree<T>, meta: Meta, updatedData: NamedData<T>) {
|
||||||
mapOne(namedData.name, namedData.data, namedData.meta)
|
mapOne(updatedData.name, updatedData.data, updatedData.meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ internal class MapAction<T : Any, R : Any>(
|
|||||||
* A one-to-one mapping action
|
* A one-to-one mapping action
|
||||||
*/
|
*/
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
public inline fun <T : Any, reified R : Any> Action.Companion.mapping(
|
public inline fun <T, reified R> Action.Companion.mapping(
|
||||||
noinline builder: MapActionBuilder<T, R>.() -> Unit,
|
noinline builder: MapActionBuilder<T, R>.() -> Unit,
|
||||||
): Action<T, R> = MapAction(typeOf<R>(), builder)
|
): Action<T, R> = MapAction(typeOf<R>(), builder)
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import kotlin.reflect.KType
|
|||||||
import kotlin.reflect.typeOf
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
|
||||||
public class JoinGroup<T : Any, R : Any>(
|
public class JoinGroup<T, R>(
|
||||||
public var name: String,
|
public var name: String,
|
||||||
internal val set: DataTree<T>,
|
internal val set: DataTree<T>,
|
||||||
@PublishedApi internal var outputType: KType,
|
@PublishedApi internal var outputType: KType,
|
||||||
@ -35,7 +35,7 @@ public class JoinGroup<T : Any, R : Any>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DFBuilder
|
@DFBuilder
|
||||||
public class ReduceGroupBuilder<T : Any, R : Any>(
|
public class ReduceGroupBuilder<T, R>(
|
||||||
public val actionMeta: Meta,
|
public val actionMeta: Meta,
|
||||||
private val outputType: KType,
|
private val outputType: KType,
|
||||||
) {
|
) {
|
||||||
@ -79,7 +79,7 @@ public class ReduceGroupBuilder<T : Any, R : Any>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal class ReduceAction<T : Any, R : Any>(
|
internal class ReduceAction<T, R>(
|
||||||
outputType: KType,
|
outputType: KType,
|
||||||
private val action: ReduceGroupBuilder<T, R>.() -> Unit,
|
private val action: ReduceGroupBuilder<T, R>.() -> Unit,
|
||||||
) : AbstractAction<T, R>(outputType) {
|
) : AbstractAction<T, R>(outputType) {
|
||||||
|
@ -13,9 +13,9 @@ import kotlin.reflect.KType
|
|||||||
import kotlin.reflect.typeOf
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
|
||||||
public class SplitBuilder<T : Any, R : Any>(public val name: Name, public val meta: Meta) {
|
public class SplitBuilder<T, R>(public val name: Name, public val meta: Meta) {
|
||||||
|
|
||||||
public class FragmentRule<T : Any, R : Any>(
|
public class FragmentRule<T, R>(
|
||||||
public val name: Name,
|
public val name: Name,
|
||||||
public var meta: MutableMeta,
|
public var meta: MutableMeta,
|
||||||
@PublishedApi internal var outputType: KType,
|
@PublishedApi internal var outputType: KType,
|
||||||
@ -44,7 +44,7 @@ public class SplitBuilder<T : Any, R : Any>(public val name: Name, public val me
|
|||||||
* Action that splits each incoming element into a number of fragments defined in builder
|
* Action that splits each incoming element into a number of fragments defined in builder
|
||||||
*/
|
*/
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal class SplitAction<T : Any, R : Any>(
|
internal class SplitAction<T, R>(
|
||||||
outputType: KType,
|
outputType: KType,
|
||||||
private val action: SplitBuilder<T, R>.() -> Unit,
|
private val action: SplitBuilder<T, R>.() -> Unit,
|
||||||
) : AbstractAction<T, R>(outputType) {
|
) : AbstractAction<T, R>(outputType) {
|
||||||
@ -77,8 +77,8 @@ internal class SplitAction<T : Any, R : Any>(
|
|||||||
data.forEach { splitOne(it.name, it.data, meta) }
|
data.forEach { splitOne(it.name, it.data, meta) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun DataSink<R>.update(source: DataTree<T>, meta: Meta, namedData: NamedData<T>) {
|
override fun DataSink<R>.update(source: DataTree<T>, meta: Meta, updatedData: NamedData<T>) {
|
||||||
splitOne(namedData.name, namedData.data, namedData.meta)
|
splitOne(updatedData.name, updatedData.data, updatedData.meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import space.kscience.dataforge.meta.string
|
|||||||
import space.kscience.dataforge.misc.DFInternal
|
import space.kscience.dataforge.misc.DFInternal
|
||||||
|
|
||||||
public interface GroupRule {
|
public interface GroupRule {
|
||||||
public fun <T : Any> gather(set: DataTree<T>): Map<String, DataTree<T>>
|
public fun <T> gather(set: DataTree<T>): Map<String, DataTree<T>>
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
/**
|
/**
|
||||||
@ -37,7 +37,7 @@ public interface GroupRule {
|
|||||||
defaultTagValue: String,
|
defaultTagValue: String,
|
||||||
): GroupRule = object : GroupRule {
|
): GroupRule = object : GroupRule {
|
||||||
|
|
||||||
override fun <T : Any> gather(
|
override fun <T> gather(
|
||||||
set: DataTree<T>,
|
set: DataTree<T>,
|
||||||
): Map<String, DataTree<T>> {
|
): Map<String, DataTree<T>> {
|
||||||
val map = HashMap<String, DataTreeBuilder<T>>()
|
val map = HashMap<String, DataTreeBuilder<T>>()
|
||||||
|
@ -10,7 +10,7 @@ public interface NamedData<out T> : Named, Data<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public operator fun NamedData<*>.component1(): Name = name
|
public operator fun NamedData<*>.component1(): Name = name
|
||||||
public operator fun <T: Any> NamedData<T>.component2(): Data<T> = data
|
public operator fun <T> NamedData<T>.component2(): Data<T> = data
|
||||||
|
|
||||||
private class NamedDataImpl<T>(
|
private class NamedDataImpl<T>(
|
||||||
override val name: Name,
|
override val name: Name,
|
||||||
|
@ -19,6 +19,10 @@ public annotation class MetaBuilderMarker
|
|||||||
public interface MutableMetaProvider : MetaProvider, MutableValueProvider {
|
public interface MutableMetaProvider : MetaProvider, MutableValueProvider {
|
||||||
override fun get(name: Name): MutableMeta?
|
override fun get(name: Name): MutableMeta?
|
||||||
public operator fun set(name: Name, node: Meta?)
|
public operator fun set(name: Name, node: Meta?)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set value with the given name. Does nothing if value is not changed.
|
||||||
|
*/
|
||||||
override fun setValue(name: Name, value: Value?)
|
override fun setValue(name: Name, value: Value?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,11 +52,13 @@ public interface MutableMeta : Meta, MutableMetaProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(name: Name, value: Value?) {
|
override fun setValue(name: Name, value: Value?) {
|
||||||
getOrCreate(name).value = value
|
if (value != getValue(name)) {
|
||||||
|
getOrCreate(name).value = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get existing node or create a new one
|
* Get an existing node or create a new one
|
||||||
*/
|
*/
|
||||||
public fun getOrCreate(name: Name): MutableMeta
|
public fun getOrCreate(name: Name): MutableMeta
|
||||||
|
|
||||||
@ -198,10 +204,8 @@ public operator fun MutableMetaProvider.set(key: String, metas: Iterable<Meta>):
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update existing mutable node with another node. The rules are following:
|
* Update the existing mutable node with another node.
|
||||||
* * value replaces anything
|
* Values that are present in the current provider and are missing in [meta] are kept.
|
||||||
* * node updates node and replaces anything but node
|
|
||||||
* * node list updates node list if number of nodes in the list is the same and replaces anything otherwise
|
|
||||||
*/
|
*/
|
||||||
public fun MutableMetaProvider.update(meta: Meta) {
|
public fun MutableMetaProvider.update(meta: Meta) {
|
||||||
meta.valueSequence().forEach { (name, value) ->
|
meta.valueSequence().forEach { (name, value) ->
|
||||||
@ -222,7 +226,7 @@ public fun <M : MutableTypedMeta<M>> MutableTypedMeta<M>.edit(name: Name, builde
|
|||||||
getOrCreate(name).apply(builder)
|
getOrCreate(name).apply(builder)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a value at a given [name]. If node does not exist, create it.
|
* Set a value at a given [name]. If a node does not exist, create it.
|
||||||
*/
|
*/
|
||||||
public operator fun <M : MutableTypedMeta<M>> MutableTypedMeta<M>.set(name: Name, value: Value?) {
|
public operator fun <M : MutableTypedMeta<M>> MutableTypedMeta<M>.set(name: Name, value: Value?) {
|
||||||
edit(name) {
|
edit(name) {
|
||||||
@ -367,6 +371,21 @@ public fun MutableMeta.append(name: Name, value: Value): Unit = append(name, Met
|
|||||||
|
|
||||||
public fun MutableMeta.append(key: String, value: Value): Unit = append(Name.parse(key), value)
|
public fun MutableMeta.append(key: String, value: Value): Unit = append(Name.parse(key), value)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update all items that exist in the [newMeta] and remove existing items that are missing in [newMeta].
|
||||||
|
* This produces the same result as clearing all items and updating blank meta with a [newMeta], but does not
|
||||||
|
* produce unnecessary invalidation events (if they are supported).
|
||||||
|
*/
|
||||||
|
public fun MutableMeta.reset(newMeta: Meta) {
|
||||||
|
//remove old items
|
||||||
|
(items.keys - newMeta.items.keys).forEach {
|
||||||
|
remove(it.asName())
|
||||||
|
}
|
||||||
|
newMeta.items.forEach { (token, item)->
|
||||||
|
set(token, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a mutable copy of this meta. The copy is created even if the Meta is already mutable
|
* Create a mutable copy of this meta. The copy is created even if the Meta is already mutable
|
||||||
*/
|
*/
|
||||||
|
@ -76,6 +76,8 @@ internal class MetaBuilder(
|
|||||||
|
|
||||||
|
|
||||||
override fun set(name: Name, node: Meta?) {
|
override fun set(name: Name, node: Meta?) {
|
||||||
|
//skip setting if value has not changed
|
||||||
|
if(node == get(name)) return
|
||||||
when (name.length) {
|
when (name.length) {
|
||||||
0 -> error("Can't set a meta with empty name")
|
0 -> error("Can't set a meta with empty name")
|
||||||
1 -> {
|
1 -> {
|
||||||
@ -89,7 +91,7 @@ internal class MetaBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
getOrCreate(name.first().asName()).set(name.cutFirst(), node)
|
getOrCreate(name.first().asName())[name.cutFirst()] = node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,4 +61,33 @@ class MetaTest {
|
|||||||
assertEquals(null, indexed["8"])
|
assertEquals(null, indexed["8"])
|
||||||
assertEquals(12, indexed["12"].int)
|
assertEquals(12, indexed["12"].int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun reset() {
|
||||||
|
val oldMeta = MutableMeta {
|
||||||
|
"a" put {
|
||||||
|
"value" put "aValue"
|
||||||
|
}
|
||||||
|
"b" put {
|
||||||
|
"value" put "bValue"
|
||||||
|
}
|
||||||
|
"c" put {
|
||||||
|
"value" put "cValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val newMeta = Meta {
|
||||||
|
"a" put {
|
||||||
|
"value" put "aValue"
|
||||||
|
}
|
||||||
|
"b" put {
|
||||||
|
"value" put "bValue"
|
||||||
|
}
|
||||||
|
"d" put {
|
||||||
|
"value" put "dValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oldMeta.reset(newMeta)
|
||||||
|
println(oldMeta)
|
||||||
|
assertEquals(setOf("a", "b", "d"), oldMeta.items.keys.map { it.toString() }.toSet())
|
||||||
|
}
|
||||||
}
|
}
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
Loading…
Reference in New Issue
Block a user