Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: Fix time step backward for Stopwatch::elapsedFromLastTime (#8338) #8343

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions dbms/src/Common/Stopwatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ inline UInt64 clock_gettime_ns(clockid_t clock_type = CLOCK_MONOTONIC)
{
};
clock_gettime(clock_type, &ts);
return UInt64(ts.tv_sec * 1000000000ULL + ts.tv_nsec);
return static_cast<UInt64>(ts.tv_sec * 1000000000ULL + ts.tv_nsec);
}

/// Sometimes monotonic clock may not be monotonic (due to bug in kernel?).
Expand Down Expand Up @@ -64,14 +64,14 @@ class Stopwatch

void start()
{
start_ns = nanoseconds();
start_ns = nanosecondsWithBound(start_ns);
last_ns = start_ns;
is_running = true;
}

void stop()
{
stop_ns = nanoseconds();
stop_ns = nanosecondsWithBound(start_ns);
is_running = false;
}

Expand All @@ -82,14 +82,16 @@ class Stopwatch
last_ns = 0;
is_running = false;
}

void restart() { start(); }
UInt64 elapsed() const { return is_running ? nanoseconds() - start_ns : stop_ns - start_ns; }

UInt64 elapsed() const { return is_running ? nanosecondsWithBound(start_ns) - start_ns : stop_ns - start_ns; }
UInt64 elapsedMilliseconds() const { return elapsed() / 1000000UL; }
double elapsedSeconds() const { return static_cast<double>(elapsed()) / 1000000000ULL; }

UInt64 elapsedFromLastTime()
{
const auto now_ns = nanoseconds();
const auto now_ns = nanosecondsWithBound(last_ns);
if (is_running)
{
auto rc = now_ns - last_ns;
Expand All @@ -100,7 +102,7 @@ class Stopwatch
{
return stop_ns - last_ns;
}
};
}

UInt64 elapsedMillisecondsFromLastTime() { return elapsedFromLastTime() / 1000000UL; }
UInt64 elapsedSecondsFromLastTime() { return elapsedFromLastTime() / 1000000UL; }
Expand All @@ -112,7 +114,9 @@ class Stopwatch
clockid_t clock_type;
bool is_running = false;

UInt64 nanoseconds() const { return clock_gettime_ns_adjusted(start_ns, clock_type); }
// Get current nano seconds, ensuring the return value is not
// less than `lower_bound`.
UInt64 nanosecondsWithBound(UInt64 lower_bound) const { return clock_gettime_ns_adjusted(lower_bound, clock_type); }
};


Expand Down
9 changes: 6 additions & 3 deletions dbms/src/TestUtils/FunctionTestUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,13 @@ ColumnWithTypeAndName executeFunction(
for (size_t i = 0; i < columns.size(); ++i)
argument_column_numbers.push_back(i);

/// Replace `std::random_device` with `std::chrono::system_clock` here to avoid
/// exceptions like 'random_device failed to open /dev/urandom: Operation not permitted'.
/// The reason of exceptions is unknown, but the probability of its occurrence in unittests
/// TestDateTimeDayMonthYear.dayMonthYearTest is not low.
/// Since this function is just used for testing, using current timestamp as a random seed is not a problem.
std::mt19937 g(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
/// shuffle input columns to assure function correctly use physical offsets instead of logical offsets
std::random_device rd;
std::mt19937 g(rd());

std::shuffle(argument_column_numbers.begin(), argument_column_numbers.end(), g);
const auto columns_reordered = toColumnsReordered(columns, argument_column_numbers);

Expand Down