Add ordering to name indices

This commit is contained in:
Alexander Nozik 2024-02-06 14:36:20 +03:00
parent 0e5a31db9f
commit 4197b4bb61
7 changed files with 40 additions and 9 deletions

View File

@ -3,6 +3,7 @@
## Unreleased ## Unreleased
### Added ### Added
- Name index comparator
### Changed ### Changed
@ -11,6 +12,7 @@
### Removed ### Removed
### Fixed ### Fixed
- `listOfScheme` and `listOfConvertable` delegates provides correct items order
### Security ### Security

View File

@ -8,7 +8,7 @@ plugins {
allprojects { allprojects {
group = "space.kscience" group = "space.kscience"
version = "0.8.0" version = "0.8.1-dev-1"
} }
subprojects { subprojects {

View File

@ -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.io.PartDescriptor.Companion.SEPARATOR_KEY
import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.*
import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.getIndexedList
import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.plus
private class PartDescriptor : Scheme() { private class PartDescriptor : Scheme() {
@ -84,7 +85,7 @@ public fun EnvelopeBuilder.envelopes(
public fun Envelope.parts(): EnvelopeParts { public fun Envelope.parts(): EnvelopeParts {
if (data == null) return emptyList() if (data == null) return emptyList()
//TODO add zip folder reader //TODO add zip folder reader
val parts = meta.getIndexed(PARTS_KEY).values.map { val parts = meta.getIndexedList(PARTS_KEY).map {
PartDescriptor.read(it) PartDescriptor.read(it)
} }
return if (parts.isEmpty()) { return if (parts.isEmpty()) {

View File

@ -4,6 +4,7 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.getIndexedList
import kotlin.properties.ReadWriteProperty import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
@ -65,7 +66,7 @@ public fun <T> MutableMeta.listOfConvertable(
): ReadWriteProperty<Any?, List<T>> = object : ReadWriteProperty<Any?, List<T>> { ): ReadWriteProperty<Any?, List<T>> = object : ReadWriteProperty<Any?, List<T>> {
override fun getValue(thisRef: Any?, property: KProperty<*>): List<T> { override fun getValue(thisRef: Any?, property: KProperty<*>): List<T> {
val name = key ?: property.name.asName() 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<T>) { override fun setValue(thisRef: Any?, property: KProperty<*>, value: List<T>) {

View File

@ -18,7 +18,7 @@ import kotlin.reflect.KProperty1
*/ */
public open class Scheme( public open class Scheme(
private var prototype: Meta? = null, private var prototype: Meta? = null,
descriptor: MetaDescriptor? = null descriptor: MetaDescriptor? = null,
) : Described, MetaRepr, MutableMetaProvider, Configurable { ) : Described, MetaRepr, MutableMetaProvider, Configurable {
/** /**
@ -187,7 +187,7 @@ public open class SchemeSpec<T : Scheme>(
it.initialize(MutableMeta(), it.target, descriptor) 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 * A convenience method to use specifications in builders
@ -197,7 +197,6 @@ public open class SchemeSpec<T : Scheme>(
} }
/** /**
* Update a [MutableMeta] using given specification * Update a [MutableMeta] using given specification
*/ */
@ -275,7 +274,7 @@ public fun <T : Scheme> MutableMeta.listOfScheme(
): ReadWriteProperty<Any?, List<T>> = object : ReadWriteProperty<Any?, List<T>> { ): ReadWriteProperty<Any?, List<T>> = object : ReadWriteProperty<Any?, List<T>> {
override fun getValue(thisRef: Any?, property: KProperty<*>): List<T> { override fun getValue(thisRef: Any?, property: KProperty<*>): List<T> {
val name = key ?: property.name.asName() 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<T>) { override fun setValue(thisRef: Any?, property: KProperty<*>, value: List<T>) {

View File

@ -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<String?> {
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<Meta> = getIndexed(name).entries.sortedWith(
//sort by index
compareBy(space.kscience.dataforge.names.NameIndexComparator) { it.key }
).map{it.value}

View File

@ -17,8 +17,6 @@ class ObservableMetaTest {
} }
}.asObservable() }.asObservable()
println(meta)
assertEquals("scatter", meta["data.type"].string) assertEquals("scatter", meta["data.type"].string)
} }