Fix naming conventions in names

This commit is contained in:
Alexander Nozik 2023-01-08 11:03:58 +03:00
parent 4117a05df4
commit e41fdfc086
Signed by: altavir
GPG Key ID: B10A55DCC7B9AEBB
16 changed files with 72 additions and 33 deletions

View File

@ -26,6 +26,7 @@
- Separate interfaces for `IOReader` and `IOWriter` - Separate interfaces for `IOReader` and `IOWriter`
### Deprecated ### Deprecated
- Context.fetch -> Context.request
### Removed ### Removed

View File

@ -11,6 +11,8 @@ public abstract class AbstractPlugin(override val meta: Meta = Meta.EMPTY) : Plu
private var _context: Context? = null private var _context: Context? = null
private val dependencies = HashMap<PluginFactory<*>, Meta>() private val dependencies = HashMap<PluginFactory<*>, Meta>()
override val isAttached: Boolean = _context != null
override val context: Context override val context: Context
get() = _context ?: error("Plugin $tag is not attached") get() = _context ?: error("Plugin $tag is not attached")
@ -27,7 +29,10 @@ public abstract class AbstractPlugin(override val meta: Meta = Meta.EMPTY) : Plu
/** /**
* Register plugin dependency and return a delegate which provides lazily initialized reference to dependent plugin * Register plugin dependency and return a delegate which provides lazily initialized reference to dependent plugin
*/ */
protected fun <P : Plugin> require(factory: PluginFactory<P>, meta: Meta = Meta.EMPTY): ReadOnlyProperty<AbstractPlugin, P> { protected fun <P : Plugin> require(
factory: PluginFactory<P>,
meta: Meta = Meta.EMPTY,
): ReadOnlyProperty<AbstractPlugin, P> {
dependencies[factory] = meta dependencies[factory] = meta
return PluginDependencyDelegate(factory.type) return PluginDependencyDelegate(factory.type)
} }
@ -37,6 +42,7 @@ public fun <T : Named> Collection<T>.toMap(): Map<Name, T> = associate { it.name
private class PluginDependencyDelegate<P : Plugin>(val type: KClass<out P>) : ReadOnlyProperty<AbstractPlugin, P> { private class PluginDependencyDelegate<P : Plugin>(val type: KClass<out P>) : ReadOnlyProperty<AbstractPlugin, P> {
override fun getValue(thisRef: AbstractPlugin, property: KProperty<*>): P { override fun getValue(thisRef: AbstractPlugin, property: KProperty<*>): P {
if (!thisRef.isAttached) error("Plugin dependency must not be called eagerly during initialization.")
return thisRef.context.plugins[type] ?: error("Plugin with type $type not found") return thisRef.context.plugins[type] ?: error("Plugin with type $type not found")
} }
} }

View File

@ -53,6 +53,8 @@ public interface Plugin : Named, ContextAware, Provider, MetaRepr {
*/ */
public fun detach() public fun detach()
public val isAttached: Boolean
override fun toMeta(): Meta = Meta { override fun toMeta(): Meta = Meta {
"context" put context.name.toString() "context" put context.name.toString()
"type" to this::class.simpleName "type" to this::class.simpleName

View File

@ -13,7 +13,7 @@ import kotlin.reflect.KClass
*/ */
public class PluginManager internal constructor( public class PluginManager internal constructor(
override val context: Context, override val context: Context,
private val plugins: Set<Plugin> private val plugins: Set<Plugin>,
) : ContextAware, Iterable<Plugin> { ) : ContextAware, Iterable<Plugin> {
init { init {
@ -81,12 +81,16 @@ public class PluginManager internal constructor(
* Fetch a plugin with given meta from the context. If the plugin (with given meta) is already registered, it is returned. * Fetch a plugin with given meta from the context. If the plugin (with given meta) is already registered, it is returned.
* Otherwise, new child context with the plugin is created. In the later case the context could be retrieved from the plugin. * Otherwise, new child context with the plugin is created. In the later case the context could be retrieved from the plugin.
*/ */
public inline fun <reified T : Plugin> Context.fetch(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T { public inline fun <reified T : Plugin> Context.request(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T {
val existing = plugins[factory] val existing = plugins[factory]
return if (existing != null && existing.meta == meta) existing return if (existing != null && existing.meta == meta) existing
else { else {
buildContext(name = this@fetch.name + factory.tag.name) { buildContext(name = this@request.name + factory.tag.name) {
plugin(factory, meta) plugin(factory, meta)
}.plugins[factory]!! }.plugins[factory]!!
} }
} }
@Deprecated("Replace with request", ReplaceWith("request(factory, meta)"))
public inline fun <reified T : Plugin> Context.fetch(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T =
request(factory, meta)

View File

@ -1,7 +1,7 @@
package space.kscience.dataforge.context package space.kscience.dataforge.context
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.appendLeft import space.kscience.dataforge.names.appendFirst
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -26,7 +26,7 @@ class ContextTest {
val members = context.gather<Name>("test") val members = context.gather<Name>("test")
assertEquals(3, members.count()) assertEquals(3, members.count())
members.forEach { members.forEach {
assertEquals(it.key, it.value.appendLeft("test")) assertEquals(it.key, it.value.appendFirst("test"))
} }
} }

View File

@ -73,7 +73,7 @@ private class LazyData<T : Any>(
override val type: KType, override val type: KType,
override val meta: Meta = Meta.EMPTY, override val meta: Meta = Meta.EMPTY,
additionalContext: CoroutineContext = EmptyCoroutineContext, additionalContext: CoroutineContext = EmptyCoroutineContext,
dependencies: Collection<Data<*>> = emptyList(), dependencies: Collection<Goal<*>> = emptyList(),
block: suspend () -> T, block: suspend () -> T,
) : Data<T>, LazyGoal<T>(additionalContext, dependencies, block) ) : Data<T>, LazyGoal<T>(additionalContext, dependencies, block)
@ -93,7 +93,7 @@ public fun <T : Any> Data(
type: KType, type: KType,
meta: Meta = Meta.EMPTY, meta: Meta = Meta.EMPTY,
context: CoroutineContext = EmptyCoroutineContext, context: CoroutineContext = EmptyCoroutineContext,
dependencies: Collection<Data<*>> = emptyList(), dependencies: Collection<Goal<*>> = emptyList(),
block: suspend () -> T, block: suspend () -> T,
): Data<T> = LazyData(type, meta, context, dependencies, block) ): Data<T> = LazyData(type, meta, context, dependencies, block)
@ -102,6 +102,6 @@ public fun <T : Any> Data(
public inline fun <reified T : Any> Data( public inline fun <reified T : Any> Data(
meta: Meta = Meta.EMPTY, meta: Meta = Meta.EMPTY,
context: CoroutineContext = EmptyCoroutineContext, context: CoroutineContext = EmptyCoroutineContext,
dependencies: Collection<Data<*>> = emptyList(), dependencies: Collection<Goal<*>> = emptyList(),
noinline block: suspend () -> T, noinline block: suspend () -> T,
): Data<T> = Data(typeOf<T>(), meta, context, dependencies, block) ): Data<T> = Data(typeOf<T>(), meta, context, dependencies, block)

View File

@ -67,7 +67,7 @@ public fun <T : Any> DataSet<T>.withNamePrefix(prefix: Name): DataSet<T> = if (p
} }
override fun get(name: Name): Data<T>? = override fun get(name: Name): Data<T>? =
name.removeHeadOrNull(name)?.let { this@withNamePrefix.get(it) } name.removeFirstOrNull(name)?.let { this@withNamePrefix.get(it) }
override val updates: Flow<Name> get() = this@withNamePrefix.updates.map { prefix + it } override val updates: Flow<Name> get() = this@withNamePrefix.updates.map { prefix + it }
} }
@ -87,7 +87,7 @@ public fun <T : Any> DataSet<T>.branch(branchName: Name): DataSet<T> = if (branc
override fun iterator(): Iterator<NamedData<T>> = iterator { override fun iterator(): Iterator<NamedData<T>> = iterator {
for (d in this@branch) { for (d in this@branch) {
d.name.removeHeadOrNull(branchName)?.let { name -> d.name.removeFirstOrNull(branchName)?.let { name ->
yield(d.data.named(name)) yield(d.data.named(name))
} }
} }
@ -95,7 +95,7 @@ public fun <T : Any> DataSet<T>.branch(branchName: Name): DataSet<T> = if (branc
override fun get(name: Name): Data<T>? = this@branch.get(branchName + name) override fun get(name: Name): Data<T>? = this@branch.get(branchName + name)
override val updates: Flow<Name> get() = this@branch.updates.mapNotNull { it.removeHeadOrNull(branchName) } override val updates: Flow<Name> get() = this@branch.updates.mapNotNull { it.removeFirstOrNull(branchName) }
} }
public fun <T : Any> DataSet<T>.branch(branchName: String): DataSet<T> = this@branch.branch(branchName.parseAsName()) public fun <T : Any> DataSet<T>.branch(branchName: String): DataSet<T> = this@branch.branch(branchName.parseAsName())

View File

@ -36,6 +36,8 @@ public interface Envelope {
public class SimpleEnvelope(override val meta: Meta, override val data: Binary?) : Envelope public class SimpleEnvelope(override val meta: Meta, override val data: Binary?) : Envelope
public fun Envelope(meta: Meta, data: Binary?): Envelope = SimpleEnvelope(meta, data)
/** /**
* The purpose of the envelope * The purpose of the envelope
* *

View File

@ -7,8 +7,11 @@ import space.kscience.dataforge.io.MetaFormatFactory.Companion.META_FORMAT_TYPE
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.string import space.kscience.dataforge.meta.string
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.KType
import kotlin.reflect.typeOf
public class IOPlugin(meta: Meta) : AbstractPlugin(meta) { public class IOPlugin(meta: Meta) : AbstractPlugin(meta) {
override val tag: PluginTag get() = Companion.tag override val tag: PluginTag get() = Companion.tag
@ -17,15 +20,15 @@ public class IOPlugin(meta: Meta) : AbstractPlugin(meta) {
context.gather<IOFormatFactory<*>>(IO_FORMAT_TYPE).values context.gather<IOFormatFactory<*>>(IO_FORMAT_TYPE).values
} }
public fun <T : Any> resolveIOFormat(item: Meta, type: KClass<out T>): IOFormat<T>? { @Suppress("UNCHECKED_CAST")
val key = item.string ?: item[IOFormatFactory.NAME_KEY]?.string ?: error("Format name not defined") @DFInternal
val name = Name.parse(key) public fun <T : Any> resolveIOFormat(type: KType, meta: Meta): IOFormat<T>? =
return ioFormatFactories.find { it.name == name }?.let { ioFormatFactories.singleOrNull { it.type == type }?.build(context, meta) as? IOFormat<T>
@Suppress("UNCHECKED_CAST")
if (it.type != type) error("Format type ${it.type} is not the same as requested type $type") @OptIn(DFInternal::class)
else it.build(context, item[IOFormatFactory.META_KEY] ?: Meta.EMPTY) as IOFormat<T> public inline fun <reified T : Any> resolveIOFormat(meta: Meta = Meta.EMPTY): IOFormat<T>? =
} resolveIOFormat(typeOf<T>(), meta)
}
public val metaFormatFactories: Collection<MetaFormatFactory> by lazy { public val metaFormatFactories: Collection<MetaFormatFactory> by lazy {
context.gather<MetaFormatFactory>(META_FORMAT_TYPE).values context.gather<MetaFormatFactory>(META_FORMAT_TYPE).values
@ -79,7 +82,7 @@ internal val ioContext = Context("IO") {
public val Context.io: IOPlugin public val Context.io: IOPlugin
get() = if (this == Global) { get() = if (this == Global) {
ioContext.fetch(IOPlugin) ioContext.request(IOPlugin)
} else { } else {
fetch(IOPlugin) request(IOPlugin)
} }

View File

@ -25,7 +25,7 @@ private class ObservableMetaWrapper(
listeners.add( listeners.add(
MetaListener(Pair(owner, absoluteName)) { name -> MetaListener(Pair(owner, absoluteName)) { name ->
if (name.startsWith(absoluteName)) { if (name.startsWith(absoluteName)) {
(this[absoluteName] ?: Meta.EMPTY).callback(name.removeHeadOrNull(absoluteName)!!) (this[absoluteName] ?: Meta.EMPTY).callback(name.removeFirstOrNull(absoluteName)!!)
} }
} }
) )

View File

@ -96,7 +96,7 @@ public open class Scheme : Described, MetaRepr, MutableMetaProvider, Configurabl
override fun onChange(owner: Any?, callback: Meta.(name: Name) -> Unit) { override fun onChange(owner: Any?, callback: Meta.(name: Name) -> Unit) {
listeners.add(MetaListener(owner) { changedName -> listeners.add(MetaListener(owner) { changedName ->
if (changedName.startsWith(pathName)) { if (changedName.startsWith(pathName)) {
this@Scheme.meta.callback(changedName.removeHeadOrNull(pathName)!!) this@Scheme.meta.callback(changedName.removeFirstOrNull(pathName)!!)
} }
}) })
} }

View File

@ -159,8 +159,14 @@ public operator fun Name.plus(other: String): Name = this + Name.parse(other)
public operator fun Name.plus(other: NameToken): Name = Name(tokens + other) public operator fun Name.plus(other: NameToken): Name = Name(tokens + other)
@Deprecated(
"Use appendFirst instead",
ReplaceWith("appendFirst(other)")
)
public fun Name.appendLeft(other: String): Name = NameToken(other) + this public fun Name.appendLeft(other: String): Name = NameToken(other) + this
public fun Name.appendFirst(other: String): Name = NameToken(other) + this
public fun NameToken.asName(): Name = Name(listOf(this)) public fun NameToken.asName(): Name = Name(listOf(this))
public fun Name.isEmpty(): Boolean = this.length == 0 public fun Name.isEmpty(): Boolean = this.length == 0
@ -202,12 +208,26 @@ public fun Name.endsWith(name: Name): Boolean =
/** /**
* if [this] starts with given [head] name, returns the reminder of the name (could be empty). Otherwise, returns null * if [this] starts with given [head] name, returns the reminder of the name (could be empty). Otherwise, returns null
*/ */
@Deprecated(
"Use removeFirstOrNull instead",
ReplaceWith("removeFirstOrNull(head)")
)
public fun Name.removeHeadOrNull(head: Name): Name? = if (startsWith(head)) { public fun Name.removeHeadOrNull(head: Name): Name? = if (startsWith(head)) {
Name(tokens.subList(head.length, length)) Name(tokens.subList(head.length, length))
} else { } else {
null null
} }
/**
* if [this] starts with given [first] name, returns the reminder of the name (could be empty). Otherwise, returns null
*/
public fun Name.removeFirstOrNull(first: Name): Name? = if (startsWith(first)) {
Name(tokens.subList(first.length, length))
} else {
null
}
@ThreadLocal @ThreadLocal
private val nameCache = HashMap<String, Name>() private val nameCache = HashMap<String, Name>()

View File

@ -25,7 +25,7 @@ public interface Task<out T : Any> : Described {
/** /**
* A task identification string used to compare tasks and check task body for change * A task identification string used to compare tasks and check task body for change
*/ */
public val fingerprint: String get() = hashCode().toString() public val fingerprint: String get() = hashCode().toString(radix = 16)
/** /**
* Compute a [TaskResult] using given meta. In general, the result is lazy and represents both computation model * Compute a [TaskResult] using given meta. In general, the result is lazy and represents both computation model

View File

@ -42,6 +42,6 @@ private class TaskDataImpl<out T : Any>(
// } // }
} }
public fun <T : Any> Workspace.wrapData(data: Data<T>, name: Name, taskName: Name, stageMeta: Meta): TaskData<T> = public fun <T : Any> Workspace.wrapData(data: Data<T>, name: Name, taskName: Name, taskMeta: Meta): TaskData<T> =
TaskDataImpl(this, data, name, taskName, stageMeta) TaskDataImpl(this, data, name, taskName, taskMeta)

View File

@ -25,14 +25,15 @@ public interface TaskResult<out T : Any> : DataSet<T> {
public val taskMeta: Meta public val taskMeta: Meta
override fun iterator(): Iterator<TaskData<T>> override fun iterator(): Iterator<TaskData<T>>
override fun get(name: Name): TaskData<T>? override fun get(name: Name): TaskData<T>?
} }
private class TaskResultImpl<out T : Any>( private class TaskResultImpl<out T : Any>(
override val workspace: Workspace, override val workspace: Workspace,
val dataSet: DataSet<T>,
override val taskName: Name, override val taskName: Name,
override val taskMeta: Meta, override val taskMeta: Meta,
val dataSet: DataSet<T>,
) : TaskResult<T>, DataSet<T> by dataSet { ) : TaskResult<T>, DataSet<T> by dataSet {
override fun iterator(): Iterator<TaskData<T>> = iterator { override fun iterator(): Iterator<TaskData<T>> = iterator {
@ -41,7 +42,7 @@ private class TaskResultImpl<out T : Any>(
} }
} }
override fun get(name: Name): TaskData<T>? = dataSet.get(name)?.let { override fun get(name: Name): TaskData<T>? = dataSet[name]?.let {
workspace.wrapData(it, name, taskName, taskMeta) workspace.wrapData(it, name, taskName, taskMeta)
} }
} }
@ -50,4 +51,4 @@ private class TaskResultImpl<out T : Any>(
* Wrap data into [TaskResult] * Wrap data into [TaskResult]
*/ */
public fun <T : Any> Workspace.wrapResult(dataSet: DataSet<T>, taskName: Name, taskMeta: Meta): TaskResult<T> = public fun <T : Any> Workspace.wrapResult(dataSet: DataSet<T>, taskName: Name, taskMeta: Meta): TaskResult<T> =
TaskResultImpl(this, dataSet, taskName, taskMeta) TaskResultImpl(this, taskName, taskMeta, dataSet)

View File

@ -5,4 +5,4 @@ kotlin.code.style=official
kotlin.mpp.stability.nowarn=true kotlin.mpp.stability.nowarn=true
kotlin.incremental.js.ir=true kotlin.incremental.js.ir=true
toolsVersion=0.13.0-kotlin-1.7.20-Beta toolsVersion=0.13.3-kotlin-1.7.20