From 4197b4bb6165f5847d1d84359a67702894b337a6 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 6 Feb 2024 14:36:20 +0300 Subject: [PATCH] Add ordering to name indices --- CHANGELOG.md | 2 ++ build.gradle.kts | 2 +- .../kscience/dataforge/io/EnvelopeParts.kt | 3 +- .../dataforge/meta/MutableMetaDelegate.kt | 3 +- .../space/kscience/dataforge/meta/Scheme.kt | 7 ++--- .../dataforge/names/NameIndexComparator.kt | 30 +++++++++++++++++++ .../dataforge/meta/ObservableMetaTest.kt | 2 -- 7 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/names/NameIndexComparator.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index b9d3b6a9..e5d85a2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased ### Added +- Name index comparator ### Changed @@ -11,6 +12,7 @@ ### Removed ### Fixed +- `listOfScheme` and `listOfConvertable` delegates provides correct items order ### Security diff --git a/build.gradle.kts b/build.gradle.kts index b9349868..d41918ac 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { allprojects { group = "space.kscience" - version = "0.8.0" + version = "0.8.1-dev-1" } subprojects { diff --git a/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/EnvelopeParts.kt b/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/EnvelopeParts.kt index 183e7b03..88231899 100644 --- a/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/EnvelopeParts.kt +++ b/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/EnvelopeParts.kt @@ -11,6 +11,7 @@ import space.kscience.dataforge.io.PartDescriptor.Companion.PARTS_KEY import space.kscience.dataforge.io.PartDescriptor.Companion.SEPARATOR_KEY import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.getIndexedList import space.kscience.dataforge.names.plus private class PartDescriptor : Scheme() { @@ -84,7 +85,7 @@ public fun EnvelopeBuilder.envelopes( public fun Envelope.parts(): EnvelopeParts { if (data == null) return emptyList() //TODO add zip folder reader - val parts = meta.getIndexed(PARTS_KEY).values.map { + val parts = meta.getIndexedList(PARTS_KEY).map { PartDescriptor.read(it) } return if (parts.isEmpty()) { diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MutableMetaDelegate.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MutableMetaDelegate.kt index f6e96109..70c4aceb 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MutableMetaDelegate.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MutableMetaDelegate.kt @@ -4,6 +4,7 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.getIndexedList import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty @@ -65,7 +66,7 @@ public fun MutableMeta.listOfConvertable( ): ReadWriteProperty> = object : ReadWriteProperty> { override fun getValue(thisRef: Any?, property: KProperty<*>): List { val name = key ?: property.name.asName() - return getIndexed(name).values.map { converter.read(it) } + return getIndexedList(name).map { converter.read(it) } } override fun setValue(thisRef: Any?, property: KProperty<*>, value: List) { diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt index c330de99..96b6df49 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt @@ -18,7 +18,7 @@ import kotlin.reflect.KProperty1 */ public open class Scheme( private var prototype: Meta? = null, - descriptor: MetaDescriptor? = null + descriptor: MetaDescriptor? = null, ) : Described, MetaRepr, MutableMetaProvider, Configurable { /** @@ -187,7 +187,7 @@ public open class SchemeSpec( it.initialize(MutableMeta(), it.target, descriptor) } - override fun convert(obj: T): Meta = obj.meta + override fun convert(obj: T): Meta = obj.meta /** * A convenience method to use specifications in builders @@ -197,7 +197,6 @@ public open class SchemeSpec( } - /** * Update a [MutableMeta] using given specification */ @@ -275,7 +274,7 @@ public fun MutableMeta.listOfScheme( ): ReadWriteProperty> = object : ReadWriteProperty> { override fun getValue(thisRef: Any?, property: KProperty<*>): List { val name = key ?: property.name.asName() - return getIndexed(name).values.map { spec.write(it as MutableMeta) } + return getIndexedList(name).map { spec.write(it as MutableMeta) } } override fun setValue(thisRef: Any?, property: KProperty<*>, value: List) { diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/names/NameIndexComparator.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/names/NameIndexComparator.kt new file mode 100644 index 00000000..742f8ebb --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/names/NameIndexComparator.kt @@ -0,0 +1,30 @@ +package space.kscience.dataforge.names + +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.getIndexed + + +/** + * A comparator for indices in a [Name]. If both indices are integers, compare them as integers. + * Null always stays "before" non-null index. + */ +public object NameIndexComparator : Comparator { + override fun compare(a: String?, b: String?): Int { + if (a == b) return 0 + if (a == null) return 1 + if (b == null) return -1 + val aInt = a.toIntOrNull() + val bInt = b.toIntOrNull() + return if (aInt != null && bInt != null) { + aInt.compareTo(bInt) + } else { + a.compareTo(b) + } + } + +} + +public fun Meta.getIndexedList(name: Name): List = getIndexed(name).entries.sortedWith( + //sort by index + compareBy(space.kscience.dataforge.names.NameIndexComparator) { it.key } +).map{it.value} \ No newline at end of file diff --git a/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/ObservableMetaTest.kt b/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/ObservableMetaTest.kt index 2d6cc36f..4681ec12 100644 --- a/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/ObservableMetaTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/ObservableMetaTest.kt @@ -17,8 +17,6 @@ class ObservableMetaTest { } }.asObservable() - println(meta) - assertEquals("scatter", meta["data.type"].string) }