Tables refactor to KType
This commit is contained in:
parent
cf0c934acf
commit
488cd5a939
@ -4,6 +4,7 @@
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
- Kotlin-logging moved from common to JVM and JS. Replaced by console for native.
|
||||
|
||||
### Deprecated
|
||||
|
||||
|
@ -1,20 +1,20 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.project")
|
||||
id("ru.mipt.npm.gradle.project")
|
||||
}
|
||||
|
||||
val dataforgeVersion by extra("0.3.0")
|
||||
|
||||
|
||||
|
||||
allprojects {
|
||||
group = "hep.dataforge"
|
||||
version = dataforgeVersion
|
||||
version = "0.3.1"
|
||||
|
||||
apply<org.jetbrains.dokka.gradle.DokkaPlugin>()
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply(plugin = "ru.mipt.npm.publish")
|
||||
apply(plugin = "ru.mipt.npm.gradle.publish")
|
||||
repositories{
|
||||
maven("https://dl.bintray.com/mipt-npm/kscience")
|
||||
maven("https://dl.bintray.com/mipt-npm/dev")
|
||||
}
|
||||
}
|
||||
|
||||
readme {
|
||||
|
@ -95,6 +95,10 @@ public final class hep/dataforge/context/Global : hep/dataforge/context/Context
|
||||
public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/context/LoggingJvmKt {
|
||||
public static final fun buildLogger (Lhep/dataforge/context/Context;Ljava/lang/String;)Lmu/KLogger;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/context/LoggingKt {
|
||||
public static final fun getLogger (Lhep/dataforge/context/Context;)Lmu/KLogger;
|
||||
public static final fun getLogger (Lhep/dataforge/context/ContextAware;)Lmu/KLogger;
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.mpp")
|
||||
id("ru.mipt.npm.native")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
description = "Context and provider definitions"
|
||||
@ -11,22 +11,33 @@ kscience {
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
val commonMain by getting{
|
||||
dependencies {
|
||||
api(project(":dataforge-meta"))
|
||||
api("io.github.microutils:kotlin-logging:1.9.0-dev-npm-2")
|
||||
}
|
||||
}
|
||||
val jvmMain by getting {
|
||||
jvmMain {
|
||||
dependencies {
|
||||
api(kotlin("reflect"))
|
||||
api("ch.qos.logback:logback-classic:1.2.3")
|
||||
api("io.github.microutils:kotlin-logging-jvm:2.0.4")
|
||||
implementation("ch.qos.logback:logback-classic:1.2.3")
|
||||
}
|
||||
}
|
||||
val jsMain by getting {
|
||||
jsMain {
|
||||
dependencies {
|
||||
api("io.github.microutils:kotlin-logging-js:2.0.4")
|
||||
}
|
||||
}
|
||||
//
|
||||
// val nativeMain by getting{
|
||||
// dependsOn(commonMain)
|
||||
// }
|
||||
// val mingwX64Main by getting{
|
||||
// dependsOn(nativeMain)
|
||||
// }
|
||||
// val linuxX64Main by getting{
|
||||
// dependsOn(nativeMain)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.mpp")
|
||||
id("ru.mipt.npm.native")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kscience{
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.mpp")
|
||||
id("ru.mipt.npm.native")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
description = "IO module"
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.mpp")
|
||||
// id("ru.mipt.npm.native")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
description = "YAML meta IO"
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.mpp")
|
||||
id("ru.mipt.npm.native")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kscience {
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.mpp")
|
||||
id("ru.mipt.npm.native")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.mpp")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
@ -1,14 +1,16 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.mpp")
|
||||
id("ru.mipt.npm.native")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
val commonMain by getting{
|
||||
commonMain{
|
||||
dependencies {
|
||||
api(project(":dataforge-context"))
|
||||
api(project(":dataforge-io"))
|
||||
|
||||
api(kotlin("reflect"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package hep.dataforge.tables
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
|
||||
public data class ColumnDef<out T : Any>(
|
||||
override val name: String,
|
||||
override val type: KClass<out T>,
|
||||
override val type: KType,
|
||||
override val meta: Meta
|
||||
): ColumnHeader<T>
|
@ -6,7 +6,7 @@ import hep.dataforge.meta.int
|
||||
import hep.dataforge.meta.string
|
||||
import hep.dataforge.values.Value
|
||||
import hep.dataforge.values.ValueType
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
|
||||
public typealias TableHeader<C> = List<ColumnHeader<C>>
|
||||
|
||||
@ -14,13 +14,13 @@ public typealias ValueTableHeader = List<ColumnHeader<Value>>
|
||||
|
||||
public interface ColumnHeader<out T : Any> {
|
||||
public val name: String
|
||||
public val type: KClass<out T>
|
||||
public val type: KType
|
||||
public val meta: Meta
|
||||
}
|
||||
|
||||
public data class SimpleColumnHeader<T : Any>(
|
||||
override val name: String,
|
||||
override val type: KClass<out T>,
|
||||
override val type: KType,
|
||||
override val meta: Meta
|
||||
) : ColumnHeader<T>
|
||||
|
||||
|
@ -13,11 +13,11 @@ public class ColumnTable<T : Any>(override val columns: Collection<Column<T>>) :
|
||||
override val rows: List<Row<T>>
|
||||
get() = (0 until rowsNum).map { VirtualRow(this, it) }
|
||||
|
||||
override fun getValue(row: Int, column: String): T? = columns[column]?.get(row)
|
||||
override fun get(row: Int, column: String): T? = columns[column]?.get(row)
|
||||
}
|
||||
|
||||
internal class VirtualRow<T : Any>(val table: Table<T>, val index: Int) : Row<T> {
|
||||
override fun getValue(column: String): T? = table.getValue(index, column)
|
||||
override fun get(column: String): T? = table.get(index, column)
|
||||
|
||||
// override fun <T : C> get(columnHeader: ColumnHeader<T>): T? {
|
||||
// return table.co[columnHeader][index]
|
||||
|
@ -1,12 +1,13 @@
|
||||
package hep.dataforge.tables
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
public class ListColumn<T : Any>(
|
||||
override val name: String,
|
||||
private val data: List<T?>,
|
||||
override val type: KClass<out T>,
|
||||
override val type: KType,
|
||||
override val meta: Meta
|
||||
) : Column<T> {
|
||||
override val size: Int get() = data.size
|
||||
@ -18,7 +19,7 @@ public class ListColumn<T : Any>(
|
||||
name: String,
|
||||
def: ColumnScheme,
|
||||
data: List<T?>
|
||||
): ListColumn<T> = ListColumn(name, data, T::class, def.toMeta())
|
||||
): ListColumn<T> = ListColumn(name, data, typeOf<T>(), def.toMeta())
|
||||
|
||||
public inline operator fun <reified T : Any> invoke(
|
||||
name: String,
|
||||
@ -31,5 +32,5 @@ public class ListColumn<T : Any>(
|
||||
|
||||
public inline fun <T : Any, reified R : Any> Column<T>.map(meta: Meta = this.meta, noinline block: (T?) -> R): Column<R> {
|
||||
val data = List(size) { block(get(it)) }
|
||||
return ListColumn(name, data, R::class, meta)
|
||||
return ListColumn(name, data, typeOf<R>(), meta)
|
||||
}
|
@ -11,7 +11,7 @@ public class MutableColumnTable<C: Any>(public val size: Int) : Table<C> {
|
||||
VirtualRow(this, it)
|
||||
}
|
||||
|
||||
override fun getValue(row: Int, column: String): C? = columns[column]?.get(row)
|
||||
override fun get(row: Int, column: String): C? = columns[column]?.get(row)
|
||||
|
||||
/**
|
||||
* Add a fixed column to the end of the table
|
||||
|
@ -1,26 +1,35 @@
|
||||
package hep.dataforge.tables
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.invoke
|
||||
import hep.dataforge.values.Value
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.properties.PropertyDelegateProvider
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
public class MutableTable<C : Any>(
|
||||
override val rows: MutableList<Row<C>>,
|
||||
override val header: MutableList<ColumnHeader<C>>
|
||||
) : RowTable<C>(rows, header) {
|
||||
override val headers: MutableList<ColumnHeader<C>>,
|
||||
) : RowTable<C>(rows, headers) {
|
||||
|
||||
public fun <R : C> column(name: String, type: KClass<out R>, meta: Meta): ColumnHeader<R> {
|
||||
val column = SimpleColumnHeader(name, type, meta)
|
||||
header.add(column)
|
||||
@PublishedApi
|
||||
internal fun <T : C> addColumn(name: String, type: KType, meta: Meta): ColumnHeader<T> {
|
||||
val column = SimpleColumnHeader<T>(name, type, meta)
|
||||
headers.add(column)
|
||||
return column
|
||||
}
|
||||
|
||||
public inline fun <reified T : C> column(
|
||||
public inline fun <reified T : C> addColumn(
|
||||
name: String,
|
||||
noinline columnMetaBuilder: ColumnScheme.() -> Unit = {},
|
||||
): ColumnHeader<T> = addColumn(name, typeOf<T>(), ColumnScheme(columnMetaBuilder).toMeta())
|
||||
|
||||
public inline fun <reified T : C> column(
|
||||
noinline columnMetaBuilder: ColumnScheme.() -> Unit = {}
|
||||
): ColumnHeader<T> {
|
||||
return column(name, T::class, ColumnScheme(columnMetaBuilder).toMeta())
|
||||
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ColumnHeader<T>>> =
|
||||
PropertyDelegateProvider { _, property ->
|
||||
val res = addColumn<T>(property.name, columnMetaBuilder)
|
||||
ReadOnlyProperty { _, _ -> res }
|
||||
}
|
||||
|
||||
public fun row(map: Map<String, C?>): Row<C> {
|
||||
@ -37,5 +46,5 @@ public fun MutableTable<Value>.row(vararg pairs: Pair<ColumnHeader<Value>, Any?>
|
||||
row(pairs.associate { it.first.name to Value.of(it.second) })
|
||||
|
||||
public fun <C : Any> Table<C>.edit(block: MutableTable<C>.() -> Unit): Table<C> {
|
||||
return MutableTable(rows.toMutableList(), header.toMutableList()).apply(block)
|
||||
return MutableTable(rows.toMutableList(), headers.toMutableList()).apply(block)
|
||||
}
|
@ -2,25 +2,31 @@ package hep.dataforge.tables
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
|
||||
public inline class MapRow<C : Any>(private val values: Map<String, C?>) : Row<C> {
|
||||
override fun getValue(column: String): C? = values[column]
|
||||
override fun get(column: String): C? = values[column]
|
||||
}
|
||||
|
||||
internal class RowTableColumn<C : Any, T : C>(val table: Table<C>, val header: ColumnHeader<T>) : Column<T> {
|
||||
internal class RowTableColumn<T : Any, R : T>(val table: Table<T>, val header: ColumnHeader<R>) : Column<R> {
|
||||
init {
|
||||
require(header in table.headers){"Header $header does not belong to $table"}
|
||||
}
|
||||
|
||||
override val name: String get() = header.name
|
||||
override val type: KClass<out T> get() = header.type
|
||||
override val type: KType get() = header.type
|
||||
override val meta: Meta get() = header.meta
|
||||
override val size: Int get() = table.rows.size
|
||||
|
||||
override fun get(index: Int): T? = table.rows[index].getValue(name, type)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun get(index: Int): R? = table[index, name]?.let { it as R}
|
||||
}
|
||||
|
||||
public open class RowTable<C : Any>(override val rows: List<Row<C>>, override val header: List<ColumnHeader<C>>) : Table<C> {
|
||||
override fun getValue(row: Int, column: String): C? = rows[row].getValue(column)
|
||||
public open class RowTable<C : Any>(override val rows: List<Row<C>>, override val headers: List<ColumnHeader<C>>) :
|
||||
Table<C> {
|
||||
override fun get(row: Int, column: String): C? = rows[row].get(column)
|
||||
|
||||
override val columns: List<Column<C>> get() = header.map { RowTableColumn(this, it) }
|
||||
override val columns: List<Column<C>> get() = headers.map { RowTableColumn(this, it) }
|
||||
}
|
||||
|
||||
public suspend fun <C : Any> Rows<C>.collect(): Table<C> = this as? Table<C> ?: RowTable(rowFlow().toList(), header)
|
||||
public suspend fun <C : Any> Rows<C>.collect(): Table<C> = this as? Table<C> ?: RowTable(rowFlow().toList(), headers)
|
@ -2,22 +2,20 @@ package hep.dataforge.tables
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.cast
|
||||
|
||||
/**
|
||||
* Finite or infinite row set. Rows are produced in a lazy suspendable [Flow].
|
||||
* Each row must contain at least all the fields mentioned in [header].
|
||||
* Each row must contain at least all the fields mentioned in [headers].
|
||||
*/
|
||||
public interface Rows<out T : Any> {
|
||||
public val header: TableHeader<T>
|
||||
public val headers: TableHeader<T>
|
||||
public fun rowFlow(): Flow<Row<T>>
|
||||
}
|
||||
|
||||
public interface Table<out T : Any> : Rows<T> {
|
||||
public fun getValue(row: Int, column: String): T?
|
||||
public operator fun get(row: Int, column: String): T?
|
||||
public val columns: Collection<Column<T>>
|
||||
override val header: TableHeader<T> get() = columns.toList()
|
||||
override val headers: TableHeader<T> get() = columns.toList()
|
||||
public val rows: List<Row<T>>
|
||||
override fun rowFlow(): Flow<Row<T>> = rows.asFlow()
|
||||
|
||||
@ -31,16 +29,13 @@ public interface Table<out T : Any> : Rows<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public fun <C : Any, T : C> Table<C>.getValue(row: Int, column: String, type: KClass<out T>): T? =
|
||||
type.cast(getValue(row, column))
|
||||
|
||||
public operator fun <T : Any> Collection<Column<T>>.get(name: String): Column<T>? = find { it.name == name }
|
||||
|
||||
public inline operator fun <C : Any, reified T : C> Table<C>.get(row: Int, column: String): T? =
|
||||
getValue(row, column, T::class)
|
||||
|
||||
public operator fun <C : Any, T : C> Table<C>.get(row: Int, column: ColumnHeader<T>): T? =
|
||||
getValue(row, column.name, column.type)
|
||||
public inline operator fun <T : Any, reified R : T> Table<T>.get(row: Int, column: ColumnHeader<R>): R? {
|
||||
require(headers.contains(column)) { "Column $column is not in table headers" }
|
||||
return get(row, column.name) as? R
|
||||
}
|
||||
|
||||
public interface Column<out T : Any> : ColumnHeader<T> {
|
||||
public val size: Int
|
||||
@ -56,10 +51,7 @@ public operator fun <T : Any> Column<T>.iterator(): Iterator<T?> = iterator {
|
||||
}
|
||||
|
||||
public interface Row<out T : Any> {
|
||||
public fun getValue(column: String): T?
|
||||
public operator fun get(column: String): T?
|
||||
}
|
||||
|
||||
public fun <C : Any, T : C> Row<C>.getValue(column: String, type: KClass<out T>): T? = type.cast(getValue(column))
|
||||
|
||||
public inline operator fun <reified T : Any> Row<T>.get(column: String): T? = T::class.cast(getValue(column))
|
||||
public operator fun <C : Any, T : C> Row<C>.get(column: ColumnHeader<T>): T? = getValue(column.name, column.type)
|
||||
public inline operator fun <T : Any, reified R : T> Row<T>.get(column: ColumnHeader<R>): R? = get(column.name) as? R
|
@ -1,17 +1,18 @@
|
||||
package hep.dataforge.tables
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
/**
|
||||
* A virtual column obtained by transforming Given row to a single value
|
||||
*/
|
||||
public class TransformationColumn<T : Any, R : Any>(
|
||||
public val table: Table<T>,
|
||||
override val type: KClass<out R>,
|
||||
override val type: KType,
|
||||
override val name: String,
|
||||
override val meta: Meta,
|
||||
public val mapper: (Row<T>) -> R?
|
||||
public val mapper: (Row<T>) -> R?,
|
||||
) : Column<R> {
|
||||
override val size: Int get() = table.rows.size
|
||||
|
||||
@ -25,10 +26,10 @@ public class TransformationColumn<T : Any, R : Any>(
|
||||
*/
|
||||
public class CachedTransformationColumn<T : Any, R : Any>(
|
||||
public val table: Table<T>,
|
||||
override val type: KClass<out R>,
|
||||
override val type: KType,
|
||||
override val name: String,
|
||||
override val meta: Meta,
|
||||
public val mapper: (Row<T>) -> R?
|
||||
public val mapper: (Row<T>) -> R?,
|
||||
) : Column<R> {
|
||||
override val size: Int get() = table.rows.size
|
||||
private val values: HashMap<Int, R?> = HashMap()
|
||||
@ -42,14 +43,18 @@ public inline fun <T : Any, reified R : Any> Table<T>.mapRows(
|
||||
name: String,
|
||||
meta: Meta = Meta.EMPTY,
|
||||
cache: Boolean = false,
|
||||
noinline mapper: (Row<T>) -> R?
|
||||
noinline mapper: (Row<T>) -> R?,
|
||||
): Column<R> = if (cache) {
|
||||
CachedTransformationColumn(this, R::class, name, meta, mapper)
|
||||
CachedTransformationColumn(this, typeOf<R>(), name, meta, mapper)
|
||||
} else {
|
||||
TransformationColumn(this, R::class, name, meta, mapper)
|
||||
TransformationColumn(this, typeOf<R>(), name, meta, mapper)
|
||||
}
|
||||
|
||||
public fun <T : Any> Table<T>.mapRowsToDouble(name: String, meta: Meta = Meta.EMPTY, block: (Row<T>) -> Double): RealColumn {
|
||||
public fun <T : Any> Table<T>.mapRowsToDouble(
|
||||
name: String,
|
||||
meta: Meta = Meta.EMPTY,
|
||||
block: (Row<T>) -> Double,
|
||||
): RealColumn {
|
||||
val data = DoubleArray(rows.size) { block(rows[it]) }
|
||||
return RealColumn(name, data, meta)
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ private fun readLine(header: ValueTableHeader, line: String): Row<Value> {
|
||||
* Finite or infinite [Rows] created from a fixed width text binary
|
||||
*/
|
||||
@ExperimentalIoApi
|
||||
public class TextRows(override val header: ValueTableHeader, private val binary: Binary) : Rows<Value> {
|
||||
public class TextRows(override val headers: ValueTableHeader, private val binary: Binary) : Rows<Value> {
|
||||
|
||||
/**
|
||||
* A flow of indexes of string start offsets ignoring empty strings
|
||||
@ -52,7 +52,7 @@ public class TextRows(override val header: ValueTableHeader, private val binary:
|
||||
flow {
|
||||
forEachUtf8Line { line ->
|
||||
if (line.isNotBlank()) {
|
||||
val row = readLine(header, line)
|
||||
val row = readLine(headers, line)
|
||||
emit(row)
|
||||
}
|
||||
}
|
||||
@ -73,25 +73,25 @@ public suspend fun TextRows.buildRowIndex(): List<Int> = indexFlow().toList()
|
||||
*/
|
||||
@ExperimentalIoApi
|
||||
public class TextTable(
|
||||
override val header: ValueTableHeader,
|
||||
override val headers: ValueTableHeader,
|
||||
private val binary: Binary,
|
||||
public val index: List<Int>
|
||||
) : Table<Value> {
|
||||
|
||||
override val columns: Collection<Column<Value>> get() = header.map { RowTableColumn(this, it) }
|
||||
override val columns: Collection<Column<Value>> get() = headers.map { RowTableColumn(this, it) }
|
||||
|
||||
override val rows: List<Row<Value>> get() = index.map { readAt(it) }
|
||||
|
||||
override fun rowFlow(): Flow<Row<Value>> = TextRows(header, binary).rowFlow()
|
||||
override fun rowFlow(): Flow<Row<Value>> = TextRows(headers, binary).rowFlow()
|
||||
|
||||
private fun readAt(offset: Int): Row<Value> {
|
||||
return binary.read(offset) {
|
||||
val line = readUtf8Line()
|
||||
return@read readLine(header, line)
|
||||
return@read readLine(headers, line)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getValue(row: Int, column: String): Value? {
|
||||
override fun get(row: Int, column: String): Value? {
|
||||
val offset = index[row]
|
||||
return readAt(offset)[column]
|
||||
}
|
||||
@ -132,11 +132,11 @@ private fun Output.writeValue(value: Value, width: Int, left: Boolean = true) {
|
||||
* Write rows without header to the output
|
||||
*/
|
||||
public suspend fun Output.writeRows(rows: Rows<Value>) {
|
||||
val widths: List<Int> = rows.header.map {
|
||||
val widths: List<Int> = rows.headers.map {
|
||||
it.textWidth
|
||||
}
|
||||
rows.rowFlow().collect { row ->
|
||||
rows.header.forEachIndexed { index, columnHeader ->
|
||||
rows.headers.forEachIndexed { index, columnHeader ->
|
||||
writeValue(row[columnHeader] ?: Null, widths[index])
|
||||
}
|
||||
writeUtf8String("\r\n")
|
||||
|
@ -10,12 +10,13 @@ import kotlinx.io.Binary
|
||||
import kotlinx.io.ByteArrayOutput
|
||||
import kotlinx.io.ExperimentalIoApi
|
||||
import kotlinx.io.asBinary
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
|
||||
@ExperimentalIoApi
|
||||
public suspend fun Table<Value>.wrap(): Envelope = Envelope {
|
||||
public suspend fun Table<Value>.toEnvelope(): Envelope = Envelope {
|
||||
meta {
|
||||
header.forEachIndexed { index, columnHeader ->
|
||||
headers.forEachIndexed { index, columnHeader ->
|
||||
set("column", index.toString(), Meta {
|
||||
"name" put columnHeader.name
|
||||
if (!columnHeader.meta.isEmpty()) {
|
||||
@ -26,9 +27,9 @@ public suspend fun Table<Value>.wrap(): Envelope = Envelope {
|
||||
}
|
||||
|
||||
type = "table.value"
|
||||
dataID = "valueTable[${this@wrap.hashCode()}]"
|
||||
dataID = "valueTable[${this@toEnvelope.hashCode()}]"
|
||||
|
||||
data = ByteArrayOutput().apply { writeRows(this@wrap) }.toByteArray().asBinary()
|
||||
data = ByteArrayOutput().apply { writeRows(this@toEnvelope) }.toByteArray().asBinary()
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
@ -37,7 +38,7 @@ public fun TextRows.Companion.readEnvelope(envelope: Envelope): TextRows {
|
||||
val header = envelope.meta.getIndexed("column")
|
||||
.entries.sortedBy { it.key?.toInt() }
|
||||
.map { (_, item) ->
|
||||
SimpleColumnHeader(item.node["name"].string!!, Value::class, item.node["meta"].node ?: Meta.EMPTY)
|
||||
SimpleColumnHeader<Value>(item.node["name"].string!!, typeOf<Value>(), item.node["meta"].node ?: Meta.EMPTY)
|
||||
}
|
||||
return TextRows(header, envelope.data ?: Binary.EMPTY)
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package hep.dataforge.tables
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.invoke
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
|
||||
public class RealColumn(
|
||||
@ -10,7 +10,7 @@ public class RealColumn(
|
||||
public val data: DoubleArray,
|
||||
override val meta: Meta = Meta.EMPTY
|
||||
) : Column<Double> {
|
||||
override val type: KClass<out Double> get() = Double::class
|
||||
override val type: KType get() = typeOf<Double>()
|
||||
|
||||
override val size: Int get() = data.size
|
||||
|
||||
@ -49,7 +49,7 @@ public class IntColumn(
|
||||
public val data: IntArray,
|
||||
override val meta: Meta = Meta.EMPTY
|
||||
) : Column<Int> {
|
||||
override val type: KClass<out Int> get() = Int::class
|
||||
override val type: KType get() = typeOf<Int>()
|
||||
|
||||
override val size: Int get() = data.size
|
||||
|
||||
|
@ -2,30 +2,31 @@ package hep.dataforge.tables
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.full.isSubclassOf
|
||||
import kotlin.reflect.safeCast
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.full.isSubtypeOf
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public fun <T : Any> Column<*>.cast(type: KClass<out T>): Column<T> {
|
||||
return if (type.isSubclassOf(this.type)) {
|
||||
public fun <T : Any> Column<*>.cast(type: KType): Column<T> {
|
||||
return if (type.isSubtypeOf(this.type)) {
|
||||
this as Column<T>
|
||||
} else {
|
||||
CastColumn(this, type)
|
||||
}
|
||||
}
|
||||
|
||||
public class CastColumn<T : Any>(private val origin: Column<*>, override val type: KClass<out T>) : Column<T> {
|
||||
private class CastColumn<T : Any>(private val origin: Column<*>, override val type: KType) : Column<T> {
|
||||
override val name: String get() = origin.name
|
||||
override val meta: Meta get() = origin.meta
|
||||
override val size: Int get() = origin.size
|
||||
|
||||
|
||||
override fun get(index: Int): T? = type.safeCast(origin[index])
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun get(index: Int): T? = origin[index]?.let {
|
||||
it as T
|
||||
}
|
||||
}
|
||||
|
||||
public class ColumnProperty<C: Any, T : C>(public val table: Table<C>, public val type: KClass<T>) : ReadOnlyProperty<Any?, Column<T>> {
|
||||
public class ColumnProperty<C: Any, T : C>(public val table: Table<C>, public val type: KType) : ReadOnlyProperty<Any?, Column<T>> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Column<T> {
|
||||
val name = property.name
|
||||
return (table.columns[name] ?: error("Column with name $name not found in the table")).cast(type)
|
||||
|
@ -2,7 +2,6 @@ package hep.dataforge.tables.io
|
||||
|
||||
import hep.dataforge.misc.DFExperimental
|
||||
import hep.dataforge.tables.Table
|
||||
import hep.dataforge.tables.get
|
||||
import hep.dataforge.tables.row
|
||||
import hep.dataforge.values.Value
|
||||
import hep.dataforge.values.int
|
||||
@ -19,16 +18,15 @@ import kotlin.test.assertEquals
|
||||
@ExperimentalIoApi
|
||||
class TextRowsTest {
|
||||
val table = Table<Value> {
|
||||
val a = column<Value>("a")
|
||||
val b = column<Value>("b")
|
||||
val a by column<Value>()
|
||||
val b by column<Value>()
|
||||
row(a to 1, b to "b1")
|
||||
row(a to 2, b to "b2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTableWriteRead() {
|
||||
runBlocking {
|
||||
val envelope = table.wrap()
|
||||
fun testTableWriteRead() = runBlocking {
|
||||
val envelope = table.toEnvelope()
|
||||
val string = envelope.data!!.toByteArray().decodeToString()
|
||||
println(string)
|
||||
val table = TextRows.readEnvelope(envelope)
|
||||
@ -36,5 +34,4 @@ class TextRowsTest {
|
||||
assertEquals(1, rows[0]["a"]?.int)
|
||||
assertEquals("b2", rows[1]["b"]?.string)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.mpp")
|
||||
id("ru.mipt.npm.native")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
@ -1,9 +1,11 @@
|
||||
kotlin.code.style=official
|
||||
kotlin.parallel.tasks.in.project=true
|
||||
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||
//kotlin.native.enableDependencyPropagation=false
|
||||
kotlin.mpp.stability.nowarn=true
|
||||
|
||||
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
|
||||
org.gradle.parallel=true
|
||||
systemProp.org.gradle.internal.publish.checksums.insecure=true
|
||||
|
||||
kotlin.code.style=official
|
||||
kotlin.parallel.tasks.in.project=true
|
||||
|
||||
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||
kotlin.native.enableDependencyPropagation=false
|
||||
kotlin.mpp.stability.nowarn=true
|
||||
|
||||
bintrayPublish=true
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -1,6 +1,6 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven("https://repo.kotlin.link")
|
||||
jcenter()
|
||||
gradlePluginPortal()
|
||||
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||
@ -10,15 +10,15 @@ pluginManagement {
|
||||
maven("https://dl.bintray.com/mipt-npm/dev")
|
||||
}
|
||||
|
||||
val toolsVersion = "0.7.6"
|
||||
val toolsVersion = "0.8.3"
|
||||
val kotlinVersion = "1.4.30"
|
||||
|
||||
plugins {
|
||||
id("ru.mipt.npm.project") version toolsVersion
|
||||
id("ru.mipt.npm.mpp") version toolsVersion
|
||||
id("ru.mipt.npm.jvm") version toolsVersion
|
||||
id("ru.mipt.npm.js") version toolsVersion
|
||||
id("ru.mipt.npm.publish") version toolsVersion
|
||||
id("ru.mipt.npm.gradle.project") version toolsVersion
|
||||
id("ru.mipt.npm.gradle.mpp") version toolsVersion
|
||||
id("ru.mipt.npm.gradle.jvm") version toolsVersion
|
||||
id("ru.mipt.npm.gradle.js") version toolsVersion
|
||||
id("ru.mipt.npm.gradle.publish") version toolsVersion
|
||||
kotlin("jvm") version kotlinVersion
|
||||
kotlin("js") version kotlinVersion
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user