diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregator.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregator.kt index 87efe88790..ef41bc0c75 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregator.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregator.kt @@ -8,6 +8,7 @@ import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.inputHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.FlatteningMultipleColumnsHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.NoMultipleColumnsHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.TwoStepMultipleColumnsHandler +import org.jetbrains.kotlinx.dataframe.impl.columns.ParameterValue import kotlin.reflect.KType import kotlin.reflect.full.withNullability @@ -51,6 +52,7 @@ public class Aggregator( public val inputHandler: AggregatorInputHandler, public val multipleColumnsHandler: AggregatorMultipleColumnsHandler, public val name: String, + public val statisticsParameters: Map, ) : AggregatorInputHandler by inputHandler, AggregatorMultipleColumnsHandler by multipleColumnsHandler, AggregatorAggregationHandler by aggregationHandler { @@ -84,6 +86,7 @@ public class Aggregator( aggregationHandler: AggregatorAggregationHandler, inputHandler: AggregatorInputHandler, multipleColumnsHandler: AggregatorMultipleColumnsHandler, + statisticsParameters: Map, ): AggregatorProvider = AggregatorProvider { name -> Aggregator( @@ -91,6 +94,23 @@ public class Aggregator( inputHandler = inputHandler, multipleColumnsHandler = multipleColumnsHandler, name = name, + statisticsParameters = statisticsParameters, + ) + } + + // fictitious, I want the program to compile + internal operator fun invoke( + aggregationHandler: AggregatorAggregationHandler, + inputHandler: AggregatorInputHandler, + multipleColumnsHandler: AggregatorMultipleColumnsHandler, + ): AggregatorProvider = + AggregatorProvider { name -> + Aggregator( + aggregationHandler = aggregationHandler, + inputHandler = inputHandler, + multipleColumnsHandler = multipleColumnsHandler, + name = name, + emptyMap(), ) } } diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/AggregatorAggregationHandler.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/AggregatorAggregationHandler.kt index 7b1b0357eb..da574b3a46 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/AggregatorAggregationHandler.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/AggregatorAggregationHandler.kt @@ -3,6 +3,9 @@ package org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators import org.jetbrains.kotlinx.dataframe.DataColumn import org.jetbrains.kotlinx.dataframe.api.asSequence import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.aggregationHandlers.SelectingAggregationHandler +import org.jetbrains.kotlinx.dataframe.impl.columns.ParameterValue +import org.jetbrains.kotlinx.dataframe.impl.columns.StatisticResult +import org.jetbrains.kotlinx.dataframe.impl.columns.ValueColumnInternal import kotlin.reflect.KType /** @@ -26,13 +29,37 @@ public interface AggregatorAggregationHandler /** * Aggregates the data in the given column and computes a single resulting value. - * Calls [aggregateSequence]. + * Calls [aggregateSequence]. It tries to exploit a cache for statistics which is proper of + * [ValueColumnInternal] */ - public fun aggregateSingleColumn(column: DataColumn): Return = - aggregateSequence( + public fun aggregateSingleColumn(column: DataColumn): Return { + if (column is ValueColumnInternal<*>) { + println("ValueColumnInternal") + // cache check, cache is dynamically created + val aggregator = this.aggregator ?: throw IllegalStateException("Aggregator is required") + val desiredStatisticNotConsideringParameters = column.statistics.getOrPut(aggregator.name) { + mutableMapOf, StatisticResult>() + } + // can't compare maps whose Values are Any? -> ParameterValue instead + val desiredStatistic = desiredStatisticNotConsideringParameters[aggregator.statisticsParameters] + // if desiredStatistic is null, statistic was never calculated + if (desiredStatistic != null) { + println("cache hit") + return desiredStatistic.value as Return + } + println("cache miss") + val statistic = aggregateSequence( + values = column.asSequence(), + valueType = column.type().toValueType(), + ) + desiredStatisticNotConsideringParameters.put(aggregator.statisticsParameters, StatisticResult(statistic)) + return aggregateSingleColumn(column) + } + return aggregateSequence( values = column.asSequence(), valueType = column.type().toValueType(), ) + } /** * Function that can give the return type of [aggregateSequence] as [KType], given the type of the input. diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregators.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregators.kt index 6ab45bbe73..faceba349a 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregators.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregators.kt @@ -8,6 +8,7 @@ import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.inputHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.inputHandlers.NumberInputHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.FlatteningMultipleColumnsHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.TwoStepMultipleColumnsHandler +import org.jetbrains.kotlinx.dataframe.impl.columns.ParameterValue import org.jetbrains.kotlinx.dataframe.math.indexOfMax import org.jetbrains.kotlinx.dataframe.math.indexOfMedian import org.jetbrains.kotlinx.dataframe.math.indexOfMin @@ -35,10 +36,12 @@ public object Aggregators { getReturnType: CalculateReturnType, indexOfResult: IndexOfResult, stepOneSelector: Selector, + statisticsParameters: Map, ) = Aggregator( aggregationHandler = SelectingAggregationHandler(stepOneSelector, indexOfResult, getReturnType), inputHandler = AnyInputHandler(), multipleColumnsHandler = TwoStepMultipleColumnsHandler(), + statisticsParameters = statisticsParameters, ) private fun flattenHybridForAny( @@ -123,8 +126,9 @@ public object Aggregators { by withOneOption { skipNaN: Boolean -> twoStepSelectingForAny, Comparable?>( getReturnType = minTypeConversion, - stepOneSelector = { type -> minOrNull(type, skipNaN) }, indexOfResult = { type -> indexOfMin(type, skipNaN) }, + stepOneSelector = { type -> minOrNull(type, skipNaN) }, + statisticsParameters = mapOf(Pair("skipNaN", ParameterValue(skipNaN))), ) } @@ -134,10 +138,13 @@ public object Aggregators { public val max: AggregatorOptionSwitch1, Comparable?> by withOneOption { skipNaN: Boolean -> + // the following function is 'getAggregator' of AggregatorOptionSwitch + // this is the fun that works with the parameter! twoStepSelectingForAny, Comparable?>( getReturnType = maxTypeConversion, stepOneSelector = { type -> maxOrNull(type, skipNaN) }, indexOfResult = { type -> indexOfMax(type, skipNaN) }, + statisticsParameters = mapOf(Pair("skipNaN", ParameterValue(skipNaN))), ) } diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/ValueColumnImpl.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/ValueColumnImpl.kt index f758360d1f..27d1c2add9 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/ValueColumnImpl.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/ValueColumnImpl.kt @@ -8,6 +8,43 @@ import org.jetbrains.kotlinx.dataframe.columns.ValueColumn import kotlin.reflect.KType import kotlin.reflect.full.withNullability +@JvmInline +public value class StatisticResult(public val value: Any?) + +public class ParameterValue(public val parameter: Any?) { + + override fun equals(other: Any?): Boolean { + if (parameter is Boolean && other is Boolean) { + return this.parameter == other + } + if (parameter is Int && other is Int) { + return this.parameter == other + } + if (parameter is Double && other is Double) { + return this.parameter == other + } + return super.equals(other) + } + + override fun hashCode(): Int { + if (parameter is Boolean) { + return this.parameter.hashCode() + } + if (parameter is Int) { + return this.parameter.hashCode() + } + if (parameter is Double) { + return this.parameter.hashCode() + } + return super.hashCode() + } +} + +internal interface ValueColumnInternal : ValueColumn { + // val statistics: MutableMap, WrappedStatistic>> + val statistics: MutableMap, StatisticResult>> +} + internal open class ValueColumnImpl( values: List, name: String, @@ -15,7 +52,8 @@ internal open class ValueColumnImpl( val defaultValue: T? = null, distinct: Lazy>? = null, ) : DataColumnImpl(values, name, type, distinct), - ValueColumn { + ValueColumn, + ValueColumnInternal { override fun distinct() = ValueColumnImpl(toSet().toList(), name, type, defaultValue, distinct) @@ -48,10 +86,13 @@ internal open class ValueColumnImpl( override fun defaultValue() = defaultValue override fun forceResolve() = ResolvingValueColumn(this) + + override val statistics = mutableMapOf, StatisticResult>>() } internal class ResolvingValueColumn(override val source: ValueColumn) : ValueColumn by source, + ValueColumnInternal, ForceResolvedColumn { override fun resolve(context: ColumnResolutionContext) = super.resolve(context) @@ -70,4 +111,6 @@ internal class ResolvingValueColumn(override val source: ValueColumn) : override fun equals(other: Any?) = source.checkEquals(other) override fun hashCode(): Int = source.hashCode() + + override val statistics = mutableMapOf, StatisticResult>>() } diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/statistics/max.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/statistics/max.kt index bdb532329c..c6383d3a5c 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/statistics/max.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/statistics/max.kt @@ -27,6 +27,7 @@ class MaxTests { fun `max with regular values`() { val col = columnOf(5, 2, 8, 1, 9) col.max() shouldBe 9 + col.max() shouldBe 9 } @Test diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregator.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregator.kt index a7cb2a8b14..a8cf1922ef 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregator.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregator.kt @@ -8,6 +8,7 @@ import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.inputHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.FlatteningMultipleColumnsHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.NoMultipleColumnsHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.TwoStepMultipleColumnsHandler +import org.jetbrains.kotlinx.dataframe.impl.columns.ParameterValue import kotlin.reflect.KType import kotlin.reflect.full.withNullability @@ -42,6 +43,7 @@ public class Aggregator( public val inputHandler: AggregatorInputHandler, public val multipleColumnsHandler: AggregatorMultipleColumnsHandler, public val name: String, + public val statisticsParameters: Map, ) : AggregatorInputHandler by inputHandler, AggregatorMultipleColumnsHandler by multipleColumnsHandler, AggregatorAggregationHandler by aggregationHandler { @@ -75,6 +77,7 @@ public class Aggregator( aggregationHandler: AggregatorAggregationHandler, inputHandler: AggregatorInputHandler, multipleColumnsHandler: AggregatorMultipleColumnsHandler, + statisticsParameters: Map, ): AggregatorProvider = AggregatorProvider { name -> Aggregator( @@ -82,6 +85,22 @@ public class Aggregator( inputHandler = inputHandler, multipleColumnsHandler = multipleColumnsHandler, name = name, + statisticsParameters = statisticsParameters, + ) + } + + internal operator fun invoke( + aggregationHandler: AggregatorAggregationHandler, + inputHandler: AggregatorInputHandler, + multipleColumnsHandler: AggregatorMultipleColumnsHandler, + ): AggregatorProvider = + AggregatorProvider { name -> + Aggregator( + aggregationHandler = aggregationHandler, + inputHandler = inputHandler, + multipleColumnsHandler = multipleColumnsHandler, + name = name, + emptyMap(), ) } } diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/AggregatorAggregationHandler.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/AggregatorAggregationHandler.kt index 7b1b0357eb..a7f65152c3 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/AggregatorAggregationHandler.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/AggregatorAggregationHandler.kt @@ -3,6 +3,9 @@ package org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators import org.jetbrains.kotlinx.dataframe.DataColumn import org.jetbrains.kotlinx.dataframe.api.asSequence import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.aggregationHandlers.SelectingAggregationHandler +import org.jetbrains.kotlinx.dataframe.impl.columns.ParameterValue +import org.jetbrains.kotlinx.dataframe.impl.columns.StatisticResult +import org.jetbrains.kotlinx.dataframe.impl.columns.ValueColumnInternal import kotlin.reflect.KType /** @@ -26,13 +29,34 @@ public interface AggregatorAggregationHandler /** * Aggregates the data in the given column and computes a single resulting value. - * Calls [aggregateSequence]. + * Calls [aggregateSequence]. It tries to exploit a cache for statistics which is proper of + * [ValueColumnInternal] */ - public fun aggregateSingleColumn(column: DataColumn): Return = - aggregateSequence( + public fun aggregateSingleColumn(column: DataColumn): Return { + if (column is ValueColumnInternal<*>) { + // cache check, cache is dynamically created + val aggregator = this.aggregator ?: throw IllegalStateException("Aggregator is required") + val desiredStatisticNotConsideringParameters = column.statistics.getOrPut(aggregator.name) { + mutableMapOf, StatisticResult>() + } + // can't compare maps whose Values are Any? -> ParameterValue instead + val desiredStatistic = desiredStatisticNotConsideringParameters[aggregator.statisticsParameters] + // if desiredStatistic is null, statistic was never calculated + if (desiredStatistic != null) { + return desiredStatistic.value as Return + } + val statistic = aggregateSequence( + values = column.asSequence(), + valueType = column.type().toValueType(), + ) + desiredStatisticNotConsideringParameters[aggregator.statisticsParameters] = StatisticResult(statistic) + return aggregateSingleColumn(column) + } + return aggregateSequence( values = column.asSequence(), valueType = column.type().toValueType(), ) + } /** * Function that can give the return type of [aggregateSequence] as [KType], given the type of the input. diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregators.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregators.kt index 9648fed3ad..25660dd3d1 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregators.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/aggregation/aggregators/Aggregators.kt @@ -8,6 +8,7 @@ import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.inputHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.inputHandlers.NumberInputHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.FlatteningMultipleColumnsHandler import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.TwoStepMultipleColumnsHandler +import org.jetbrains.kotlinx.dataframe.impl.columns.ParameterValue import org.jetbrains.kotlinx.dataframe.math.indexOfMax import org.jetbrains.kotlinx.dataframe.math.indexOfMedian import org.jetbrains.kotlinx.dataframe.math.indexOfMin @@ -35,10 +36,12 @@ public object Aggregators { getReturnType: CalculateReturnType, indexOfResult: IndexOfResult, stepOneSelector: Selector, + statisticsParameters: Map, ) = Aggregator( aggregationHandler = SelectingAggregationHandler(stepOneSelector, indexOfResult, getReturnType), inputHandler = AnyInputHandler(), multipleColumnsHandler = TwoStepMultipleColumnsHandler(), + statisticsParameters = statisticsParameters, ) private fun flattenHybridForAny( @@ -117,8 +120,9 @@ public object Aggregators { by withOneOption { skipNaN: Boolean -> twoStepSelectingForAny, Comparable?>( getReturnType = minTypeConversion, - stepOneSelector = { type -> minOrNull(type, skipNaN) }, indexOfResult = { type -> indexOfMin(type, skipNaN) }, + stepOneSelector = { type -> minOrNull(type, skipNaN) }, + statisticsParameters = mapOf(Pair("skipNaN", ParameterValue(skipNaN))), ) } @@ -132,6 +136,7 @@ public object Aggregators { getReturnType = maxTypeConversion, stepOneSelector = { type -> maxOrNull(type, skipNaN) }, indexOfResult = { type -> indexOfMax(type, skipNaN) }, + statisticsParameters = mapOf(Pair("skipNaN", ParameterValue(skipNaN))), ) } diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/ValueColumnImpl.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/ValueColumnImpl.kt index f758360d1f..071801a5d8 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/ValueColumnImpl.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/ValueColumnImpl.kt @@ -8,6 +8,32 @@ import org.jetbrains.kotlinx.dataframe.columns.ValueColumn import kotlin.reflect.KType import kotlin.reflect.full.withNullability +@JvmInline +internal value class StatisticResult(val value: Any?) + +public class ParameterValue(public val parameter: Any?) { + + override fun equals(other: Any?): Boolean { + val otherAsParameterValue = other as ParameterValue? + val that = otherAsParameterValue?.parameter + if (parameter is Boolean && that is Boolean) { + return this.parameter == that + } + return super.equals(other) + } + + override fun hashCode(): Int { + if (parameter is Boolean?) { + return this.parameter.hashCode() + } + return super.hashCode() + } +} + +internal interface ValueColumnInternal : ValueColumn { + val statistics: MutableMap, StatisticResult>> +} + internal open class ValueColumnImpl( values: List, name: String, @@ -15,7 +41,8 @@ internal open class ValueColumnImpl( val defaultValue: T? = null, distinct: Lazy>? = null, ) : DataColumnImpl(values, name, type, distinct), - ValueColumn { + ValueColumn, + ValueColumnInternal { override fun distinct() = ValueColumnImpl(toSet().toList(), name, type, defaultValue, distinct) @@ -48,10 +75,13 @@ internal open class ValueColumnImpl( override fun defaultValue() = defaultValue override fun forceResolve() = ResolvingValueColumn(this) + + override val statistics = mutableMapOf, StatisticResult>>() } internal class ResolvingValueColumn(override val source: ValueColumn) : ValueColumn by source, + ValueColumnInternal, ForceResolvedColumn { override fun resolve(context: ColumnResolutionContext) = super.resolve(context) @@ -70,4 +100,6 @@ internal class ResolvingValueColumn(override val source: ValueColumn) : override fun equals(other: Any?) = source.checkEquals(other) override fun hashCode(): Int = source.hashCode() + + override val statistics = mutableMapOf, StatisticResult>>() } diff --git a/dataframe-csv/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/csv.kt b/dataframe-csv/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/csv.kt index 3b4d408145..2a6444488e 100644 --- a/dataframe-csv/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/csv.kt +++ b/dataframe-csv/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/csv.kt @@ -8,6 +8,7 @@ import org.jetbrains.kotlinx.dataframe.codeGen.DefaultReadDfMethod import org.jetbrains.kotlinx.dataframe.documentationCsv.DelimParams import java.io.File import java.io.InputStream +import java.nio.file.Path import kotlin.reflect.typeOf public class CsvDeephaven(private val delimiter: Char = DelimParams.CSV_DELIMITER) : SupportedDataFrameFormat { @@ -17,6 +18,9 @@ public class CsvDeephaven(private val delimiter: Char = DelimParams.CSV_DELIMITE override fun readDataFrame(file: File, header: List): DataFrame<*> = DataFrame.readCsv(file = file, header = header, delimiter = delimiter) + override fun readDataFrame(path: Path, header: List): DataFrame<*> = + DataFrame.readCsv(path = path, header = header, delimiter = delimiter) + override fun acceptsExtension(ext: String): Boolean = ext == "csv" override fun acceptsSample(sample: SupportedFormatSample): Boolean = true // Extension is enough diff --git a/dataframe-csv/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/tsv.kt b/dataframe-csv/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/tsv.kt index 9bc0cacd90..ecb123b93c 100644 --- a/dataframe-csv/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/tsv.kt +++ b/dataframe-csv/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/tsv.kt @@ -8,6 +8,7 @@ import org.jetbrains.kotlinx.dataframe.codeGen.DefaultReadDfMethod import org.jetbrains.kotlinx.dataframe.documentationCsv.DelimParams import java.io.File import java.io.InputStream +import java.nio.file.Path import kotlin.reflect.typeOf public class TsvDeephaven(private val delimiter: Char = DelimParams.TSV_DELIMITER) : SupportedDataFrameFormat { @@ -17,6 +18,9 @@ public class TsvDeephaven(private val delimiter: Char = DelimParams.TSV_DELIMITE override fun readDataFrame(file: File, header: List): DataFrame<*> = DataFrame.readTsv(file = file, header = header, delimiter = delimiter) + override fun readDataFrame(path: Path, header: List): DataFrame<*> = + DataFrame.readTsv(path = path, header = header, delimiter = delimiter) + override fun acceptsExtension(ext: String): Boolean = ext == "tsv" override fun acceptsSample(sample: SupportedFormatSample): Boolean = true // Extension is enough