diff options
| author | Dante Niewenhuis <d.niewenhuis@hotmail.com> | 2024-04-16 09:29:53 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-16 09:29:53 +0200 |
| commit | fff89d25bd3c7b874e68261d21695c473c30ed7d (patch) | |
| tree | be368dd745e8119dbdefd9cd0b012c7ff9080a7a /opendc-trace/opendc-trace-bitbrains/src/main | |
| parent | a7b0afbb5b7059274962ade234a50240677008fd (diff) | |
Revamped the trace system. All TraceFormat files are now in the api m… (#216)
* Revamped the trace system. All TraceFormat files are now in the api module. This fixes some problems with not being able to use types of traces
* applied spotless
Diffstat (limited to 'opendc-trace/opendc-trace-bitbrains/src/main')
6 files changed, 0 insertions, 1128 deletions
diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt deleted file mode 100644 index 8387d1ed..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt +++ /dev/null @@ -1,292 +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. - */ - -package org.opendc.trace.bitbrains - -import org.opendc.trace.TableReader -import org.opendc.trace.conv.resourceClusterID -import org.opendc.trace.conv.resourceCpuCapacity -import org.opendc.trace.conv.resourceCpuCount -import org.opendc.trace.conv.resourceID -import org.opendc.trace.conv.resourceMemCapacity -import org.opendc.trace.conv.resourceStateCpuDemand -import org.opendc.trace.conv.resourceStateCpuReadyPct -import org.opendc.trace.conv.resourceStateCpuUsage -import org.opendc.trace.conv.resourceStateCpuUsagePct -import org.opendc.trace.conv.resourceStateDiskRead -import org.opendc.trace.conv.resourceStateDiskWrite -import org.opendc.trace.conv.resourceStateTimestamp -import java.io.BufferedReader -import java.time.Duration -import java.time.Instant -import java.util.UUID - -/** - * A [TableReader] for the Bitbrains resource state table. - */ -internal class BitbrainsExResourceStateTableReader(private val reader: BufferedReader) : TableReader { - private var state = State.Pending - - override fun nextRow(): Boolean { - val state = state - if (state == State.Closed) { - return false - } else if (state == State.Pending) { - this.state = State.Active - } - - reset() - - var line: String? - var num = 0 - - while (true) { - line = reader.readLine() - - if (line == null) { - this.state = State.Closed - return false - } - - num++ - - if (line[0] == '#' || line.isBlank()) { - // Ignore empty lines or comments - continue - } - - break - } - - line = line!!.trim() - - val length = line.length - var col = 0 - var start: Int - var end = 0 - - while (end < length) { - // Trim all whitespace before the field - start = end - while (start < length && line[start].isWhitespace()) { - start++ - } - - end = line.indexOf(' ', start) - - if (end < 0) { - end = length - } - - val field = line.subSequence(start, end) as String - when (col++) { - colTimestamp -> timestamp = Instant.ofEpochSecond(field.toLong(10)) - colCpuUsage -> cpuUsage = field.toDouble() - colCpuDemand -> cpuDemand = field.toDouble() - colDiskRead -> diskRead = field.toDouble() - colDiskWrite -> diskWrite = field.toDouble() - colClusterID -> cluster = field.trim() - colNcpus -> cpuCores = field.toInt(10) - colCpuReadyPct -> cpuReadyPct = field.toDouble() - colPoweredOn -> poweredOn = field.toInt(10) == 1 - colCpuCapacity -> cpuCapacity = field.toDouble() - colID -> id = field.trim() - colMemCapacity -> memCapacity = field.toDouble() * 1000 // Convert from MB to KB - } - } - - return true - } - - override fun resolve(name: String): Int { - return when (name) { - resourceID -> colID - resourceClusterID -> colClusterID - resourceStateTimestamp -> colTimestamp - resourceCpuCount -> colNcpus - resourceCpuCapacity -> colCpuCapacity - resourceStateCpuUsage -> colCpuUsage - resourceStateCpuUsagePct -> colCpuUsagePct - resourceStateCpuDemand -> colCpuDemand - resourceStateCpuReadyPct -> colCpuReadyPct - resourceMemCapacity -> colMemCapacity - resourceStateDiskRead -> colDiskRead - resourceStateDiskWrite -> colDiskWrite - else -> -1 - } - } - - override fun isNull(index: Int): Boolean { - require(index in 0 until colMax) { "Invalid column index" } - return false - } - - override fun getBoolean(index: Int): Boolean { - check(state == State.Active) { "No active row" } - return when (index) { - colPoweredOn -> poweredOn - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getInt(index: Int): Int { - check(state == State.Active) { "No active row" } - return when (index) { - colNcpus -> cpuCores - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getLong(index: Int): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getFloat(index: Int): Float { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(index: Int): Double { - check(state == State.Active) { "No active row" } - return when (index) { - colCpuCapacity -> cpuCapacity - colCpuUsage -> cpuUsage - colCpuUsagePct -> cpuUsage / cpuCapacity - colCpuReadyPct -> cpuReadyPct - colCpuDemand -> cpuDemand - colMemCapacity -> memCapacity - colDiskRead -> diskRead - colDiskWrite -> diskWrite - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getString(index: Int): String? { - check(state == State.Active) { "No active row" } - return when (index) { - colID -> id - colClusterID -> cluster - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getUUID(index: Int): UUID? { - throw IllegalArgumentException("Invalid column") - } - - override fun getInstant(index: Int): Instant? { - check(state == State.Active) { "No active row" } - return when (index) { - colTimestamp -> timestamp - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getDuration(index: Int): Duration? { - throw IllegalArgumentException("Invalid column") - } - - override fun <T> getList( - index: Int, - elementType: Class<T>, - ): List<T>? { - throw IllegalArgumentException("Invalid column") - } - - override fun <T> getSet( - index: Int, - elementType: Class<T>, - ): Set<T>? { - throw IllegalArgumentException("Invalid column") - } - - override fun <K, V> getMap( - index: Int, - keyType: Class<K>, - valueType: Class<V>, - ): Map<K, V>? { - throw IllegalArgumentException("Invalid column") - } - - override fun close() { - reader.close() - reset() - state = State.Closed - } - - /** - * State fields of the reader. - */ - private var id: String? = null - private var cluster: String? = null - private var timestamp: Instant? = null - private var cpuCores = -1 - private var cpuCapacity = Double.NaN - private var cpuUsage = Double.NaN - private var cpuDemand = Double.NaN - private var cpuReadyPct = Double.NaN - private var memCapacity = Double.NaN - private var diskRead = Double.NaN - private var diskWrite = Double.NaN - private var poweredOn: Boolean = false - - /** - * Reset the state of the reader. - */ - private fun reset() { - id = null - timestamp = null - cluster = null - cpuCores = -1 - cpuCapacity = Double.NaN - cpuUsage = Double.NaN - cpuDemand = Double.NaN - cpuReadyPct = Double.NaN - memCapacity = Double.NaN - diskRead = Double.NaN - diskWrite = Double.NaN - poweredOn = false - } - - /** - * Default column indices for the extended Bitbrains format. - */ - private val colTimestamp = 0 - private val colCpuUsage = 1 - private val colCpuDemand = 2 - private val colDiskRead = 4 - private val colDiskWrite = 6 - private val colClusterID = 10 - private val colNcpus = 12 - private val colCpuReadyPct = 13 - private val colPoweredOn = 14 - private val colCpuCapacity = 18 - private val colID = 19 - private val colMemCapacity = 20 - private val colCpuUsagePct = 21 - private val colMax = colCpuUsagePct + 1 - - private enum class State { - Pending, - Active, - Closed, - } -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt deleted file mode 100644 index 6115953f..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt +++ /dev/null @@ -1,135 +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. - */ - -package org.opendc.trace.bitbrains - -import org.opendc.trace.TableColumn -import org.opendc.trace.TableColumnType -import org.opendc.trace.TableReader -import org.opendc.trace.TableWriter -import org.opendc.trace.conv.TABLE_RESOURCE_STATES -import org.opendc.trace.conv.resourceClusterID -import org.opendc.trace.conv.resourceCpuCapacity -import org.opendc.trace.conv.resourceCpuCount -import org.opendc.trace.conv.resourceID -import org.opendc.trace.conv.resourceMemCapacity -import org.opendc.trace.conv.resourceStateCpuDemand -import org.opendc.trace.conv.resourceStateCpuReadyPct -import org.opendc.trace.conv.resourceStateCpuUsage -import org.opendc.trace.conv.resourceStateCpuUsagePct -import org.opendc.trace.conv.resourceStateDiskRead -import org.opendc.trace.conv.resourceStateDiskWrite -import org.opendc.trace.conv.resourceStateTimestamp -import org.opendc.trace.spi.TableDetails -import org.opendc.trace.spi.TraceFormat -import org.opendc.trace.util.CompositeTableReader -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.bufferedReader -import kotlin.io.path.extension -import kotlin.io.path.nameWithoutExtension - -/** - * A format implementation for the extended Bitbrains trace format. - */ -public class BitbrainsExTraceFormat : TraceFormat { - /** - * The name of this trace format. - */ - override val name: String = "bitbrains-ex" - - override fun create(path: Path) { - throw UnsupportedOperationException("Writing not supported for this format") - } - - override fun getTables(path: Path): List<String> = listOf(TABLE_RESOURCE_STATES) - - override fun getDetails( - path: Path, - table: String, - ): TableDetails { - return when (table) { - TABLE_RESOURCE_STATES -> - TableDetails( - listOf( - TableColumn(resourceID, TableColumnType.String), - TableColumn(resourceClusterID, TableColumnType.String), - TableColumn(resourceStateTimestamp, TableColumnType.Instant), - TableColumn(resourceCpuCount, TableColumnType.Int), - TableColumn(resourceCpuCapacity, TableColumnType.Double), - TableColumn(resourceStateCpuUsage, TableColumnType.Double), - TableColumn(resourceStateCpuUsagePct, TableColumnType.Double), - TableColumn(resourceStateCpuDemand, TableColumnType.Double), - TableColumn(resourceStateCpuReadyPct, TableColumnType.Double), - TableColumn(resourceMemCapacity, TableColumnType.Double), - TableColumn(resourceStateDiskRead, TableColumnType.Double), - TableColumn(resourceStateDiskWrite, TableColumnType.Double), - ), - ) - else -> throw IllegalArgumentException("Table $table not supported") - } - } - - override fun newReader( - path: Path, - table: String, - projection: List<String>?, - ): TableReader { - return when (table) { - TABLE_RESOURCE_STATES -> newResourceStateReader(path) - else -> throw IllegalArgumentException("Table $table not supported") - } - } - - override fun newWriter( - path: Path, - table: String, - ): TableWriter { - throw UnsupportedOperationException("Writing not supported for this format") - } - - /** - * Construct a [TableReader] for reading over all resource state partitions. - */ - private fun newResourceStateReader(path: Path): TableReader { - val partitions = - Files.walk(path, 1) - .filter { !Files.isDirectory(it) && it.extension == "txt" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - val it = partitions.iterator() - - return object : CompositeTableReader() { - override fun nextReader(): TableReader? { - return if (it.hasNext()) { - val (_, partPath) = it.next() - return BitbrainsExResourceStateTableReader(partPath.bufferedReader()) - } else { - null - } - } - - override fun toString(): String = "BitbrainsExCompositeTableReader" - } - } -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt deleted file mode 100644 index e264fccb..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt +++ /dev/null @@ -1,365 +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. - */ - -package org.opendc.trace.bitbrains - -import com.fasterxml.jackson.core.JsonParseException -import com.fasterxml.jackson.core.JsonToken -import com.fasterxml.jackson.dataformat.csv.CsvParser -import com.fasterxml.jackson.dataformat.csv.CsvSchema -import org.opendc.trace.TableReader -import org.opendc.trace.conv.resourceCpuCapacity -import org.opendc.trace.conv.resourceCpuCount -import org.opendc.trace.conv.resourceID -import org.opendc.trace.conv.resourceMemCapacity -import org.opendc.trace.conv.resourceStateCpuUsage -import org.opendc.trace.conv.resourceStateCpuUsagePct -import org.opendc.trace.conv.resourceStateDiskRead -import org.opendc.trace.conv.resourceStateDiskWrite -import org.opendc.trace.conv.resourceStateMemUsage -import org.opendc.trace.conv.resourceStateNetRx -import org.opendc.trace.conv.resourceStateNetTx -import org.opendc.trace.conv.resourceStateTimestamp -import java.text.NumberFormat -import java.time.Duration -import java.time.Instant -import java.time.LocalDateTime -import java.time.ZoneOffset -import java.time.format.DateTimeFormatter -import java.time.format.DateTimeParseException -import java.util.Locale -import java.util.UUID - -/** - * A [TableReader] for the Bitbrains resource state table. - */ -internal class BitbrainsResourceStateTableReader(private val partition: String, private val parser: CsvParser) : TableReader { - /** - * A flag to indicate whether a single row has been read already. - */ - private var isStarted = false - - /** - * The [DateTimeFormatter] used to parse the timestamps in case of the Materna trace. - */ - private val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss") - - /** - * The type of timestamps in the trace. - */ - private var timestampType: TimestampType = TimestampType.UNDECIDED - - /** - * The [NumberFormat] used to parse doubles containing a comma. - */ - private val nf = NumberFormat.getInstance(Locale.GERMAN) - - /** - * A flag to indicate that the trace contains decimals with a comma separator. - */ - private var usesCommaDecimalSeparator = false - - init { - parser.schema = schema - } - - override fun nextRow(): Boolean { - if (!isStarted) { - isStarted = true - } - - // Reset the row state - reset() - - if (!nextStart()) { - return false - } - - while (true) { - val token = parser.nextValue() - - if (token == null || token == JsonToken.END_OBJECT) { - break - } - - when (parser.currentName) { - "Timestamp [ms]" -> { - timestamp = - when (timestampType) { - TimestampType.UNDECIDED -> { - try { - val res = LocalDateTime.parse(parser.text, formatter).toInstant(ZoneOffset.UTC) - timestampType = TimestampType.DATE_TIME - res - } catch (e: DateTimeParseException) { - timestampType = TimestampType.EPOCH_MILLIS - Instant.ofEpochSecond(parser.longValue) - } - } - TimestampType.DATE_TIME -> LocalDateTime.parse(parser.text, formatter).toInstant(ZoneOffset.UTC) - TimestampType.EPOCH_MILLIS -> Instant.ofEpochSecond(parser.longValue) - } - } - "CPU cores" -> cpuCores = parser.intValue - "CPU capacity provisioned [MHZ]" -> cpuCapacity = parseSafeDouble() - "CPU usage [MHZ]" -> cpuUsage = parseSafeDouble() - "CPU usage [%]" -> cpuUsagePct = parseSafeDouble() / 100.0 // Convert to range [0, 1] - "Memory capacity provisioned [KB]" -> memCapacity = parseSafeDouble() - "Memory usage [KB]" -> memUsage = parseSafeDouble() - "Disk read throughput [KB/s]" -> diskRead = parseSafeDouble() - "Disk write throughput [KB/s]" -> diskWrite = parseSafeDouble() - "Network received throughput [KB/s]" -> netReceived = parseSafeDouble() - "Network transmitted throughput [KB/s]" -> netTransmitted = parseSafeDouble() - } - } - - return true - } - - private val colTimestamp = 0 - private val colCpuCount = 1 - private val colCpuCapacity = 2 - private val colCpuUsage = 3 - private val colCpuUsagePct = 4 - private val colMemCapacity = 5 - private val colMemUsage = 6 - private val colDiskRead = 7 - private val colDiskWrite = 8 - private val colNetRx = 9 - private val colNetTx = 10 - private val colID = 11 - - override fun resolve(name: String): Int { - return when (name) { - resourceID -> colID - resourceStateTimestamp -> colTimestamp - resourceCpuCount -> colCpuCount - resourceCpuCapacity -> colCpuCapacity - resourceStateCpuUsage -> colCpuUsage - resourceStateCpuUsagePct -> colCpuUsagePct - resourceMemCapacity -> colMemCapacity - resourceStateMemUsage -> colMemUsage - resourceStateDiskRead -> colDiskRead - resourceStateDiskWrite -> colDiskWrite - resourceStateNetRx -> colNetRx - resourceStateNetTx -> colNetTx - else -> -1 - } - } - - override fun isNull(index: Int): Boolean { - require(index in 0..colID) { "Invalid column index" } - return false - } - - override fun getBoolean(index: Int): Boolean { - throw IllegalArgumentException("Invalid column") - } - - override fun getInt(index: Int): Int { - checkActive() - return when (index) { - colCpuCount -> cpuCores - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getLong(index: Int): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getFloat(index: Int): Float { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(index: Int): Double { - checkActive() - return when (index) { - colCpuCapacity -> cpuCapacity - colCpuUsage -> cpuUsage - colCpuUsagePct -> cpuUsagePct - colMemCapacity -> memCapacity - colMemUsage -> memUsage - colDiskRead -> diskRead - colDiskWrite -> diskWrite - colNetRx -> netReceived - colNetTx -> netTransmitted - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getString(index: Int): String { - checkActive() - return when (index) { - colID -> partition - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getUUID(index: Int): UUID? { - throw IllegalArgumentException("Invalid column") - } - - override fun getInstant(index: Int): Instant? { - checkActive() - return when (index) { - colTimestamp -> timestamp - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getDuration(index: Int): Duration? { - throw IllegalArgumentException("Invalid column") - } - - override fun <T> getList( - index: Int, - elementType: Class<T>, - ): List<T>? { - throw IllegalArgumentException("Invalid column") - } - - override fun <T> getSet( - index: Int, - elementType: Class<T>, - ): Set<T>? { - throw IllegalArgumentException("Invalid column") - } - - override fun <K, V> getMap( - index: Int, - keyType: Class<K>, - valueType: Class<V>, - ): Map<K, V>? { - throw IllegalArgumentException("Invalid column") - } - - override fun close() { - parser.close() - } - - /** - * Helper method to check if the reader is active. - */ - private fun checkActive() { - check(isStarted && !parser.isClosed) { "No active row. Did you call nextRow()?" } - } - - /** - * Advance the parser until the next object start. - */ - private fun nextStart(): Boolean { - var token = parser.nextValue() - - while (token != null && token != JsonToken.START_OBJECT) { - token = parser.nextValue() - } - - return token != null - } - - /** - * Try to parse the current value safely as double. - */ - private fun parseSafeDouble(): Double { - if (!usesCommaDecimalSeparator) { - try { - return parser.doubleValue - } catch (e: JsonParseException) { - usesCommaDecimalSeparator = true - } - } - - val text = parser.text - if (text.isBlank()) { - return 0.0 - } - - return nf.parse(text).toDouble() - } - - /** - * State fields of the reader. - */ - private var timestamp: Instant? = null - private var cpuCores = -1 - private var cpuCapacity = Double.NaN - private var cpuUsage = Double.NaN - private var cpuUsagePct = Double.NaN - private var memCapacity = Double.NaN - private var memUsage = Double.NaN - private var diskRead = Double.NaN - private var diskWrite = Double.NaN - private var netReceived = Double.NaN - private var netTransmitted = Double.NaN - - /** - * Reset the state. - */ - private fun reset() { - timestamp = null - cpuCores = -1 - cpuCapacity = Double.NaN - cpuUsage = Double.NaN - cpuUsagePct = Double.NaN - memCapacity = Double.NaN - memUsage = Double.NaN - diskRead = Double.NaN - diskWrite = Double.NaN - netReceived = Double.NaN - netTransmitted = Double.NaN - } - - /** - * The type of the timestamp in the trace. - */ - private enum class TimestampType { - UNDECIDED, - DATE_TIME, - EPOCH_MILLIS, - } - - companion object { - /** - * The [CsvSchema] that is used to parse the trace. - */ - private val schema = - CsvSchema.builder() - .addColumn("Timestamp [ms]", CsvSchema.ColumnType.NUMBER_OR_STRING) - .addColumn("CPU cores", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU capacity provisioned [MHZ]", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU usage [MHZ]", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU usage [%]", CsvSchema.ColumnType.NUMBER) - .addColumn("Memory capacity provisioned [KB]", CsvSchema.ColumnType.NUMBER) - .addColumn("Memory usage [KB]", CsvSchema.ColumnType.NUMBER) - .addColumn("Memory usage [%]", CsvSchema.ColumnType.NUMBER) - .addColumn("Disk read throughput [KB/s]", CsvSchema.ColumnType.NUMBER) - .addColumn("Disk write throughput [KB/s]", CsvSchema.ColumnType.NUMBER) - .addColumn("Disk size [GB]", CsvSchema.ColumnType.NUMBER) - .addColumn("Network received throughput [KB/s]", CsvSchema.ColumnType.NUMBER) - .addColumn("Network transmitted throughput [KB/s]", CsvSchema.ColumnType.NUMBER) - .setAllowComments(true) - .setUseHeader(true) - .setColumnSeparator(';') - .build() - } -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt deleted file mode 100644 index a12785f0..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt +++ /dev/null @@ -1,175 +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. - */ - -package org.opendc.trace.bitbrains - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.TableReader -import org.opendc.trace.conv.resourceID -import java.nio.file.Path -import java.time.Duration -import java.time.Instant -import java.util.UUID - -/** - * A [TableReader] for the Bitbrains resource table. - */ -internal class BitbrainsResourceTableReader(private val factory: CsvFactory, vms: Map<String, Path>) : TableReader { - /** - * An iterator to iterate over the resource entries. - */ - private val it = vms.iterator() - - /** - * The state of the reader. - */ - private var state = State.Pending - - override fun nextRow(): Boolean { - if (state == State.Pending) { - state = State.Active - } - - reset() - - while (it.hasNext()) { - val (name, path) = it.next() - - val parser = factory.createParser(path.toFile()) - val reader = BitbrainsResourceStateTableReader(name, parser) - val idCol = reader.resolve(resourceID) - - try { - if (!reader.nextRow()) { - continue - } - - id = reader.getString(idCol) - return true - } finally { - reader.close() - } - } - - state = State.Closed - return false - } - - private val colID = 0 - - override fun resolve(name: String): Int { - return when (name) { - resourceID -> colID - else -> -1 - } - } - - override fun isNull(index: Int): Boolean { - require(index in 0..colID) { "Invalid column index" } - return false - } - - override fun getBoolean(index: Int): Boolean { - throw IllegalArgumentException("Invalid column") - } - - override fun getInt(index: Int): Int { - throw IllegalArgumentException("Invalid column") - } - - override fun getLong(index: Int): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getFloat(index: Int): Float { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(index: Int): Double { - throw IllegalArgumentException("Invalid column") - } - - override fun getString(index: Int): String? { - check(state == State.Active) { "No active row" } - return when (index) { - colID -> id - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getUUID(index: Int): UUID? { - throw IllegalArgumentException("Invalid column") - } - - override fun getInstant(index: Int): Instant? { - throw IllegalArgumentException("Invalid column") - } - - override fun getDuration(index: Int): Duration? { - throw IllegalArgumentException("Invalid column") - } - - override fun <T> getList( - index: Int, - elementType: Class<T>, - ): List<T>? { - throw IllegalArgumentException("Invalid column") - } - - override fun <T> getSet( - index: Int, - elementType: Class<T>, - ): Set<T>? { - throw IllegalArgumentException("Invalid column") - } - - override fun <K, V> getMap( - index: Int, - keyType: Class<K>, - valueType: Class<V>, - ): Map<K, V>? { - throw IllegalArgumentException("Invalid column") - } - - override fun close() { - reset() - state = State.Closed - } - - /** - * State fields of the reader. - */ - private var id: String? = null - - /** - * Reset the state of the reader. - */ - private fun reset() { - id = null - } - - private enum class State { - Pending, - Active, - Closed, - } -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt deleted file mode 100644 index 23853077..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt +++ /dev/null @@ -1,159 +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. - */ - -package org.opendc.trace.bitbrains - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import com.fasterxml.jackson.dataformat.csv.CsvParser -import org.opendc.trace.TableColumn -import org.opendc.trace.TableColumnType -import org.opendc.trace.TableReader -import org.opendc.trace.TableWriter -import org.opendc.trace.conv.TABLE_RESOURCES -import org.opendc.trace.conv.TABLE_RESOURCE_STATES -import org.opendc.trace.conv.resourceCpuCapacity -import org.opendc.trace.conv.resourceCpuCount -import org.opendc.trace.conv.resourceID -import org.opendc.trace.conv.resourceMemCapacity -import org.opendc.trace.conv.resourceStateCpuUsage -import org.opendc.trace.conv.resourceStateCpuUsagePct -import org.opendc.trace.conv.resourceStateDiskRead -import org.opendc.trace.conv.resourceStateDiskWrite -import org.opendc.trace.conv.resourceStateMemUsage -import org.opendc.trace.conv.resourceStateNetRx -import org.opendc.trace.conv.resourceStateNetTx -import org.opendc.trace.conv.resourceStateTimestamp -import org.opendc.trace.spi.TableDetails -import org.opendc.trace.spi.TraceFormat -import org.opendc.trace.util.CompositeTableReader -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.extension -import kotlin.io.path.nameWithoutExtension - -/** - * A format implementation for the GWF trace format. - */ -public class BitbrainsTraceFormat : TraceFormat { - /** - * The name of this trace format. - */ - override val name: String = "bitbrains" - - /** - * The [CsvFactory] used to create the parser. - */ - private val factory = - CsvFactory() - .enable(CsvParser.Feature.ALLOW_COMMENTS) - .enable(CsvParser.Feature.TRIM_SPACES) - - override fun create(path: Path) { - throw UnsupportedOperationException("Writing not supported for this format") - } - - override fun getTables(path: Path): List<String> = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) - - override fun getDetails( - path: Path, - table: String, - ): TableDetails { - return when (table) { - TABLE_RESOURCES -> - TableDetails( - listOf( - TableColumn(resourceID, TableColumnType.String), - ), - ) - TABLE_RESOURCE_STATES -> - TableDetails( - listOf( - TableColumn(resourceID, TableColumnType.String), - TableColumn(resourceStateTimestamp, TableColumnType.Instant), - TableColumn(resourceCpuCount, TableColumnType.Int), - TableColumn(resourceCpuCapacity, TableColumnType.Double), - TableColumn(resourceStateCpuUsage, TableColumnType.Double), - TableColumn(resourceStateCpuUsagePct, TableColumnType.Double), - TableColumn(resourceMemCapacity, TableColumnType.Double), - TableColumn(resourceStateMemUsage, TableColumnType.Double), - TableColumn(resourceStateDiskRead, TableColumnType.Double), - TableColumn(resourceStateDiskWrite, TableColumnType.Double), - TableColumn(resourceStateNetRx, TableColumnType.Double), - TableColumn(resourceStateNetTx, TableColumnType.Double), - ), - ) - else -> throw IllegalArgumentException("Table $table not supported") - } - } - - override fun newReader( - path: Path, - table: String, - projection: List<String>?, - ): TableReader { - return when (table) { - TABLE_RESOURCES -> { - val vms = - Files.walk(path, 1) - .filter { !Files.isDirectory(it) && it.extension == "csv" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - BitbrainsResourceTableReader(factory, vms) - } - TABLE_RESOURCE_STATES -> newResourceStateReader(path) - else -> throw IllegalArgumentException("Table $table not supported") - } - } - - override fun newWriter( - path: Path, - table: String, - ): TableWriter { - throw UnsupportedOperationException("Writing not supported for this format") - } - - /** - * Construct a [TableReader] for reading over all resource state partitions. - */ - private fun newResourceStateReader(path: Path): TableReader { - val partitions = - Files.walk(path, 1) - .filter { !Files.isDirectory(it) && it.extension == "csv" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - val it = partitions.iterator() - - return object : CompositeTableReader() { - override fun nextReader(): TableReader? { - return if (it.hasNext()) { - val (partition, partPath) = it.next() - return BitbrainsResourceStateTableReader(partition, factory.createParser(partPath.toFile())) - } else { - null - } - } - - override fun toString(): String = "BitbrainsCompositeTableReader" - } - } -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat deleted file mode 100644 index fd6a2180..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat +++ /dev/null @@ -1,2 +0,0 @@ -org.opendc.trace.bitbrains.BitbrainsTraceFormat -org.opendc.trace.bitbrains.BitbrainsExTraceFormat |
