diff --git a/velox/common/io/IoStatistics.h b/velox/common/io/IoStatistics.h index e1d72afc9cfe..99936d408163 100644 --- a/velox/common/io/IoStatistics.h +++ b/velox/common/io/IoStatistics.h @@ -48,19 +48,42 @@ class IoCounter { return sum_; } + uint64_t min() const { + return min_; + } + + uint64_t max() const { + return max_; + } + void increment(uint64_t amount) { ++count_; sum_ += amount; + casLoop(min_, amount, std::greater()); + casLoop(max_, amount, std::less()); } void merge(const IoCounter& other) { sum_ += other.sum_; count_ += other.count_; + casLoop(min_, other.min_, std::greater()); + casLoop(max_, other.max_, std::less()); } private: + template + static void + casLoop(std::atomic& value, uint64_t newValue, Compare compare) { + uint64_t old = value; + while (compare(old, newValue) && + !value.compare_exchange_weak(old, newValue)) { + } + } + std::atomic count_{0}; std::atomic sum_{0}; + std::atomic min_{std::numeric_limits::max()}; + std::atomic max_{0}; }; class IoStatistics { diff --git a/velox/connectors/hive/HiveDataSource.cpp b/velox/connectors/hive/HiveDataSource.cpp index 448f673ac65a..994ce248cb79 100644 --- a/velox/connectors/hive/HiveDataSource.cpp +++ b/velox/connectors/hive/HiveDataSource.cpp @@ -683,6 +683,10 @@ std::unordered_map HiveDataSource::runtimeStats() { RuntimeCounter( ioStats_->queryThreadIoLatency().sum() * 1000, RuntimeCounter::Unit::kNanos)}, + {"maxSingleIoWaitNanos", + RuntimeCounter( + ioStats_->queryThreadIoLatency().max() * 1000, + RuntimeCounter::Unit::kNanos)}, {"overreadBytes", RuntimeCounter( ioStats_->rawOverreadBytes(), RuntimeCounter::Unit::kBytes)}, diff --git a/velox/exec/tests/PrintPlanWithStatsTest.cpp b/velox/exec/tests/PrintPlanWithStatsTest.cpp index f61f64d1b67f..ae70387e4f1d 100644 --- a/velox/exec/tests/PrintPlanWithStatsTest.cpp +++ b/velox/exec/tests/PrintPlanWithStatsTest.cpp @@ -190,6 +190,7 @@ TEST_F(PrintPlanWithStatsTest, innerJoinWithTableScan) { {" flattenStringDictionaryValues [ ]* sum: 0, count: 1, min: 0, max: 0"}, {" ioWaitNanos [ ]* sum: .+, count: .+ min: .+, max: .+"}, {" localReadBytes [ ]* sum: 0B, count: 1, min: 0B, max: 0B"}, + {" maxSingleIoWaitNanos[ ]*sum: .+, count: 1, min: .+, max: .+"}, {" numLocalRead [ ]* sum: 0, count: 1, min: 0, max: 0"}, {" numPrefetch [ ]* sum: .+, count: 1, min: .+, max: .+"}, {" numRamRead [ ]* sum: 40, count: 1, min: 40, max: 40"}, @@ -283,6 +284,7 @@ TEST_F(PrintPlanWithStatsTest, partialAggregateWithTableScan) { {" flattenStringDictionaryValues [ ]* sum: 0, count: 1, min: 0, max: 0"}, {" ioWaitNanos [ ]* sum: .+, count: .+ min: .+, max: .+"}, {" localReadBytes [ ]* sum: 0B, count: 1, min: 0B, max: 0B"}, + {" maxSingleIoWaitNanos[ ]*sum: .+, count: 1, min: .+, max: .+"}, {" numLocalRead [ ]* sum: 0, count: 1, min: 0, max: 0"}, {" numPrefetch [ ]* sum: .+, count: .+, min: .+, max: .+"}, {" numRamRead [ ]* sum: 6, count: 1, min: 6, max: 6"},