summaryrefslogtreecommitdiff
path: root/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc')
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt13
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt50
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumnType.kt95
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt222
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableWriter.kt197
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/InterferenceGroupColumns.kt11
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/ResourceColumns.kt17
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/ResourceStateColumns.kt28
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/TableColumns.kt36
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/TaskColumns.kt40
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt7
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TableDetails.kt6
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt5
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/CompositeTableReader.kt53
-rw-r--r--opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/TableColumnConversion.kt77
15 files changed, 606 insertions, 251 deletions
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt
index 05d0234a..e6e97706 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt
@@ -32,21 +32,16 @@ public interface Table {
public val name: String
/**
- * The list of columns supported in this table.
+ * The columns in this table.
*/
- public val columns: List<TableColumn<*>>
-
- /**
- * The columns by which the table is partitioned.
- */
- public val partitionKeys: List<TableColumn<*>>
+ public val columns: List<TableColumn>
/**
* Open a [TableReader] for a projection of this table.
*
- * @param projection The list of columns to fetch from the table or `null` if no projection is performed.
+ * @param projection The names of the columns to fetch from the table or `null` if no projection is performed.
*/
- public fun newReader(projection: List<TableColumn<*>>? = null): TableReader
+ public fun newReader(projection: List<String>? = null): TableReader
/**
* Open a [TableWriter] for this table.
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt
index b77a2982..0f75d890 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt
@@ -22,47 +22,15 @@
package org.opendc.trace
-import java.util.*
-
/**
- * A column in a trace table.
+ * A column in a [Table].
*
- * @param name The universal name of this column.
+ * @property name The universal name of this column.
+ * @property type The type of the column.
+ * @property isNullable A flag to indicate that the column is nullable.
*/
-public class TableColumn<out T>(public val name: String, type: Class<T>) {
- /**
- * The type of the column.
- */
- public val type: Class<*> = type
-
- /**
- * Determine whether the type of the column is a subtype of [column].
- */
- public fun isAssignableTo(column: TableColumn<*>): Boolean {
- return name == column.name && type.isAssignableFrom(column.type)
- }
-
- /**
- * Compute a hash code for this column.
- */
- public override fun hashCode(): Int = Objects.hash(name, type)
-
- /**
- * Determine whether this column is equal to [other].
- */
- public override fun equals(other: Any?): Boolean {
- // Fast-path: reference equality
- if (this === other) {
- return true
- } else if (other == null || other !is TableColumn<*>) {
- return false
- }
-
- return name == other.name && type == other.type
- }
-
- /**
- * Return a string representation of this column.
- */
- public override fun toString(): String = "TableColumn[$name,$type]"
-}
+public data class TableColumn(
+ public val name: String,
+ public val type: TableColumnType,
+ public val isNullable: Boolean = false
+)
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumnType.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumnType.kt
new file mode 100644
index 00000000..6cae47f9
--- /dev/null
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumnType.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2022 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.trace
+
+/**
+ * The type of a [TableColumn].
+ */
+public sealed class TableColumnType {
+ /**
+ * A column of booleans.
+ */
+ public object Boolean : TableColumnType()
+
+ /**
+ * A column of 32-bit integers.
+ */
+ public object Int : TableColumnType()
+
+ /**
+ * A column of 64-bit integers.
+ */
+ public object Long : TableColumnType()
+
+ /**
+ * A column of 32-bit floats.
+ */
+ public object Float : TableColumnType()
+
+ /**
+ * A column of 64-bit floats.
+ */
+ public object Double : TableColumnType()
+
+ /**
+ * A column of UUIDs.
+ */
+ public object UUID : TableColumnType()
+
+ /**
+ * A column of variable-length strings.
+ */
+ public object String : TableColumnType()
+
+ /**
+ * A column of timestamps, mapping to [java.time.Instant].
+ */
+ public object Instant : TableColumnType()
+
+ /**
+ * A column of durations, mapping to [java.time.Duration]
+ */
+ public object Duration : TableColumnType()
+
+ /**
+ * A column containing embedded lists.
+ *
+ * @property elementType The type of the elements in the list.
+ */
+ public data class List(public val elementType: TableColumnType) : TableColumnType()
+
+ /**
+ * A column containing embedded sets.
+ *
+ * @property elementType The type of the elements in the sets.
+ */
+ public data class Set(public val elementType: TableColumnType) : TableColumnType()
+
+ /**
+ * A column containing embedded maps.
+ *
+ * @property keyType The type of the key.
+ * @property valueType The type of the value.
+ */
+ public data class Map(public val keyType: TableColumnType, public val valueType: TableColumnType) : TableColumnType()
+}
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt
index 8a796e6c..42b1c690 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt
@@ -22,8 +22,12 @@
package org.opendc.trace
+import java.time.Duration
+import java.time.Instant
+import java.util.UUID
+
/**
- * Base class for reading entities from a workload trace table in streaming fashion.
+ * Base class for reading entities from a [Table] in streaming fashion.
*/
public interface TableReader : AutoCloseable {
/**
@@ -34,20 +38,15 @@ public interface TableReader : AutoCloseable {
public fun nextRow(): Boolean
/**
- * Resolve the index of the specified [column] for this reader.
+ * Resolve the index of the column by its [name].
*
- * @param column The column to lookup.
+ * @param name The name of the column to lookup.
* @return The zero-based index of the column or a negative value if the column is not present in this table.
*/
- public fun resolve(column: TableColumn<*>): Int
-
- /**
- * Determine whether the [TableReader] supports the specified [column].
- */
- public fun hasColumn(column: TableColumn<*>): Boolean = resolve(column) >= 0
+ public fun resolve(name: String): Int
/**
- * Determine whether the specified [column] has a `null` value for the current row.
+ * Determine whether the column with the specified [index] has a `null` value for the current row.
*
* @param index The zero-based index of the column to check for a null value.
* @throws IllegalArgumentException if the column index is not valid for this reader.
@@ -56,15 +55,6 @@ public interface TableReader : AutoCloseable {
public fun isNull(index: Int): Boolean
/**
- * Obtain the object value of the column with the specified [index].
- *
- * @param index The zero-based index of the column to obtain the value for.
- * @throws IllegalArgumentException if the column index is not valid for this reader.
- * @return The object value of the column.
- */
- public fun get(index: Int): Any?
-
- /**
* Obtain the boolean value of the column with the specified [index].
*
* @param index The zero-based index of the column to obtain the value for.
@@ -74,7 +64,7 @@ public interface TableReader : AutoCloseable {
public fun getBoolean(index: Int): Boolean
/**
- * Obtain the integer value of the column with the specified [index].
+ * Obtain the boolean value of the column with the specified [index].
*
* @param index The zero-based index of the column to obtain the value for.
* @throws IllegalArgumentException if the column index is not valid for this reader.
@@ -92,6 +82,15 @@ public interface TableReader : AutoCloseable {
public fun getLong(index: Int): Long
/**
+ * Obtain the float value of the column with the specified [index].
+ *
+ * @param index The zero-based index of the column to obtain the value for.
+ * @throws IllegalArgumentException if the column index is not valid for this reader.
+ * @return The float value of the column or [Float.NaN] if the column is `null`.
+ */
+ public fun getFloat(index: Int): Float
+
+ /**
* Obtain the double value of the column with the specified [index].
*
* @param index The zero-based index of the column to obtain the value for.
@@ -101,62 +100,193 @@ public interface TableReader : AutoCloseable {
public fun getDouble(index: Int): Double
/**
- * Determine whether the specified [column] has a `null` value for the current row.
+ * Obtain the [String] value of the column with the specified [index].
*
- * @param column The column to lookup.
- * @throws IllegalArgumentException if the column is not valid for this table.
- * @return `true` if the column value for the current value has a `null` value, `false` otherwise.
+ * @param index The zero-based index of the column to obtain the value for.
+ * @throws IllegalArgumentException if the column index is not valid for this reader.
+ * @return The [String] value of the column or `null` if the column is `null`.
*/
- public fun isNull(column: TableColumn<*>): Boolean = isNull(resolve(column))
+ public fun getString(index: Int): String?
/**
- * Obtain the value of the current column with type [T].
+ * Obtain the [UUID] value of the column with the specified [index].
*
- * @param column The column to obtain the value for.
- * @throws IllegalArgumentException if the column is not valid for this reader.
- * @return The object value of the column.
+ * @param index The zero-based index of the column to obtain the value for.
+ * @throws IllegalArgumentException if the column index is not valid for this reader.
+ * @return The [UUID] value of the column or `null` if the column is `null`.
+ */
+ public fun getUUID(index: Int): UUID?
+
+ /**
+ * Obtain the [Instant] value of the column with the specified [index].
+ *
+ * @param index The zero-based index of the column to obtain the value for.
+ * @throws IllegalArgumentException if the column index is not valid for this reader.
+ * @return The [Instant] value of the column or `null` if the column is `null`.
+ */
+ public fun getInstant(index: Int): Instant?
+
+ /**
+ * Obtain the [Duration] value of the column with the specified [index].
+ *
+ * @param index The zero-based index of the column to obtain the value for.
+ * @throws IllegalArgumentException if the column index is not valid for this reader.
+ * @return The [Duration] value of the column or `null` if the column is `null`.
+ */
+ public fun getDuration(index: Int): Duration?
+
+ /**
+ * Obtain the value of the column with the specified [index] as [List].
+ *
+ * @param index The zero-based index of the column to obtain the value for.
+ * @param elementType Class representing the Java data type to convert elements of the designated column to.
+ * @throws IllegalArgumentException if the column index is not valid for this reader or this type.
+ * @return The value of the column as `List` or `null` if the column is null.
+ */
+ public fun <T> getList(index: Int, elementType: Class<T>): List<T>?
+
+ /**
+ * Obtain the value of the column with the specified [index] as [Set].
+ *
+ * @param index The zero-based index of the column to obtain the value for.
+ * @param elementType Class representing the Java data type to convert elements of the designated column to.
+ * @throws IllegalArgumentException if the column index is not valid for this reader or this type.
+ * @return The value of the column as `Set` or `null` if the column is null.
+ */
+ public fun <T> getSet(index: Int, elementType: Class<T>): Set<T>?
+
+ /**
+ * Obtain the value of the column with the specified [index] as [Set].
+ *
+ * @param index The zero-based index of the column to obtain the value for.
+ * @param keyType Class representing the Java data type to convert the keys of the designated column to.
+ * @param valueType Class representing the Java data type to convert the values of the designated column to.
+ * @throws IllegalArgumentException if the column index is not valid for this reader or this type.
+ * @return The value of the column as `Map` or `null` if the column is null.
+ */
+ public fun <K, V> getMap(index: Int, keyType: Class<K>, valueType: Class<V>): Map<K, V>?
+
+ /**
+ * Determine whether a column named [name] has a `null` value for the current row.
+ *
+ * @param name The name of the column to lookup.
+ * @throws IllegalArgumentException if the column is not valid for this table.
+ * @return `true` if the column value for the current value has a `null` value, `false` otherwise.
*/
- public fun <T> get(column: TableColumn<T>): T {
- // This cast should always succeed since the resolve the index of the typed column
- @Suppress("UNCHECKED_CAST")
- return get(resolve(column)) as T
- }
+ public fun isNull(name: String): Boolean = isNull(resolve(name))
/**
- * Read the specified [column] as boolean.
+ * Read the column named [name] as boolean.
*
- * @param column The column to obtain the value for.
+ * @param name The name of the column to get the value for.
* @throws IllegalArgumentException if the column is not valid for this reader.
* @return The boolean value of the column or `false` if the column is `null`.
*/
- public fun getBoolean(column: TableColumn<Boolean>): Boolean = getBoolean(resolve(column))
+ public fun getBoolean(name: String): Boolean = getBoolean(resolve(name))
/**
- * Read the specified [column] as integer.
+ * Read the column named [name] as integer.
*
- * @param column The column to obtain the value for.
+ * @param name The name of the column to get the value for.
* @throws IllegalArgumentException if the column is not valid for this reader.
* @return The integer value of the column or `0` if the column is `null`.
*/
- public fun getInt(column: TableColumn<Int>): Int = getInt(resolve(column))
+ public fun getInt(name: String): Int = getInt(resolve(name))
/**
- * Read the specified [column] as long.
+ * Read the column named [name] as long.
*
- * @param column The column to obtain the value for.
+ * @param name The name of the column to get the value for
* @throws IllegalArgumentException if the column is not valid for this reader.
* @return The long value of the column or `0` if the column is `null`.
*/
- public fun getLong(column: TableColumn<Long>): Long = getLong(resolve(column))
+ public fun getLong(name: String): Long = getLong(resolve(name))
+
+ /**
+ * Read the column named [name] as float.
+ *
+ * @param name The name of the column to get the value for.
+ * @throws IllegalArgumentException if the column is not valid for this reader.
+ * @return The float value of the column or [Float.NaN] if the column is `null`.
+ */
+ public fun getFloat(name: String): Float = getFloat(resolve(name))
/**
- * Read the specified [column] as double.
+ * Read the column named [name] as double.
*
- * @param column The column to obtain the value for.
+ * @param name The name of the column to get the value for.
* @throws IllegalArgumentException if the column is not valid for this reader.
* @return The double value of the column or [Double.NaN] if the column is `null`.
*/
- public fun getDouble(column: TableColumn<Double>): Double = getDouble(resolve(column))
+ public fun getDouble(name: String): Double = getDouble(resolve(name))
+
+ /**
+ * Read the column named [name] as [String].
+ *
+ * @param name The name of the column to get the value for.
+ * @throws IllegalArgumentException if the column is not valid for this reader.
+ * @return The [String] value of the column or `null` if the column is `null`.
+ */
+ public fun getString(name: String): String? = getString(resolve(name))
+
+ /**
+ * Read the column named [name] as [UUID].
+ *
+ * @param name The name of the column to get the value for.
+ * @throws IllegalArgumentException if the column is not valid for this reader.
+ * @return The [UUID] value of the column or `null` if the column is `null`.
+ */
+ public fun getUUID(name: String): UUID? = getUUID(resolve(name))
+
+ /**
+ * Read the column named [name] as [Instant].
+ *
+ * @param name The name of the column to get the value for.
+ * @throws IllegalArgumentException if the column is not valid for this reader.
+ * @return The [Instant] value of the column or `null` if the column is `null`.
+ */
+ public fun getInstant(name: String): Instant? = getInstant(resolve(name))
+
+ /**
+ * Read the column named [name] as [Duration].
+ *
+ * @param name The name of the column to get the value for.
+ * @throws IllegalArgumentException if the column is not valid for this reader.
+ * @return The [Duration] value of the column or `null` if the column is `null`.
+ */
+ public fun getDuration(name: String): Duration? = getDuration(resolve(name))
+
+ /**
+ * Obtain the value of the column named [name] as [List].
+ *
+ * @param name The name of the column to get the value for.
+ * @param elementType Class representing the Java data type to convert elements of the designated column to.
+ * @throws IllegalArgumentException if the column index is not valid for this reader or this type.
+ * @return The value of the column as `List` or `null` if the column is null.
+ */
+ public fun <T> getList(name: String, elementType: Class<T>): List<T>? = getList(resolve(name), elementType)
+
+ /**
+ * Obtain the value of the column named [name] as [Set].
+ *
+ * @param name The name of the column to get the value for.
+ * @param elementType Class representing the Java data type to convert elements of the designated column to.
+ * @throws IllegalArgumentException if the column index is not valid for this reader or this type.
+ * @return The value of the column as `Set` or `null` if the column is null.
+ */
+ public fun <T> getSet(name: String, elementType: Class<T>): Set<T>? = getSet(resolve(name), elementType)
+
+ /**
+ * Obtain the value of the column named [name] as [Set].
+ *
+ * @param name The name of the column to get the value for.
+ * @param keyType Class representing the Java data type to convert the keys of the designated column to.
+ * @param valueType Class representing the Java data type to convert the values of the designated column to.
+ * @throws IllegalArgumentException if the column index is not valid for this reader or this type.
+ * @return The value of the column as `Map` or `null` if the column is null.
+ */
+ public fun <K, V> getMap(name: String, keyType: Class<K>, valueType: Class<V>): Map<K, V>? =
+ getMap(resolve(name), keyType, valueType)
/**
* Closes the reader so that no further iteration or data access can be made.
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableWriter.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableWriter.kt
index 423ce86a..a3122ec9 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableWriter.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableWriter.kt
@@ -22,6 +22,10 @@
package org.opendc.trace
+import java.time.Duration
+import java.time.Instant
+import java.util.*
+
/**
* Base class for writing workload traces.
*/
@@ -37,107 +41,228 @@ public interface TableWriter : AutoCloseable {
public fun endRow()
/**
- * Resolve the index of the specified [column] for this writer.
+ * Resolve the index of the column named [name] for this writer.
*
- * @param column The column to lookup.
+ * @param name The name of the column to lookup.
* @return The zero-based index of the column or a negative value if the column is not present in this table.
*/
- public fun resolve(column: TableColumn<*>): Int
+ public fun resolve(name: String): Int
/**
- * Determine whether the [TableReader] supports the specified [column].
+ * Set the column with index [index] to boolean [value].
+ *
+ * @param index The zero-based index of the column to set the value for.
+ * @param value The boolean value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun hasColumn(column: TableColumn<*>): Boolean = resolve(column) >= 0
+ public fun setBoolean(index: Int, value: Boolean)
/**
- * Set [column] to [value].
+ * Set the column with index [index] to integer [value].
*
* @param index The zero-based index of the column to set the value for.
- * @param value The value to set the column to.
+ * @param value The integer value to set the column to.
* @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun set(index: Int, value: Any)
+ public fun setInt(index: Int, value: Int)
/**
- * Set [column] to boolean [value].
+ * Set the column with index [index] to long [value].
*
* @param index The zero-based index of the column to set the value for.
- * @param value The boolean value to set the column to.
+ * @param value The long value to set the column to.
* @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun setBoolean(index: Int, value: Boolean)
+ public fun setLong(index: Int, value: Long)
/**
- * Set [column] to integer [value].
+ * Set the column with index [index] to float [value].
*
* @param index The zero-based index of the column to set the value for.
- * @param value The integer value to set the column to.
+ * @param value The float value to set the column to.
* @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun setInt(index: Int, value: Int)
+ public fun setFloat(index: Int, value: Float)
/**
- * Set [column] to long [value].
+ * Set the column with index [index] to double [value].
*
* @param index The zero-based index of the column to set the value for.
- * @param value The long value to set the column to.
+ * @param value The double value to set the column to.
* @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun setLong(index: Int, value: Long)
+ public fun setDouble(index: Int, value: Double)
/**
- * Set [column] to double [value].
+ * Set the column with index [index] to [String] [value].
*
* @param index The zero-based index of the column to set the value for.
- * @param value The double value to set the column to.
+ * @param value The [String] value to set the column to.
* @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun setDouble(index: Int, value: Double)
+ public fun setString(index: Int, value: String)
+
+ /**
+ * Set the column with index [index] to [UUID] [value].
+ *
+ * @param index The zero-based index of the column to set the value for.
+ * @param value The [UUID] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun setUUID(index: Int, value: UUID)
+
+ /**
+ * Set the column with index [index] to [Instant] [value].
+ *
+ * @param index The zero-based index of the column to set the value for.
+ * @param value The [Instant] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun setInstant(index: Int, value: Instant)
/**
- * Set [column] to [value].
+ * Set the column with index [index] to [Duration] [value].
*
- * @param column The column to set the value for.
- * @param value The value to set the column to.
+ * @param index The zero-based index of the column to set the value for.
+ * @param value The [Duration] value to set the column to.
* @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun <T : Any> set(column: TableColumn<T>, value: T): Unit = set(resolve(column), value)
+ public fun setDuration(index: Int, value: Duration)
/**
- * Set [column] to boolean [value].
+ * Set the column with index [index] to [List] [value].
*
- * @param column The column to set the value for.
+ * @param index The zero-based index of the column to set the value for.
+ * @param value The [Map] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun <T> setList(index: Int, value: List<T>)
+
+ /**
+ * Set the column with index [index] to [Set] [value].
+ *
+ * @param index The zero-based index of the column to set the value for.
+ * @param value The [Set] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun <T> setSet(index: Int, value: Set<T>)
+
+ /**
+ * Set the column with index [index] to [Map] [value].
+ *
+ * @param index The zero-based index of the column to set the value for.
+ * @param value The [Map] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun <K, V> setMap(index: Int, value: Map<K, V>)
+
+ /**
+ * Set the column named [name] to boolean [value].
+ *
+ * @param name The name of the column to set the value for.
* @param value The boolean value to set the column to.
* @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun setBoolean(column: TableColumn<Boolean>, value: Boolean): Unit = setBoolean(resolve(column), value)
+ public fun setBoolean(name: String, value: Boolean): Unit = setBoolean(resolve(name), value)
/**
- * Set [column] to integer [value].
+ * Set the column named [name] to integer [value].
*
- * @param column The column to set the value for.
+ * @param name The name of the column to set the value for.
* @param value The integer value to set the column to.
* @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun setInt(column: TableColumn<Int>, value: Int): Unit = setInt(resolve(column), value)
+ public fun setInt(name: String, value: Int): Unit = setInt(resolve(name), value)
/**
- * Set [column] to long [value].
+ * Set the column named [name] to long [value].
*
- * @param column The column to set the value for.
+ * @param name The name of the column to set the value for.
* @param value The long value to set the column to.
* @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun setLong(column: TableColumn<Long>, value: Long): Unit = setLong(resolve(column), value)
+ public fun setLong(name: String, value: Long): Unit = setLong(resolve(name), value)
+
+ /**
+ * Set the column named [name] to float [value].
+ *
+ * @param name The name of the column to set the value for.
+ * @param value The float value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun setFloat(name: String, value: Float): Unit = setFloat(resolve(name), value)
/**
- * Set [column] to double [value].
+ * Set the column named [name] to double [value].
*
- * @param column The column to set the value for.
+ * @param name The name of the column to set the value for.
* @param value The double value to set the column to.
* @throws IllegalArgumentException if the column is not valid for this method.
*/
- public fun setDouble(column: TableColumn<Double>, value: Double): Unit = setDouble(resolve(column), value)
+ public fun setDouble(name: String, value: Double): Unit = setDouble(resolve(name), value)
+
+ /**
+ * Set the column named [name] to [String] [value].
+ *
+ * @param name The name of the column to set the value for.
+ * @param value The [String] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun setString(name: String, value: String): Unit = setString(resolve(name), value)
+
+ /**
+ * Set the column named [name] to [UUID] [value].
+ *
+ * @param name The name of the column to set the value for.
+ * @param value The [UUID] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun setUUID(name: String, value: UUID): Unit = setUUID(resolve(name), value)
+
+ /**
+ * Set the column named [name] to [Instant] [value].
+ *
+ * @param name The name of the column to set the value for.
+ * @param value The [Instant] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun setInstant(name: String, value: Instant): Unit = setInstant(resolve(name), value)
+
+ /**
+ * Set the column named [name] to [Duration] [value].
+ *
+ * @param name The name of the column to set the value for.
+ * @param value The [Duration] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun setDuration(name: String, value: Duration): Unit = setDuration(resolve(name), value)
+
+ /**
+ * Set the column named [name] to [List] [value].
+ *
+ * @param name The name of the column to set the value for.
+ * @param value The [List] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun <T> setList(name: String, value: List<T>): Unit = setList(resolve(name), value)
+
+ /**
+ * Set the column named [name] to [Set] [value].
+ *
+ * @param name The name of the column to set the value for.
+ * @param value The [Set] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun <T> setSet(name: String, value: Set<T>): Unit = setSet(resolve(name), value)
+
+ /**
+ * Set the column named [name] to [Map] [value].
+ *
+ * @param name The name of the column to set the value for.
+ * @param value The [Map] value to set the column to.
+ * @throws IllegalArgumentException if the column is not valid for this method.
+ */
+ public fun <K, V> setMap(name: String, value: Map<K, V>): Unit = setMap(resolve(name), value)
/**
* Flush any buffered content to the underlying target.
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/InterferenceGroupColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/InterferenceGroupColumns.kt
index 5e8859e4..2a80687c 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/InterferenceGroupColumns.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/InterferenceGroupColumns.kt
@@ -23,22 +23,17 @@
@file:JvmName("InterferenceGroupColumns")
package org.opendc.trace.conv
-import org.opendc.trace.TableColumn
-
/**
* Members of the interference group.
*/
-@JvmField
-public val INTERFERENCE_GROUP_MEMBERS: TableColumn<Set<String>> = column("members")
+public const val INTERFERENCE_GROUP_MEMBERS: String = "members"
/**
* Target load after which the interference occurs.
*/
-@JvmField
-public val INTERFERENCE_GROUP_TARGET: TableColumn<Double> = column("target")
+public const val INTERFERENCE_GROUP_TARGET: String = "target"
/**
* Performance score when the interference occurs.
*/
-@JvmField
-public val INTERFERENCE_GROUP_SCORE: TableColumn<Double> = column("score")
+public const val INTERFERENCE_GROUP_SCORE: String = "score"
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/ResourceColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/ResourceColumns.kt
index e602e534..9b7b8195 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/ResourceColumns.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/ResourceColumns.kt
@@ -23,47 +23,44 @@
@file:JvmName("ResourceColumns")
package org.opendc.trace.conv
-import org.opendc.trace.TableColumn
-import java.time.Instant
-
/**
* Identifier of the resource.
*/
@JvmField
-public val RESOURCE_ID: TableColumn<String> = column("id")
+public val RESOURCE_ID: String = "id"
/**
* The cluster to which the resource belongs.
*/
@JvmField
-public val RESOURCE_CLUSTER_ID: TableColumn<String> = column("cluster_id")
+public val RESOURCE_CLUSTER_ID: String = "cluster_id"
/**
* Start time for the resource.
*/
@JvmField
-public val RESOURCE_START_TIME: TableColumn<Instant> = column("start_time")
+public val RESOURCE_START_TIME: String = "start_time"
/**
* End time for the resource.
*/
@JvmField
-public val RESOURCE_STOP_TIME: TableColumn<Instant> = column("stop_time")
+public val RESOURCE_STOP_TIME: String = "stop_time"
/**
* Number of CPUs for the resource.
*/
@JvmField
-public val RESOURCE_CPU_COUNT: TableColumn<Int> = column("cpu_count")
+public val RESOURCE_CPU_COUNT: String = "cpu_count"
/**
* Total CPU capacity of the resource in MHz.
*/
@JvmField
-public val RESOURCE_CPU_CAPACITY: TableColumn<Double> = column("cpu_capacity")
+public val RESOURCE_CPU_CAPACITY: String = "cpu_capacity"
/**
* Memory capacity for the resource in KB.
*/
@JvmField
-public val RESOURCE_MEM_CAPACITY: TableColumn<Double> = column("mem_capacity")
+public val RESOURCE_MEM_CAPACITY: String = "mem_capacity"
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/ResourceStateColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/ResourceStateColumns.kt
index 3a44f817..e9dd7673 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/ResourceStateColumns.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/ResourceStateColumns.kt
@@ -23,78 +23,74 @@
@file:JvmName("ResourceStateColumns")
package org.opendc.trace.conv
-import org.opendc.trace.TableColumn
-import java.time.Duration
-import java.time.Instant
-
/**
* The timestamp at which the state was recorded.
*/
@JvmField
-public val RESOURCE_STATE_TIMESTAMP: TableColumn<Instant> = column("timestamp")
+public val RESOURCE_STATE_TIMESTAMP: String = "timestamp"
/**
* Duration for the state.
*/
@JvmField
-public val RESOURCE_STATE_DURATION: TableColumn<Duration> = column("duration")
+public val RESOURCE_STATE_DURATION: String = "duration"
/**
* A flag to indicate that the resource is powered on.
*/
@JvmField
-public val RESOURCE_STATE_POWERED_ON: TableColumn<Boolean> = column("powered_on")
+public val RESOURCE_STATE_POWERED_ON: String = "powered_on"
/**
* Total CPU usage of the resource in MHz.
*/
@JvmField
-public val RESOURCE_STATE_CPU_USAGE: TableColumn<Double> = column("cpu_usage")
+public val RESOURCE_STATE_CPU_USAGE: String = "cpu_usage"
/**
* Total CPU usage of the resource in percentage.
*/
@JvmField
-public val RESOURCE_STATE_CPU_USAGE_PCT: TableColumn<Double> = column("cpu_usage_pct")
+public val RESOURCE_STATE_CPU_USAGE_PCT: String = "cpu_usage_pct"
/**
* Total CPU demand of the resource in MHz.
*/
@JvmField
-public val RESOURCE_STATE_CPU_DEMAND: TableColumn<Double> = column("cpu_demand")
+public val RESOURCE_STATE_CPU_DEMAND: String = "cpu_demand"
/**
* CPU ready percentage.
*/
@JvmField
-public val RESOURCE_STATE_CPU_READY_PCT: TableColumn<Double> = column("cpu_ready_pct")
+public val RESOURCE_STATE_CPU_READY_PCT: String = "cpu_ready_pct"
/**
* Memory usage of the resource in KB.
*/
@JvmField
-public val RESOURCE_STATE_MEM_USAGE: TableColumn<Double> = column("mem_usage")
+public val RESOURCE_STATE_MEM_USAGE: String = "mem_usage"
/**
* Disk read throughput of the resource in KB/s.
*/
@JvmField
-public val RESOURCE_STATE_DISK_READ: TableColumn<Double> = column("disk_read")
+public val RESOURCE_STATE_DISK_READ: String = "disk_read"
/**
* Disk write throughput of the resource in KB/s.
*/
@JvmField
-public val RESOURCE_STATE_DISK_WRITE: TableColumn<Double> = column("disk_write")
+public val RESOURCE_STATE_DISK_WRITE: String = "disk_write"
/**
* Network receive throughput of the resource in KB/s.
*/
@JvmField
-public val RESOURCE_STATE_NET_RX: TableColumn<Double> = column("net_rx")
+public val RESOURCE_STATE_NET_RX: String = "net_rx"
/**
* Network transmit throughput of the resource in KB/s.
*/
@JvmField
-public val RESOURCE_STATE_NET_TX: TableColumn<Double> = column("net_tx")
+public val RESOURCE_STATE_NET_TX: String = "net_tx"
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/TableColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/TableColumns.kt
deleted file mode 100644
index a58505e9..00000000
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/TableColumns.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-@file:JvmName("TableColumns")
-package org.opendc.trace.conv
-
-import org.opendc.trace.TableColumn
-
-/**
- * Construct a [TableColumn] with the specified [name] and type [T].
- */
-public inline fun <reified T> column(name: String): TableColumn<T> = column(name, T::class.java)
-
-/**
- * Construct a [TableColumn] with the specified [name] and [type].
- */
-public fun <T> column(name: String, type: Class<T>): TableColumn<T> = TableColumn(name, type)
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/TaskColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/TaskColumns.kt
index e6daafb7..da5c343f 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/TaskColumns.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/conv/TaskColumns.kt
@@ -23,78 +23,62 @@
@file:JvmName("TaskColumns")
package org.opendc.trace.conv
-import org.opendc.trace.TableColumn
-import java.time.Duration
-import java.time.Instant
-
/**
* A column containing the task identifier.
*/
-@JvmField
-public val TASK_ID: TableColumn<String> = column("id")
+public const val TASK_ID: String = "id"
/**
* A column containing the identifier of the workflow.
*/
-@JvmField
-public val TASK_WORKFLOW_ID: TableColumn<String> = column("workflow_id")
+public const val TASK_WORKFLOW_ID: String = "workflow_id"
/**
* A column containing the submission time of the task.
*/
-@JvmField
-public val TASK_SUBMIT_TIME: TableColumn<Instant> = column("submit_time")
+public const val TASK_SUBMIT_TIME: String = "submit_time"
/**
* A column containing the wait time of the task.
*/
-@JvmField
-public val TASK_WAIT_TIME: TableColumn<Instant> = column("wait_time")
+public const val TASK_WAIT_TIME: String = "wait_time"
/**
* A column containing the runtime time of the task.
*/
-@JvmField
-public val TASK_RUNTIME: TableColumn<Duration> = column("runtime")
+public const val TASK_RUNTIME: String = "runtime"
/**
* A column containing the parents of a task.
*/
-@JvmField
-public val TASK_PARENTS: TableColumn<Set<String>> = column("parents")
+public const val TASK_PARENTS: String = "parents"
/**
* A column containing the children of a task.
*/
-@JvmField
-public val TASK_CHILDREN: TableColumn<Set<String>> = column("children")
+public const val TASK_CHILDREN: String = "children"
/**
* A column containing the requested CPUs of a task.
*/
-@JvmField
-public val TASK_REQ_NCPUS: TableColumn<Int> = column("req_ncpus")
+public const val TASK_REQ_NCPUS: String = "req_ncpus"
/**
* A column containing the allocated CPUs of a task.
*/
-@JvmField
-public val TASK_ALLOC_NCPUS: TableColumn<Int> = column("alloc_ncpus")
+public const val TASK_ALLOC_NCPUS: String = "alloc_ncpus"
/**
* A column containing the status of a task.
*/
-@JvmField
-public val TASK_STATUS: TableColumn<Int> = column("status")
+public const val TASK_STATUS: String = "status"
/**
* A column containing the group id of a task.
*/
-@JvmField
-public val TASK_GROUP_ID: TableColumn<Int> = column("group_id")
+public const val TASK_GROUP_ID: String = "group_id"
/**
* A column containing the user id of a task.
*/
-@JvmField
-public val TASK_USER_ID: TableColumn<Int> = column("user_id")
+public const val TASK_USER_ID: String = "user_id"
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt
index b848e19a..1e1bf676 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt
@@ -37,13 +37,10 @@ internal class TableImpl(val trace: TraceImpl, override val name: String) : Tabl
*/
private val details = trace.format.getDetails(trace.path, name)
- override val columns: List<TableColumn<*>>
+ override val columns: List<TableColumn>
get() = details.columns
- override val partitionKeys: List<TableColumn<*>>
- get() = details.partitionKeys
-
- override fun newReader(projection: List<TableColumn<*>>?): TableReader {
+ override fun newReader(projection: List<String>?): TableReader {
return trace.format.newReader(trace.path, name, projection)
}
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TableDetails.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TableDetails.kt
index 1a9b9ee1..5206d02b 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TableDetails.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TableDetails.kt
@@ -29,9 +29,5 @@ import org.opendc.trace.TableColumn
* A class used by the [TraceFormat] interface for describing the metadata of a [Table].
*
* @param columns The available columns in the table.
- * @param partitionKeys The table columns that act as partition keys for the table.
*/
-public data class TableDetails(
- val columns: List<TableColumn<*>>,
- val partitionKeys: List<TableColumn<*>> = emptyList()
-)
+public data class TableDetails(val columns: List<TableColumn>)
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt
index 47761e0f..eff6fa83 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt
@@ -22,7 +22,6 @@
package org.opendc.trace.spi
-import org.opendc.trace.TableColumn
import org.opendc.trace.TableReader
import org.opendc.trace.TableWriter
import java.nio.file.Path
@@ -69,11 +68,11 @@ public interface TraceFormat {
*
* @param path The path to the trace to open.
* @param table The name of the table to open a [TableReader] for.
- * @param projection The list of [TableColumn]s to project or `null` if no projection is performed.
+ * @param projection The name of the columns to project or `null` if no projection is performed.
* @throws IllegalArgumentException If [table] does not exist.
* @return A [TableReader] instance for the table.
*/
- public fun newReader(path: Path, table: String, projection: List<TableColumn<*>>?): TableReader
+ public fun newReader(path: Path, table: String, projection: List<String>?): TableReader
/**
* Open a [TableWriter] for the specified [table].
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/CompositeTableReader.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/CompositeTableReader.kt
index 11e032c7..c4854265 100644
--- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/CompositeTableReader.kt
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/CompositeTableReader.kt
@@ -22,8 +22,10 @@
package org.opendc.trace.util
-import org.opendc.trace.TableColumn
import org.opendc.trace.TableReader
+import java.time.Duration
+import java.time.Instant
+import java.util.*
/**
* A helper class to chain multiple [TableReader]s.
@@ -63,11 +65,11 @@ public abstract class CompositeTableReader : TableReader {
return delegate != null
}
- override fun resolve(column: TableColumn<*>): Int {
+ override fun resolve(name: String): Int {
tryStart()
val delegate = delegate
- return delegate?.resolve(column) ?: -1
+ return delegate?.resolve(name) ?: -1
}
override fun isNull(index: Int): Boolean {
@@ -75,11 +77,6 @@ public abstract class CompositeTableReader : TableReader {
return delegate.isNull(index)
}
- override fun get(index: Int): Any? {
- val delegate = checkNotNull(delegate) { "Invalid reader state" }
- return delegate.get(index)
- }
-
override fun getBoolean(index: Int): Boolean {
val delegate = checkNotNull(delegate) { "Invalid reader state" }
return delegate.getBoolean(index)
@@ -95,11 +92,51 @@ public abstract class CompositeTableReader : TableReader {
return delegate.getLong(index)
}
+ override fun getFloat(index: Int): Float {
+ val delegate = checkNotNull(delegate) { "Invalid reader state" }
+ return delegate.getFloat(index)
+ }
+
override fun getDouble(index: Int): Double {
val delegate = checkNotNull(delegate) { "Invalid reader state" }
return delegate.getDouble(index)
}
+ override fun getString(index: Int): String? {
+ val delegate = checkNotNull(delegate) { "Invalid reader state" }
+ return delegate.getString(index)
+ }
+
+ override fun getUUID(index: Int): UUID? {
+ val delegate = checkNotNull(delegate) { "Invalid reader state" }
+ return delegate.getUUID(index)
+ }
+
+ override fun getInstant(index: Int): Instant? {
+ val delegate = checkNotNull(delegate) { "Invalid reader state" }
+ return delegate.getInstant(index)
+ }
+
+ override fun getDuration(index: Int): Duration? {
+ val delegate = checkNotNull(delegate) { "Invalid reader state" }
+ return delegate.getDuration(index)
+ }
+
+ override fun <T> getList(index: Int, elementType: Class<T>): List<T>? {
+ val delegate = checkNotNull(delegate) { "Invalid reader state" }
+ return delegate.getList(index, elementType)
+ }
+
+ override fun <T> getSet(index: Int, elementType: Class<T>): Set<T>? {
+ val delegate = checkNotNull(delegate) { "Invalid reader state" }
+ return delegate.getSet(index, elementType)
+ }
+
+ override fun <K, V> getMap(index: Int, keyType: Class<K>, valueType: Class<V>): Map<K, V>? {
+ val delegate = checkNotNull(delegate) { "Invalid reader state" }
+ return delegate.getMap(index, keyType, valueType)
+ }
+
override fun close() {
delegate?.close()
}
diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/TableColumnConversion.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/TableColumnConversion.kt
new file mode 100644
index 00000000..8ef080b5
--- /dev/null
+++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/TableColumnConversion.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2022 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+@file:JvmName("TableColumnConversions")
+package org.opendc.trace.util
+
+import org.opendc.trace.TableColumnType
+import java.time.Duration
+import java.time.Instant
+import java.util.UUID
+
+/**
+ * Helper method to convert a [List] into a [List] with elements of [targetElementType].
+ */
+public fun <T> TableColumnType.List.convertTo(value: List<*>?, targetElementType: Class<T>): List<T>? {
+ require(elementType.isCompatible(targetElementType)) { "Target element type is not compatible with $elementType" }
+ @Suppress("UNCHECKED_CAST")
+ return value as List<T>?
+}
+
+/**
+ * Helper method to convert a [Set] into a [Set] with elements of [targetElementType].
+ */
+public fun <T> TableColumnType.Set.convertTo(value: Set<*>?, targetElementType: Class<T>): Set<T>? {
+ require(elementType.isCompatible(targetElementType)) { "Target element type is not compatible with $elementType" }
+ @Suppress("UNCHECKED_CAST")
+ return value as Set<T>?
+}
+
+/**
+ * Helper method to convert a [Map] into a [Map] with [targetKeyType] keys and [targetValueType] values.
+ */
+public fun <K, V> TableColumnType.Map.convertTo(value: Map<*, *>?, targetKeyType: Class<K>, targetValueType: Class<V>): Map<K, V>? {
+ require(keyType.isCompatible(targetKeyType)) { "Target key type $targetKeyType is not compatible with $keyType" }
+ require(valueType.isCompatible(targetValueType)) { "Target value type $targetValueType is not compatible with $valueType" }
+ @Suppress("UNCHECKED_CAST")
+ return value as Map<K, V>?
+}
+
+/**
+ * Helper method to determine [javaType] is compatible with this [TableColumnType].
+ */
+private fun TableColumnType.isCompatible(javaType: Class<*>): Boolean {
+ return when (this) {
+ is TableColumnType.Boolean -> javaType.isAssignableFrom(Boolean::class.java)
+ is TableColumnType.Int -> javaType.isAssignableFrom(Int::class.java)
+ is TableColumnType.Long -> javaType.isAssignableFrom(Long::class.java)
+ is TableColumnType.Float -> javaType.isAssignableFrom(Float::class.java)
+ is TableColumnType.Double -> javaType.isAssignableFrom(Double::class.java)
+ is TableColumnType.String -> javaType.isAssignableFrom(String::class.java)
+ is TableColumnType.UUID -> javaType.isAssignableFrom(UUID::class.java)
+ is TableColumnType.Instant -> javaType.isAssignableFrom(Instant::class.java)
+ is TableColumnType.Duration -> javaType.isAssignableFrom(Duration::class.java)
+ is TableColumnType.List -> javaType.isAssignableFrom(List::class.java)
+ is TableColumnType.Set -> javaType.isAssignableFrom(Set::class.java)
+ is TableColumnType.Map -> javaType.isAssignableFrom(Map::class.java)
+ }
+}