From efa48d5e624ef61b98423932cd003d70709c448a Mon Sep 17 00:00:00 2001 From: Bulat Date: Mon, 8 Apr 2024 20:56:22 +0300 Subject: [PATCH] Removed excess time utils (#140) --- client/impl/ydb_internal/retry/retry.h | 7 +- client/impl/ydb_internal/retry/retry_async.h | 2 +- client/impl/ydb_internal/retry/retry_sync.h | 2 +- util/CMakeLists.txt | 1 - util/datetime/cputimer.cpp | 117 +--------- util/datetime/cputimer.h | 107 +-------- util/draft/CMakeLists.txt | 11 - util/draft/date.cpp | 113 --------- util/draft/date.h | 129 ---------- util/draft/date_ut.cpp | 36 --- util/draft/datetime.cpp | 234 ------------------- util/draft/datetime.h | 183 --------------- util/draft/datetime_ut.cpp | 231 ------------------ util/draft/enum.cpp | 1 - util/draft/enum.h | 135 ----------- util/draft/holder_vector.cpp | 1 - util/draft/holder_vector.h | 103 -------- util/draft/holder_vector_ut.cpp | 69 ------ util/draft/ip.cpp | 1 - util/draft/ip.h | 131 ----------- util/draft/matrix.cpp | 1 - util/draft/matrix.h | 108 --------- util/draft/memory.cpp | 1 - util/draft/memory.h | 40 ---- util/draft/memory_ut.cpp | 69 ------ util/draft/ut/ya.make | 20 -- 26 files changed, 20 insertions(+), 1833 deletions(-) delete mode 100644 util/draft/CMakeLists.txt delete mode 100644 util/draft/date.cpp delete mode 100644 util/draft/date.h delete mode 100644 util/draft/date_ut.cpp delete mode 100644 util/draft/datetime.cpp delete mode 100644 util/draft/datetime.h delete mode 100644 util/draft/datetime_ut.cpp delete mode 100644 util/draft/enum.cpp delete mode 100644 util/draft/enum.h delete mode 100644 util/draft/holder_vector.cpp delete mode 100644 util/draft/holder_vector.h delete mode 100644 util/draft/holder_vector_ut.cpp delete mode 100644 util/draft/ip.cpp delete mode 100644 util/draft/ip.h delete mode 100644 util/draft/matrix.cpp delete mode 100644 util/draft/matrix.h delete mode 100644 util/draft/memory.cpp delete mode 100644 util/draft/memory.h delete mode 100644 util/draft/memory_ut.cpp delete mode 100644 util/draft/ut/ya.make diff --git a/client/impl/ydb_internal/retry/retry.h b/client/impl/ydb_internal/retry/retry.h index 2695d379888..0a607f3718b 100644 --- a/client/impl/ydb_internal/retry/retry.h +++ b/client/impl/ydb_internal/retry/retry.h @@ -35,12 +35,13 @@ class TRetryContextBase : TNonCopyable { protected: TRetryOperationSettings Settings_; ui32 RetryNumber_; - TSimpleTimer RetryTimer_; + TInstant RetryStartTime_; protected: TRetryContextBase(const TRetryOperationSettings& settings) : Settings_(settings) , RetryNumber_(0) + , RetryStartTime_(TInstant::Now()) {} virtual void Reset() {} @@ -60,7 +61,7 @@ class TRetryContextBase : TNonCopyable { if (RetryNumber_ >= Settings_.MaxRetries_) { return NextStep::Finish; } - if (RetryTimer_.Get() >= Settings_.MaxTimeout_) { + if (TInstant::Now() - RetryStartTime_ >= Settings_.MaxTimeout_) { return NextStep::Finish; } switch (status.GetStatus()) { @@ -107,7 +108,7 @@ class TRetryContextBase : TNonCopyable { } TDuration GetRemainingTimeout() { - return Settings_.MaxTimeout_ - RetryTimer_.Get(); + return Settings_.MaxTimeout_ - (TInstant::Now() - RetryStartTime_); } }; diff --git a/client/impl/ydb_internal/retry/retry_async.h b/client/impl/ydb_internal/retry/retry_async.h index c939a128356..6859854ecb0 100644 --- a/client/impl/ydb_internal/retry/retry_async.h +++ b/client/impl/ydb_internal/retry/retry_async.h @@ -18,7 +18,7 @@ class TRetryContext : public TThrRefBase, public TRetryContextBase { public: TAsyncStatusType Execute() { - this->RetryTimer_.Reset(); + this->RetryStartTime_ = TInstant::Now(); this->Retry(); return this->Promise_.GetFuture(); } diff --git a/client/impl/ydb_internal/retry/retry_sync.h b/client/impl/ydb_internal/retry/retry_sync.h index 51094817a95..56c9051bd0f 100644 --- a/client/impl/ydb_internal/retry/retry_sync.h +++ b/client/impl/ydb_internal/retry/retry_sync.h @@ -13,7 +13,7 @@ class TRetryContext : public TRetryContextBase { public: TStatusType Execute() { - this->RetryTimer_.Reset(); + this->RetryStartTime_ = TInstant::Now(); TStatusType status = Retry(); // first attempt for (this->RetryNumber_ = 0; this->RetryNumber_ <= this->Settings_.MaxRetries_;) { auto nextStep = this->GetNextStep(status); diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index 729624e2a29..504f3b06d8c 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -1,5 +1,4 @@ add_subdirectory(charset) -add_subdirectory(draft) add_library(yutil) target_compile_options(yutil PRIVATE diff --git a/util/datetime/cputimer.cpp b/util/datetime/cputimer.cpp index 2fb22682e98..04f95341f7a 100644 --- a/util/datetime/cputimer.cpp +++ b/util/datetime/cputimer.cpp @@ -5,133 +5,26 @@ #include #include -#include #include -#if defined(_unix_) - #include - #include -#elif defined(_win_) - #include -#endif - TTimer::TTimer(const std::string_view message) { - static const int SMALL_DURATION_CHAR_LENGTH = 9; // strlen("0.123456s") - Message_.Reserve(message.length() + SMALL_DURATION_CHAR_LENGTH + 1); // +"\n" Message_ << message; - // Do not measure the allocations above. - Start_ = TInstant::Now(); + Start_ = Clock_.now(); } TTimer::~TTimer() { - const TDuration duration = TInstant::Now() - Start_; + const TClock::duration duration = Clock_.now() - Start_; Message_ << duration << "\n"; - std::cerr << Message_.Str(); -} - -static ui64 ManuallySetCyclesPerSecond = 0; - -static ui64 GetCyclesPerSecond() { - if (ManuallySetCyclesPerSecond != 0) { - return ManuallySetCyclesPerSecond; - } else { - return NHPTimer::GetCyclesPerSecond(); - } -} - -void SetCyclesPerSecond(ui64 cycles) { - ManuallySetCyclesPerSecond = cycles; -} - -ui64 GetCyclesPerMillisecond() { - return GetCyclesPerSecond() / 1000; -} - -TDuration CyclesToDuration(ui64 cycles) { - return TDuration::MicroSeconds(cycles * 1000000 / GetCyclesPerSecond()); -} - -TDuration CyclesToDurationSafe(ui64 cycles) -{ - constexpr ui64 cyclesLimit = std::numeric_limits::max() / 1000000; - if (cycles <= cyclesLimit) { - return CyclesToDuration(cycles); - } - return TDuration::MicroSeconds(cycles / GetCyclesPerSecond() * 1000000); -} - -ui64 DurationToCycles(TDuration duration) { - return duration.MicroSeconds() * GetCyclesPerSecond() / 1000000; -} - -ui64 DurationToCyclesSafe(TDuration duration) -{ - if (duration.MicroSeconds() <= std::numeric_limits::max() / GetCyclesPerSecond()) { - return DurationToCycles(duration); - } - return duration.MicroSeconds() / 1000000 * GetCyclesPerSecond(); -} - -TPrecisionTimer::TPrecisionTimer() - : Start(::GetCycleCount()) -{ -} - -ui64 TPrecisionTimer::GetCycleCount() const { - return ::GetCycleCount() - Start; -} - -std::string FormatCycles(ui64 cycles) { - ui64 milliseconds = cycles / GetCyclesPerMillisecond(); - ui32 ms = ui32(milliseconds % 1000); - milliseconds /= 1000; - ui32 secs = ui32(milliseconds % 60); - milliseconds /= 60; - ui32 mins = ui32(milliseconds); - std::string result = std::format("%" PRIu32 " m %.2" PRIu32 " s %.3" PRIu32 " ms", mins, secs, ms); - return result; + std::cerr << Message_.str(); } TFuncTimer::TFuncTimer(const char* func) - : Start_(TInstant::Now()) + : Start_(Clock_.now()) , Func_(func) { std::cerr << "enter " << Func_ << std::endl; } TFuncTimer::~TFuncTimer() { - std::cerr << "leave " << Func_ << " -> " << (TInstant::Now() - Start_).ToString() << std::endl; -} - -TTimeLogger::TTimeLogger(const std::string& message, bool verbose) - : Message(message) - , Verbose(verbose) - , OK(false) - , Begin(time(nullptr)) - , BeginCycles(GetCycleCount()) -{ - if (Verbose) { - fprintf(stderr, "=========================================================\n"); - fprintf(stderr, "%s started: %.24s (%lu) (%d)\n", Message.data(), ctime(&Begin), (unsigned long)Begin, (int)getpid()); - } -} - -double TTimeLogger::ElapsedTime() const { - return time(nullptr) - Begin; -} - -void TTimeLogger::SetOK() { - OK = true; -} - -TTimeLogger::~TTimeLogger() { - time_t tim = time(nullptr); - ui64 endCycles = GetCycleCount(); - if (Verbose) { - const char* prefix = (OK) ? "" : "!"; - fprintf(stderr, "%s%s ended: %.24s (%lu) (%d) (took %lus = %s)\n", - prefix, Message.data(), ctime(&tim), (unsigned long)tim, (int)getpid(), - (unsigned long)tim - (unsigned long)Begin, FormatCycles(endCycles - BeginCycles).data()); - fprintf(stderr, "%s=========================================================\n", prefix); - } + std::cerr << "leave " << Func_ << " -> " << Clock_.now() - Start_ << std::endl; } diff --git a/util/datetime/cputimer.h b/util/datetime/cputimer.h index 604607393d1..4c61bb3035d 100644 --- a/util/datetime/cputimer.h +++ b/util/datetime/cputimer.h @@ -1,116 +1,27 @@ #pragma once -#include "base.h" - -#include -#include +#include class TTimer { -private: - TInstant Start_; - TStringStream Message_; + using TClock = std::chrono::high_resolution_clock; + + TClock Clock_; + std::chrono::time_point Start_; + std::stringstream Message_; public: TTimer(const std::string_view message = " took: "); ~TTimer(); }; -class TSimpleTimer { - TInstant T; - -public: - TSimpleTimer() { - Reset(); - } - TDuration Get() const { - return TInstant::Now() - T; - } - void Reset() { - T = TInstant::Now(); - } -}; - -class TProfileTimer { - TDuration T; - -public: - TProfileTimer() { - Reset(); - } - TDuration Get() const { - return TRusage::Get().Utime - T; - } - TDuration Step() { - TRusage r; - r.Fill(); - TDuration d = r.Utime - T; - T = r.Utime; - return d; - } - void Reset() { - T = TRusage::Get().Utime; - } -}; - -/// Return cached processor cycle count per second. Method takes 1 second at first invocation. -/// Note, on older systems cycle rate may change during program lifetime, -/// so returned value may be incorrect. Modern Intel and AMD processors keep constant TSC rate. -ui64 GetCyclesPerMillisecond(); -void SetCyclesPerSecond(ui64 cycles); - -TDuration CyclesToDuration(ui64 cycles); -ui64 DurationToCycles(TDuration duration); - -// NBS-3400 - CyclesToDuration and DurationToCycles may overflow for long running events -TDuration CyclesToDurationSafe(ui64 cycles); -ui64 DurationToCyclesSafe(TDuration duration); - -class TPrecisionTimer { -private: - ui64 Start = 0; - -public: - TPrecisionTimer(); - - ui64 GetCycleCount() const; -}; - -std::string FormatCycles(ui64 cycles); - class TFuncTimer { + using TClock = std::chrono::high_resolution_clock; public: TFuncTimer(const char* func); ~TFuncTimer(); private: - const TInstant Start_; + TClock Clock_; + const std::chrono::time_point Start_; const char* Func_; }; - -class TFakeTimer { -public: - inline TFakeTimer(const char* = nullptr) noexcept { - } -}; - -#if defined(WITH_DEBUG) - #define TDebugTimer TFuncTimer -#else - #define TDebugTimer TFakeTimer -#endif - -class TTimeLogger { -private: - std::string Message; - bool Verbose; - bool OK; - time_t Begin; - ui64 BeginCycles; - -public: - TTimeLogger(const std::string& message, bool verbose = true); - ~TTimeLogger(); - - void SetOK(); - double ElapsedTime() const; -}; diff --git a/util/draft/CMakeLists.txt b/util/draft/CMakeLists.txt deleted file mode 100644 index ccf604445f9..00000000000 --- a/util/draft/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -add_library(util-draft) - -target_sources(util-draft PRIVATE - ${CMAKE_SOURCE_DIR}/util/draft/date.cpp - ${CMAKE_SOURCE_DIR}/util/draft/datetime.cpp - ${CMAKE_SOURCE_DIR}/util/draft/enum.cpp - ${CMAKE_SOURCE_DIR}/util/draft/holder_vector.cpp - ${CMAKE_SOURCE_DIR}/util/draft/ip.cpp - ${CMAKE_SOURCE_DIR}/util/draft/matrix.cpp - ${CMAKE_SOURCE_DIR}/util/draft/memory.cpp -) diff --git a/util/draft/date.cpp b/util/draft/date.cpp deleted file mode 100644 index 2ab73602f37..00000000000 --- a/util/draft/date.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "date.h" - -#include -#include -#include - -time_t GetDateStart(time_t ts) { - tm dateTm; - memset(&dateTm, 0, sizeof(tm)); - localtime_r(&ts, &dateTm); - - dateTm.tm_isdst = -1; - - dateTm.tm_sec = 0; - dateTm.tm_min = 0; - dateTm.tm_hour = 0; - return mktime(&dateTm); -} - -static time_t ParseDate(const char* date, const char* format) { - tm dateTm; - memset(&dateTm, 0, sizeof(tm)); - if (!strptime(date, format, &dateTm)) { - ythrow yexception() << "Invalid date string and format: " << date << ", " << format; - } - return mktime(&dateTm); -} - -static time_t ParseDate(const char* dateStr) { - if (strlen(dateStr) != 8) { - ythrow yexception() << "Invalid date string: " << dateStr; - } - - return ParseDate(dateStr, "%Y%m%d"); -} - -template <> -TDate FromStringImpl(const char* data, size_t len) { - return TDate(ParseDate(std::string(data, len).data())); -} - -TDate::TDate(const char* yyyymmdd) - : Timestamp(GetDateStart(ParseDate(yyyymmdd))) -{ -} - -TDate::TDate(const std::string& yyyymmdd) - : Timestamp(GetDateStart(ParseDate(yyyymmdd.c_str()))) -{ -} - -TDate::TDate(time_t ts) - : Timestamp(GetDateStart(ts)) -{ -} - -TDate::TDate(const std::string& date, const std::string& format) - : Timestamp(GetDateStart(ParseDate(date.data(), format.data()))) -{ -} - -TDate::TDate(unsigned year, unsigned month, unsigned monthDay) { - tm dateTm; - Zero(dateTm); - dateTm.tm_year = year - 1900; - dateTm.tm_mon = month - 1; - dateTm.tm_mday = monthDay; - dateTm.tm_isdst = -1; - Timestamp = mktime(&dateTm); - if (Timestamp == (time_t)-1) { - ythrow yexception() << "Invalid TDate args:(" << year << ',' << month << ',' << monthDay << ')'; - } -} - -time_t TDate::GetStartUTC() const { - tm dateTm; - localtime_r(&Timestamp, &dateTm); - dateTm.tm_isdst = -1; - dateTm.tm_sec = 0; - dateTm.tm_min = 0; - dateTm.tm_hour = 0; - return TimeGM(&dateTm); -} - -std::string TDate::ToStroka(const char* format) const { - tm dateTm; - localtime_r(&Timestamp, &dateTm); - return Strftime(format, &dateTm); -} - -unsigned TDate::GetWeekDay() const { - tm dateTm; - localtime_r(&Timestamp, &dateTm); - return (unsigned)dateTm.tm_wday; -} - -unsigned TDate::GetYear() const { - tm dateTm; - localtime_r(&Timestamp, &dateTm); - return ((unsigned)dateTm.tm_year) + 1900; -} - -unsigned TDate::GetMonth() const { - tm dateTm; - localtime_r(&Timestamp, &dateTm); - return ((unsigned)dateTm.tm_mon) + 1; -} - -unsigned TDate::GetMonthDay() const { - tm dateTm; - localtime_r(&Timestamp, &dateTm); - return (unsigned)dateTm.tm_mday; -} diff --git a/util/draft/date.h b/util/draft/date.h deleted file mode 100644 index 0be22400235..00000000000 --- a/util/draft/date.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include - -// XXX: uses system calls for trivial things. may be very slow therefore. - -time_t GetDateStart(time_t ts); - -// Local date (without time zone) -class TDate { - // XXX: wrong: must store number of days since epoch - time_t Timestamp; - -public: - TDate() - : Timestamp(0) - { - } - - // XXX: wrong. Should be replace with two methods: TodayGmt() and TodayLocal() - static TDate Today() { - return TDate(time(nullptr)); - } - - TDate(const char* yyyymmdd); - TDate(const std::string& yyyymmdd); - TDate(unsigned year, unsigned month, unsigned monthDay); // month from 01, monthDay from 01 - TDate(const std::string& date, const std::string& format); - - explicit TDate(time_t t); - - time_t GetStart() const { - return Timestamp; - } - - time_t GetStartUTC() const; - - std::string ToStroka(const char* format = "%Y%m%d") const; - - TDate& operator++() { - Timestamp = GetDateStart(Timestamp + 3 * (SECONDS_IN_DAY / 2)); - return *this; - } - - TDate& operator--() { - Timestamp = GetDateStart(Timestamp - SECONDS_IN_DAY / 2); - return *this; - } - - TDate& operator+=(unsigned days) { - Timestamp = GetDateStart(Timestamp + days * SECONDS_IN_DAY + SECONDS_IN_DAY / 2); - return *this; - } - - TDate& operator-=(unsigned days) { - Timestamp = GetDateStart(Timestamp - days * SECONDS_IN_DAY + SECONDS_IN_DAY / 2); - return *this; - } - - TDate operator+(unsigned days) const { - return TDate(Timestamp + days * SECONDS_IN_DAY + SECONDS_IN_DAY / 2); - } - - TDate operator-(unsigned days) const { - return TDate(Timestamp - days * SECONDS_IN_DAY + SECONDS_IN_DAY / 2); - } - - unsigned GetWeekDay() const; // days since Sunday - - unsigned GetYear() const; - unsigned GetMonth() const; // from 01 - unsigned GetMonthDay() const; // from 01 - - friend bool operator<(const TDate& left, const TDate& right); - friend bool operator>(const TDate& left, const TDate& right); - friend bool operator<=(const TDate& left, const TDate& right); - friend bool operator>=(const TDate& left, const TDate& right); - friend bool operator==(const TDate& left, const TDate& right); - friend int operator-(const TDate& left, const TDate& right); - - friend IInputStream& operator>>(IInputStream& left, TDate& right); - friend IOutputStream& operator<<(IOutputStream& left, const TDate& right); -}; - -Y_DECLARE_PODTYPE(TDate); - -inline bool operator<(const TDate& left, const TDate& right) { - return left.Timestamp < right.Timestamp; -} - -inline bool operator>(const TDate& left, const TDate& right) { - return left.Timestamp > right.Timestamp; -} - -inline bool operator<=(const TDate& left, const TDate& right) { - return left.Timestamp <= right.Timestamp; -} - -inline bool operator>=(const TDate& left, const TDate& right) { - return left.Timestamp >= right.Timestamp; -} - -inline bool operator==(const TDate& left, const TDate& right) { - return left.Timestamp == right.Timestamp; -} - -inline int operator-(const TDate& left, const TDate& right) { - if (left < right) { - return -(right - left); - } - return static_cast((left.Timestamp + SECONDS_IN_DAY / 2 - right.Timestamp) / SECONDS_IN_DAY); -} - -inline IInputStream& operator>>(IInputStream& left, TDate& right) { - std::string stroka; - left >> stroka; - TDate date(stroka.c_str()); - right = date; - return left; -} - -inline IOutputStream& operator<<(IOutputStream& left, const TDate& right) { - return left << right.ToStroka(); -} diff --git a/util/draft/date_ut.cpp b/util/draft/date_ut.cpp deleted file mode 100644 index 8c33a6c1cfd..00000000000 --- a/util/draft/date_ut.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "date.h" - -#include - -Y_UNIT_TEST_SUITE(TDateTest) { - Y_UNIT_TEST(ComponentsTest) { - { - TDate d("20110215"); - UNIT_ASSERT_EQUAL(d.GetYear(), 2011); - UNIT_ASSERT_EQUAL(d.GetMonth(), 2); - UNIT_ASSERT_EQUAL(d.GetMonthDay(), 15); - UNIT_ASSERT_EQUAL(d.ToStroka("%Y%m%d"), "20110215"); - UNIT_ASSERT_EQUAL(d.ToStroka(), "20110215"); - UNIT_ASSERT_EQUAL(d.ToStroka("%Y--%m--%d"), "2011--02--15"); - UNIT_ASSERT_EQUAL(d.ToStroka("%U"), "07"); - UNIT_ASSERT_EQUAL(d.GetStartUTC(), 1297728000); - } - { - TDate d(2005, 6, 3); - UNIT_ASSERT_EQUAL(d.GetYear(), 2005); - UNIT_ASSERT_EQUAL(d.GetMonth(), 6); - UNIT_ASSERT_EQUAL(d.GetMonthDay(), 3); - UNIT_ASSERT_EQUAL(d.ToStroka(), "20050603"); - UNIT_ASSERT_EQUAL(d.ToStroka("____%Y__%m____%d"), "____2005__06____03"); - UNIT_ASSERT_EQUAL(d.GetStartUTC(), 1117756800); - } - { - TDate d("2011-02-15", "%Y-%m-%d"); - UNIT_ASSERT_EQUAL(d.GetYear(), 2011); - UNIT_ASSERT_EQUAL(d.GetMonth(), 2); - UNIT_ASSERT_EQUAL(d.GetMonthDay(), 15); - UNIT_ASSERT_EQUAL(d.ToStroka("%Y%m%d"), "20110215"); - UNIT_ASSERT_EQUAL(d.GetStartUTC(), 1297728000); - } - } -} diff --git a/util/draft/datetime.cpp b/util/draft/datetime.cpp deleted file mode 100644 index c8a5601b997..00000000000 --- a/util/draft/datetime.cpp +++ /dev/null @@ -1,234 +0,0 @@ -#include "datetime.h" - -#include - -#include -#include -#include -#include -#include -#include -namespace NDatetime { - const ui32 MonthDays[2][12] = { - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //nleap - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} //leap - }; - - const ui32 MonthDaysNewYear[2][13] = { - {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, //nleap - {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} //leap - }; - - void YDayToMonthAndDay(ui32 yday, bool isleap, ui32* month, ui32* mday) { - const ui32* begin = MonthDaysNewYear[isleap] + 1; - const ui32* end = begin + 12; - // [31, ..., 365] or [31, ..., 366] (12 elements) - - const ui32* pos = UpperBound(begin, end, yday); - Y_ENSURE(pos != end, "day no. " << yday << " does not exist in " << (isleap ? "leap" : "non-leap") << " year"); - - *month = pos - begin; - *mday = yday - *(pos - 1) + 1; - - Y_ASSERT((*month < 12) && (1 <= *mday) && (*mday <= MonthDays[isleap][*month])); - } - - struct TTimeData { - i32 IsDst = 0; - i32 GMTOff = 0; - - TTimeData(time_t t) { - struct ::tm tt; - ::localtime_r(&t, &tt); -#ifndef _win_ - GMTOff = tt.tm_gmtoff; -#else - TIME_ZONE_INFORMATION tz; - switch (GetTimeZoneInformation(&tz)) { - case TIME_ZONE_ID_UNKNOWN: - GMTOff = tz.Bias * -60; - break; - case TIME_ZONE_ID_STANDARD: - GMTOff = (tz.Bias + tz.StandardBias) * -60; - break; - case TIME_ZONE_ID_DAYLIGHT: - GMTOff = (tz.Bias + tz.DaylightBias) * -60; - break; - default: - break; - } -#endif - IsDst = tt.tm_isdst; - } - }; - - TSimpleTM TSimpleTM::CurrentUTC() { - return New((time_t)TInstant::MicroSeconds(InterpolatedMicroSeconds()).Seconds()); - } - - TSimpleTM TSimpleTM::New(time_t t, i32 gmtoff, i8 isdst) { - time_t tt = t + gmtoff + isdst * 3600; - struct tm tmSys; - Zero(tmSys); - GmTimeR(&tt, &tmSys); - tmSys.tm_isdst = isdst; -#ifndef _win_ - tmSys.tm_gmtoff = gmtoff; -#endif - - return New(tmSys); - } - - TSimpleTM TSimpleTM::NewLocal(time_t t) { - TTimeData d(t); - return New(t, d.GMTOff, d.IsDst); - } - - TSimpleTM TSimpleTM::New(const struct tm& t) { - TSimpleTM res; - res.IsDst = t.tm_isdst; - res.Sec = t.tm_sec; - res.Min = t.tm_min; - res.Hour = t.tm_hour; - res.WDay = t.tm_wday; - res.Mon = t.tm_mon; - res.MDay = t.tm_mday; - res.Year = t.tm_year; - res.YDay = t.tm_yday; - res.IsLeap = LeapYearAD(res.Year + 1900); -#ifndef _win_ - res.GMTOff = t.tm_gmtoff; -#endif - return res; - } - - TSimpleTM& TSimpleTM::SetRealDate(ui32 year, ui32 mon, ui32 mday, ui32 hour, ui32 min, ui32 sec, i32 isdst) { - mday = ::Max(mday, 1); - mon = ::Min(::Max(mon, 1), 12); - year = ::Max(year, 1900); - - IsLeap = LeapYearAD(year); - Year = year - 1900; - Mon = mon - 1; - MDay = ::Min(mday, MonthDays[IsLeap][Mon]); - Hour = Max() == hour ? Hour : ::Min(hour, 23); - Min = Max() == min ? Min : ::Min(min, 59); - Sec = Max() == sec ? Sec : ::Min(sec, 60); - IsDst = isdst; - - return RegenerateFields(); - } - - TSimpleTM& TSimpleTM::RegenerateFields() { - return *this = New(AsTimeT(), GMTOff, IsDst); - } - - TSimpleTM& TSimpleTM::Add(EField f, i32 amount) { - if (!amount) { - return *this; - } - - switch (f) { - default: - return *this; - case F_DAY: - amount *= 24; - [[fallthrough]]; - case F_HOUR: - amount *= 60; - [[fallthrough]]; - case F_MIN: - amount *= 60; - [[fallthrough]]; - case F_SEC: { - return *this = New(AsTimeT() + amount, GMTOff, IsDst); - } - case F_YEAR: { - i32 y = amount + (i32)Year; - y = ::Min(Max(y, 0), 255 /*max year*/); - - // YDay may correspond to different MDay if it's March or greater and the years have different leap status - if (Mon > 1) { - YDay += (i32)LeapYearAD(RealYear()) - (i32)LeapYearAD(RealYear()); - } - - Year = y; - IsLeap = LeapYearAD(RealYear()); - return RegenerateFields(); - } - case F_MON: { - i32 m = amount + Mon; - i32 y = (m < 0 ? (-12 + m) : m) / 12; - m = m - y * 12; - - if (y) { - Add(F_YEAR, y); - } - - if (m >= 0 && m < 12) { - MDay = ::Min(MonthDays[IsLeap][m], MDay); - Mon = m; - } - - return RegenerateFields(); - } - } - } - - std::string TSimpleTM::ToString(const char* fmt) const { - struct tm t = *this; - return Strftime(fmt, &t); - } - - time_t TSimpleTM::AsTimeT() const { - struct tm t = AsStructTmLocal(); - return TimeGM(&t) - GMTOff - IsDst * 3600; - } - - struct tm TSimpleTM::AsStructTmUTC() const { - struct tm res; - Zero(res); - time_t t = AsTimeT(); - return *GmTimeR(&t, &res); - } - - struct tm TSimpleTM::AsStructTmLocal() const { - struct tm t; - Zero(t); - t.tm_isdst = IsDst; - t.tm_sec = Sec; - t.tm_min = Min; - t.tm_hour = Hour; - t.tm_wday = WDay; - t.tm_mon = Mon; - t.tm_mday = MDay; - t.tm_year = Year; - t.tm_yday = YDay; -#ifndef _win_ - t.tm_gmtoff = GMTOff; -#endif - return t; - } -} - -template <> -void In(IInputStream& in, TMonth& t) { - char buf[4]; - LoadPodArray(&in, buf, 4); - t.Year = FromString(buf, 4); - LoadPodArray(&in, buf, 2); - t.Month = ui8(FromString(buf, 2)) - 1; -} - -template <> -void Out(IOutputStream& o, const TMonth& t) { - o << t.Year << std::format("%.2hu", (ui16)(t.Month + 1)); -} - -template <> -TMonth FromStringImpl(const char* s, size_t len) { - TMonth res; - TMemoryInput in(s, len); - in >> res; - return res; -} diff --git a/util/draft/datetime.h b/util/draft/datetime.h deleted file mode 100644 index 504a931c2f6..00000000000 --- a/util/draft/datetime.h +++ /dev/null @@ -1,183 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include - -#include - -namespace NDatetime { - extern const ui32 MonthDays[2][12]; // !leapYear; !!leapYear - extern const ui32 MonthDaysNewYear[2][13]; // !leapYear; !!leapYear - - inline ui32 YearDaysAD(ui32 year) { - year = Max(year, 1) - 1; //1 AD comes straight after 1 BC, no 0 AD - return year * 365 + year / 4 - year / 100 + year / 400; - } - - inline bool LeapYearAD(ui32 year) { - return (!(year % 4) && (year % 100)) || !(year % 400); - } - - inline ui32 YDayFromMonthAndDay(ui32 month /*0 - based*/, ui32 mday /*1 - based*/, bool isleap) { - return MonthDaysNewYear[isleap][Min(month, (ui32)11u)] + mday - 1; - } - - void YDayToMonthAndDay(ui32 yday /*0 - based*/, bool isleap, ui32* month /*0 - based*/, ui32* mday /*1 - based*/); - - struct TSimpleTM { - enum EField { - F_NONE = 0, - F_SEC, - F_MIN, - F_HOUR, - F_DAY, - F_MON, - F_YEAR - }; - - i32 GMTOff = 0; // -43200 - 50400 seconds - ui16 Year = 0; // from 1900 - ui16 YDay = 0; // 0-365 - ui8 Mon = 0; // 0-11 - ui8 MDay = 0; // 1-31 - ui8 WDay = 0; // 0-6 - ui8 Hour = 0; // 0-23 - ui8 Min = 0; // 0-59 - ui8 Sec = 0; // 0-60 - doesn't care for leap seconds. Most of the time it's ok. - i8 IsDst = 0; // -1/0/1 - bool IsLeap = false; - - public: - static TSimpleTM New(time_t t = 0, i32 gmtoff = 0, i8 isdst = 0); - static TSimpleTM NewLocal(time_t = 0); - - static TSimpleTM New(const struct tm&); - - static TSimpleTM CurrentUTC(); - - TSimpleTM() = default; - - TSimpleTM(ui32 year, ui32 mon, ui32 day, ui32 h = 0, ui32 m = 0, ui32 s = 0) { - Zero(*this); - SetRealDate(year, mon, day, h, m, s); - } - - // keeps the object consistent - TSimpleTM& Add(EField f, i32 amount = 1); - - std::string ToString(const char* fmt = "%a, %d %b %Y %H:%M:%S %z") const; - - TSimpleTM& ToUTC() { - return *this = New(AsTimeT()); - } - - bool IsUTC() const { - return !IsDst && !GMTOff; - } - - time_t AsTimeT() const; - - operator time_t() const { - return AsTimeT(); - } - - struct tm AsStructTmLocal() const; - - struct tm AsStructTmUTC() const; - - operator struct tm() const { - return AsStructTmLocal(); - } - - ui32 RealYear() const { - return ui32(Year + 1900); - } - - ui32 RealMonth() const { - return ui32(Mon + 1); - } - - TSimpleTM& SetRealDate(ui32 year, ui32 mon, ui32 mday, ui32 hour = -1, ui32 min = -1, ui32 sec = -1, i32 isdst = 0); - - // regenerates all fields from Year, MDay, Hour, Min, Sec, IsDst, GMTOffset - TSimpleTM& RegenerateFields(); - - friend bool operator==(const TSimpleTM& a, const TSimpleTM& b) { - return a.AsTimeT() == b.AsTimeT(); - } - - friend bool operator==(const TSimpleTM& s, const struct tm& t) { - return s == New(t); - } - - friend bool operator==(const struct tm& t, const TSimpleTM& s) { - return s == t; - } - - friend bool operator!=(const TSimpleTM& a, const TSimpleTM& b) { - return !(a == b); - } - - friend bool operator!=(const TSimpleTM& s, const struct tm& t) { - return !(s == t); - } - - friend bool operator!=(const struct tm& t, const TSimpleTM& s) { - return s != t; - } - }; -} - -inline std::string date2str(const time_t date) { - struct tm dateTm; - memset(&dateTm, 0, sizeof(dateTm)); - localtime_r(&date, &dateTm); - char buf[9]; - strftime(buf, sizeof(buf), "%Y%m%d", &dateTm); - return std::string(buf); -} - -inline time_t str2date(const std::string& dateStr) { - struct tm dateTm; - memset(&dateTm, 0, sizeof(tm)); - strptime(dateStr.data(), "%Y%m%d", &dateTm); - return mktime(&dateTm); -} - -// checks whether time2 > time1 and close enough to it -inline bool AreTimesSeqAndClose(time_t time1, time_t time2, time_t closeInterval = 10) { - return (time2 - time1) <= closeInterval; -} - -// checks whether time2 and time1 are close enough -inline bool AreTimesClose(time_t time1, time_t time2, time_t closeInterval = 10) { - return std::abs(time2 - time1) <= closeInterval; -} - -//////////////////////////////// - -struct TMonth { - ui16 Year; - ui8 Month; - - TMonth(ui16 year = 0, ui8 month = 0) - : Year(year) - , Month(month) - { - } - - TMonth operator-(ui16 n) { - if (n <= Month) { - return TMonth(Year, Month - (ui8)n); - } else { - n -= Month; - return (n % 12) ? TMonth(Year - 1 - (n / 12), 12 - (n % 12)) : TMonth(Year - (n / 12), 0); - } - } -}; - -Y_DECLARE_PODTYPE(NDatetime::TSimpleTM); diff --git a/util/draft/datetime_ut.cpp b/util/draft/datetime_ut.cpp deleted file mode 100644 index 017c962cb88..00000000000 --- a/util/draft/datetime_ut.cpp +++ /dev/null @@ -1,231 +0,0 @@ -#include "datetime.h" - -#include - -#include - -Y_UNIT_TEST_SUITE(TSimpleTMTest) { - std::string PrintMarker(const std::string& test, int line) { - return TStringBuilder() << "test " << test << " at line " << line; - } - - std::string JoinMarker(const std::string& marker, time_t t) { - return TStringBuilder() << marker << " (tstamp=" << t << ")"; - } - - std::string PrintMarker(const std::string& test, int line, time_t t) { - return JoinMarker(PrintMarker(test, line), t); - } - - void AssertStructTmEqual(const std::string& marker, const struct tm& tmt, const NDatetime::TSimpleTM& tms) { - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Sec, tmt.tm_sec, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Min, tmt.tm_min, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Hour, tmt.tm_hour, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.WDay, tmt.tm_wday, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.MDay, tmt.tm_mday, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Mon, tmt.tm_mon, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.YDay, tmt.tm_yday, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Year, tmt.tm_year, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.IsDst, tmt.tm_isdst, marker); -#ifndef _win_ - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.GMTOff, tmt.tm_gmtoff, marker); -#endif - } - - void AssertSimpleTM(const std::string& mark, - const NDatetime::TSimpleTM& tms, - time_t tstamp, ui32 year, ui32 mon, ui32 mday, ui32 hour, ui32 minu, ui32 sec) { - std::string marker = JoinMarker(mark, tstamp); - struct tm tmt; - Zero(tmt); - GmTimeR(&tstamp, &tmt); - AssertStructTmEqual(marker, tmt, tms); - tmt = tms.AsStructTmUTC(); - time_t tstamp1 = TimeGM(&tmt); - UNIT_ASSERT_VALUES_EQUAL_C(tstamp, tstamp1, marker); - UNIT_ASSERT_VALUES_EQUAL_C(tstamp, tms.AsTimeT(), marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.RealYear(), year, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.RealMonth(), mon, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.MDay, mday, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Hour, hour, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Min, minu, marker); - UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Sec, sec, marker); - } - - Y_UNIT_TEST(TestLeap) { - using namespace NDatetime; - UNIT_ASSERT(LeapYearAD(2000)); - UNIT_ASSERT(LeapYearAD(2012)); - UNIT_ASSERT(!LeapYearAD(1999)); - UNIT_ASSERT(LeapYearAD(2004)); - UNIT_ASSERT(!LeapYearAD(1900)); - } - - Y_UNIT_TEST(TestYDayConversion) { - using namespace NDatetime; - ui32 month; - ui32 mday; - - for (ui32 yday = 0; yday < 365; ++yday) { - YDayToMonthAndDay(yday, false, &month, &mday); - UNIT_ASSERT_VALUES_EQUAL(yday, YDayFromMonthAndDay(month, mday, false)); - } - for (ui32 yday = 0; yday < 366; ++yday) { - YDayToMonthAndDay(yday, true, &month, &mday); - UNIT_ASSERT_VALUES_EQUAL(yday, YDayFromMonthAndDay(month, mday, true)); - } - - UNIT_ASSERT_EXCEPTION(YDayToMonthAndDay(365, false, &month, &mday), yexception); - UNIT_ASSERT_EXCEPTION(YDayToMonthAndDay(366, true, &month, &mday), yexception); - } - - Y_UNIT_TEST(SimpleTMTest) { - using namespace NDatetime; - - tzset(); - - TSimpleTM::New(-1); //should not die here - - UNIT_ASSERT_VALUES_EQUAL((ui32)0, (ui32)TSimpleTM::New(0)); - UNIT_ASSERT((ui32)TSimpleTM::New(0).IsUTC()); - time_t t = time(nullptr); - - { - struct tm tmt; - Zero(tmt); - gmtime_r(&t, &tmt); - UNIT_ASSERT_VALUES_EQUAL_C((i64)t, (i64)TSimpleTM::New(t).AsTimeT(), ToString(t)); // time_t -> gmt tm -> time_t - UNIT_ASSERT_VALUES_EQUAL_C((i64)t, (i64)TSimpleTM::New(tmt).AsTimeT(), ToString(t)); // gmt tm -> time_t - AssertStructTmEqual(PrintMarker("UTC:time_t", __LINE__, t), - tmt, TSimpleTM::New(t)); - AssertStructTmEqual(PrintMarker("UTC:tm", __LINE__, t), - tmt, TSimpleTM::New(tmt)); - UNIT_ASSERT(TSimpleTM::New(t).IsUTC()); - UNIT_ASSERT(TSimpleTM::New(tmt).IsUTC()); - } - - { - struct tm tmt; - Zero(tmt); - localtime_r(&t, &tmt); - - UNIT_ASSERT_VALUES_EQUAL((i64)t, (i64)TSimpleTM::NewLocal(t).AsTimeT()); // time_t -> local tm -> time_t - UNIT_ASSERT_VALUES_EQUAL((i64)t, (i64)TSimpleTM::New(tmt).AsTimeT()); - AssertStructTmEqual(PrintMarker("local:time_t", __LINE__, t), - tmt, TSimpleTM::NewLocal(t)); - AssertStructTmEqual(PrintMarker("local:tm", __LINE__, t), - tmt, TSimpleTM::New(tmt)); - AssertStructTmEqual(PrintMarker("local:tm:RegenerateFields", __LINE__, t), - tmt, TSimpleTM::New(tmt).RegenerateFields()); - AssertStructTmEqual(PrintMarker("local:time_t:SetRealDate", __LINE__, t), - tmt, TSimpleTM::NewLocal(t).SetRealDate(tmt.tm_year + 1900, tmt.tm_mon + 1, tmt.tm_mday, tmt.tm_hour, tmt.tm_min, tmt.tm_sec, tmt.tm_isdst)); - } - - { - TSimpleTM tt = TSimpleTM::New(0); - - tt.SetRealDate(2012, 3, 30, 5, 6, 7); - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1333083967, 2012, 3, 30, 5, 6, 7); - - tt.SetRealDate(2012, 3, 8, 5, 6, 7); - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1331183167, 2012, 3, 8, 5, 6, 7); - - tt.SetRealDate(2010, 10, 4, 5, 6, 7); - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1286168767, 2010, 10, 4, 5, 6, 7); - - tt.Add(TSimpleTM::F_MON); - AssertSimpleTM(PrintMarker("UTC:AddMonth", __LINE__), - tt, 1288847167, 2010, 11, 4, 5, 6, 7); - - tt.Add(TSimpleTM::F_DAY); - AssertSimpleTM(PrintMarker("UTC:AddDay", __LINE__), - tt, 1288933567, 2010, 11, 5, 5, 6, 7); - - tt.Add(TSimpleTM::F_YEAR); - AssertSimpleTM(PrintMarker("UTC:AddYear", __LINE__), - tt, 1320469567, 2011, 11, 5, 5, 6, 7); - - for (ui32 i = 0; i < 365; ++i) { - tt.Add(TSimpleTM::F_DAY); - } - - AssertSimpleTM(PrintMarker("UTC:365*AddDay", __LINE__), - tt, 1352005567, 2012, 11, 4, 5, 6, 7); - - tt.Add(TSimpleTM::F_MON, -10); - AssertSimpleTM(PrintMarker("UTC:AddMonth(-10)", __LINE__), - tt, 1325653567, 2012, 1, 4, 5, 6, 7); - - tt.Add(TSimpleTM::F_HOUR, -24 * 4 - 6); - AssertSimpleTM(PrintMarker("UTC:AddHour(-102)", __LINE__), - tt, 1325286367, 2011, 12, 30, 23, 6, 7); - } - - { - TSimpleTM tt = TSimpleTM::New(); - - tt.SetRealDate(2012, 2, 29); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1330473600, 2012, 2, 29, 0, 0, 0); - - tt.SetRealDate(2012, 2, 29); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1330473600, 2012, 2, 29, 0, 0, 0); - - tt.SetRealDate(2013, 12, 28); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1388188800, 2013, 12, 28, 0, 0, 0); - - tt.SetRealDate(2012, 10, 23); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1350950400, 2012, 10, 23, 0, 0, 0); - - tt.SetRealDate(2013, 3, 16); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1363392000, 2013, 3, 16, 0, 0, 0); - - tt.SetRealDate(2013, 2, 17); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1361059200, 2013, 2, 17, 0, 0, 0); - - tt.SetRealDate(2012, 12, 23); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1356220800, 2012, 12, 23, 0, 0, 0); - - tt.SetRealDate(2012, 5, 17); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1337212800, 2012, 5, 17, 0, 0, 0); - - tt.SetRealDate(2012, 6, 15); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1339718400, 2012, 6, 15, 0, 0, 0); - - tt.SetRealDate(2009, 3, 17); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1237248000, 2009, 3, 17, 0, 0, 0); - - tt.SetRealDate(2013, 8, 12); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1376265600, 2013, 8, 12, 0, 0, 0); - - tt.SetRealDate(2015, 12, 11, 10, 9, 8); - - AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__), - tt, 1449828548, 2015, 12, 11, 10, 9, 8); - } - } -} diff --git a/util/draft/enum.cpp b/util/draft/enum.cpp deleted file mode 100644 index 40c79fb679a..00000000000 --- a/util/draft/enum.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "enum.h" diff --git a/util/draft/enum.h b/util/draft/enum.h deleted file mode 100644 index 0260c676de1..00000000000 --- a/util/draft/enum.h +++ /dev/null @@ -1,135 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include - -class TEnumNotFoundException: public yexception { -}; - -#define EnumFromString(key, entries) EnumFromStringImpl(key, entries, Y_ARRAY_SIZE(entries)) -#define EnumFromStringWithSize(key, entries, size) EnumFromStringImpl(key, entries, size) -#define FindEnumFromString(key, entries) FindEnumFromStringImpl(key, entries, Y_ARRAY_SIZE(entries)) -#define FindEnumFromStringWithSize(key, entries, size) FindEnumFromStringImpl(key, entries, size) -#define EnumToString(key, entries) EnumToStringImpl(key, entries, Y_ARRAY_SIZE(entries)) -#define EnumToStringWithSize(key, entries, size) EnumToStringImpl(key, entries, size) -#define PrintEnumItems(entries) PrintEnumItemsImpl(entries, Y_ARRAY_SIZE(entries)) - -template -const V* FindEnumFromStringImpl(K1 key, const std::pair* entries, size_t arraySize) { - for (size_t i = 0; i < arraySize; i++) - if (entries[i].first == key) - return &entries[i].second; - return nullptr; -} - -// special version for const char* -template -const V* FindEnumFromStringImpl(const char* key, const std::pair* entries, size_t arraySize) { - for (size_t i = 0; i < arraySize; i++) - if (entries[i].first && key && !strcmp(entries[i].first, key)) - return &entries[i].second; - return nullptr; -} - -template -std::string PrintEnumItemsImpl(const std::pair* entries, size_t arraySize) { - std::string result; - TStringOutput out(result); - for (size_t i = 0; i < arraySize; i++) - out << (i ? ", " : "") << "'" << entries[i].first << "'"; - return result; -} - -// special version for const char* -template -std::string PrintEnumItemsImpl(const std::pair* entries, size_t arraySize) { - std::string result; - TStringOutput out(result); - for (size_t i = 0; i < arraySize; i++) - out << (i ? ", " : "") << "'" << (entries[i].first ? entries[i].first : "") << "'"; - return result; -} - -template -const V* EnumFromStringImpl(K1 key, const std::pair* entries, size_t arraySize) { - const V* res = FindEnumFromStringImpl(key, entries, arraySize); - if (res) - return res; - - ythrow TEnumNotFoundException() << "Key '" << key << "' not found in enum. Valid options are: " << PrintEnumItemsImpl(entries, arraySize) << ". "; -} - -template -const K* EnumToStringImpl(V value, const std::pair* entries, size_t arraySize) { - for (size_t i = 0; i < arraySize; i++) - if (entries[i].second == value) - return &entries[i].first; - - TEnumNotFoundException exc; - exc << "Value '" << int(value) << "' not found in enum. Valid values are: "; - for (size_t i = 0; i < arraySize; i++) - exc << (i ? ", " : "") << int(entries[i].second); - exc << ". "; - ythrow exc; -} - -/////////////////////////////////// - -template -inline void SetEnumFlagsForEmptySpec(B& flags, bool allIfEmpty) { - if (allIfEmpty) { - flags.set(); - } else { - flags.reset(); - } -} - -// all set by default -template -inline void SetEnumFlags(const std::pair (&str2Enum)[N], std::string_view optSpec, - std::bitset& flags, bool allIfEmpty = true) { - if (optSpec.empty()) { - SetEnumFlagsForEmptySpec(flags, allIfEmpty); - } else { - flags.reset(); - for (const auto& it : StringSplitter(optSpec).Split(',')) { - E e = *EnumFromStringImpl(ToString(it.Token()).data(), str2Enum, N); - flags.set(e); - } - } -} - -template -inline void SetEnumFlags(const std::pair* str2Enum, std::string_view optSpec, - std::bitset& flags, const size_t size, - bool allIfEmpty = true) { - if (optSpec.empty()) { - SetEnumFlagsForEmptySpec(flags, allIfEmpty); - } else { - flags.reset(); - for (const auto& it : StringSplitter(optSpec).Split(',')) { - E e = *EnumFromStringImpl(ToString(it.Token()).data(), str2Enum, size); - flags.set(e); - } - } -} - -// for enums generated with GENERATE_ENUM_SERIALIZATION -template -inline void SetEnumFlags(std::string_view optSpec, std::bitset& flags, bool allIfEmpty = true) { - if (optSpec.empty()) { - SetEnumFlagsForEmptySpec(flags, allIfEmpty); - } else { - flags.reset(); - for (const auto& it : StringSplitter(optSpec).Split(',')) { - E e; - if (!TryFromString(it.Token(), e)) - ythrow yexception() << "Unknown enum value '" << it.Token() << "'"; - flags.set((size_t)e); - } - } -} diff --git a/util/draft/holder_vector.cpp b/util/draft/holder_vector.cpp deleted file mode 100644 index 9994c2a2b56..00000000000 --- a/util/draft/holder_vector.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "holder_vector.h" diff --git a/util/draft/holder_vector.h b/util/draft/holder_vector.h deleted file mode 100644 index 3840596229c..00000000000 --- a/util/draft/holder_vector.h +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -#include -#include - -#include - -template -class THolderVector: public std::vector, public TNonCopyable { - using TBase = std::vector; - -public: - explicit THolderVector(size_t n = 0) - : TBase(n) - { - } - - ~THolderVector() { - Clear(); - } - - void Clear() { - for (typename TBase::iterator it = TBase::begin(); it != TBase::end(); ++it) { - if (*it) - D::Destroy(*it); - } - TBase::clear(); - } - - size_t Size() const { - return TBase::size(); - } - - // std::vector takes ownership of T - void PushBack(T* t) { - try { - TBase::push_back(t); - } catch (...) { - if (t) - D::Destroy(t); - throw; - } - } - - void PushBack(std::unique_ptr t) { - PushBack(t.release()); - } - - void PushBack(THolder t) { - PushBack(t.Release()); - } - - void Reset(size_t i, THolder t) { - T* current = (*this)[i]; - if (current) { - Y_ASSERT(current != t.Get()); - D::Destroy(current); - } - (*this)[i] = t.Release(); - } - - void PopBack() { - if (size()) { - D::Destroy(back()); - TBase::pop_back(); - } - } - - T* Release(size_t i) { - T* t = (*this)[i]; - (*this)[i] = nullptr; - return t; - } - - void Resize(size_t newSize) { - for (size_t i = newSize; i < size(); ++i) { - D::Destroy((*this)[i]); - } - TBase::resize(newSize); - } - - void Swap(THolderVector& other) { - TBase::swap(other); - } - - using TBase::operator[]; - using TBase::operator bool; - using TBase::at; - using TBase::back; - using TBase::begin; - using TBase::capacity; - using TBase::empty; - using TBase::end; - using TBase::front; - using TBase::reserve; - using TBase::size; - - using typename TBase::const_iterator; - using typename TBase::const_reverse_iterator; - using typename TBase::iterator; - using typename TBase::reverse_iterator; - using typename TBase::value_type; -}; diff --git a/util/draft/holder_vector_ut.cpp b/util/draft/holder_vector_ut.cpp deleted file mode 100644 index 8f6d571f7fc..00000000000 --- a/util/draft/holder_vector_ut.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "holder_vector.h" - -#include - -Y_UNIT_TEST_SUITE(THolderVectorTest) { - Y_UNIT_TEST(TestCreateEmpty) { - THolderVector ints; - UNIT_ASSERT_EQUAL(ints.Size(), 0); - UNIT_ASSERT(!ints); - } - - Y_UNIT_TEST(TestCreateNonEmpty) { - THolderVector ints(5); - UNIT_ASSERT_EQUAL(ints.Size(), 5); - UNIT_ASSERT(ints); - - for (size_t i = 0; i < ints.Size(); ++i) { - UNIT_ASSERT_EQUAL(ints[i], (int*)nullptr); - } - } - - Y_UNIT_TEST(TestResetValue) { - THolderVector ints; - ints.PushBack(new int(0)); - ints.PushBack(new int(1)); - UNIT_ASSERT_VALUES_EQUAL(*ints[0], 0); - UNIT_ASSERT_VALUES_EQUAL(*ints[1], 1); - ints.Reset(0, MakeHolder(2)); - ints.Reset(1, MakeHolder(3)); - UNIT_ASSERT_VALUES_EQUAL(*ints[0], 2); - UNIT_ASSERT_VALUES_EQUAL(*ints[1], 3); - } - - Y_UNIT_TEST(TestResetNoValue) { - THolderVector ints; - ints.Resize(1); - UNIT_ASSERT_EQUAL(ints[0], (int*)nullptr); - ints.Reset(0, MakeHolder(1)); - UNIT_ASSERT_UNEQUAL(ints[0], (int*)nullptr); - UNIT_ASSERT_VALUES_EQUAL(*ints[0], 1); - } - - Y_UNIT_TEST(TestResetSmartPtr) { - THolderVector ints; - ints.Resize(2); - - THolder holder(new int(1)); - ints.Reset(0, std::move(holder)); - UNIT_ASSERT_VALUES_EQUAL(*ints[0], 1); - UNIT_ASSERT(!holder); - } - - Y_UNIT_TEST(TestSwap) { - THolderVector v1; - v1.PushBack(new int(1)); - - THolderVector v2; - v1.Swap(v2); - UNIT_ASSERT(v1.empty() && v2.size() == 1 && *v2.front() == 1); - } - - Y_UNIT_TEST(TestUniquePtr) { - THolderVector v; - std::unique_ptr str(new std::string("hello")); - v.PushBack(std::move(str)); - UNIT_ASSERT(v.Size() == 1); - UNIT_ASSERT(str.get() == nullptr); - } -} diff --git a/util/draft/ip.cpp b/util/draft/ip.cpp deleted file mode 100644 index a43bcdadcf2..00000000000 --- a/util/draft/ip.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "ip.h" diff --git a/util/draft/ip.h b/util/draft/ip.h deleted file mode 100644 index 049d3f5fdd0..00000000000 --- a/util/draft/ip.h +++ /dev/null @@ -1,131 +0,0 @@ -#pragma once - -#include - -#include - -#include -#include - -#ifdef _unix_ - #include - #include - #include -#endif // _unix_ - -#include -#include - -#ifndef INET6_ADDRSTRLEN - #define INET6_ADDRSTRLEN 46 -#endif - -// Network (big-endian) byte order -using TIp4 = TIpHost; - -// Network (big-endian) byte order -struct TIp6 { - char Data[16]; - - bool operator==(const TIp6& rhs) const { - return memcmp(Data, rhs.Data, sizeof(Data)) == 0; - } - - bool operator<(const TIp6& rhs) const { - return memcmp(Data, rhs.Data, sizeof(Data)) < 0; - } -}; - -template <> -struct THash { - inline size_t operator()(const TIp6& ip) const { - return MurmurHash((const void*)ip.Data, 16); - } -}; - -static inline TIp6 Ip6FromIp4(TIp4 addr) { - TIp6 res; - memset(res.Data, 0, sizeof(res.Data)); - res.Data[10] = '\xFF'; - res.Data[11] = '\xFF'; - memcpy(res.Data + 12, &addr, 4); - return res; -} - -static inline TIp6 Ip6FromString(const char* ipStr) { - TIp6 res; - - if (inet_pton(AF_INET6, ipStr, &res.Data) == 0) { - ythrow TSystemError() << "Failed to convert (" << ipStr << ") to ipv6 address"; - } - - return res; -} - -static inline std::optional TryParseIp6FromString(const char* ipStr) { - TIp6 res; - - if (inet_pton(AF_INET6, ipStr, &res.Data) == 0) { - return std::nullopt; - } - - return res; -} - -static inline char* Ip6ToString(const TIp6& ip, char* buf, size_t len) { - if (!inet_ntop(AF_INET6, (void*)&ip.Data, buf, (socklen_t)len)) { - ythrow TSystemError() << "Failed to get ipv6 address string"; - } - - return buf; -} - -static inline std::string Ip6ToString(const TIp6& ip) { - char buf[INET6_ADDRSTRLEN]; - - return std::string(Ip6ToString(ip, buf, sizeof(buf))); -} - -template <> -inline void Out(IOutputStream& os, const TIp6& a) { - os << Ip6ToString(a); -} - -using TIp4Or6 = std::variant; - -static inline TIp4Or6 Ip4Or6FromString(const char* ipStr) { - const char* c = ipStr; - for (; *c; ++c) { - if (*c == '.') { - return IpFromString(ipStr); - } - if (*c == ':') { - return Ip6FromString(ipStr); - } - } - ythrow TSystemError() << "Failed to convert (" << ipStr << ") to ipv4 or ipv6 address"; -} - -static inline std::string Ip4Or6ToString(const TIp4Or6& ip) { - if (std::holds_alternative(ip)) { - return Ip6ToString(std::get(ip)); - } else { - return IpToString(std::get(ip)); - } -} - -// for TIp4 or TIp6, not TIp4Or6 -template -struct TIpCompare { - bool Less(const TIp& l, const TIp& r) const { - return memcmp(&l, &r, sizeof(TIp)) < 0; - } - - bool LessEqual(const TIp& l, const TIp& r) const { - return memcmp(&l, &r, sizeof(TIp)) <= 0; - } - - bool operator()(const TIp& l, const TIp& r) const { - return Less(l, r); - } -}; diff --git a/util/draft/matrix.cpp b/util/draft/matrix.cpp deleted file mode 100644 index 24a274b8101..00000000000 --- a/util/draft/matrix.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "matrix.h" diff --git a/util/draft/matrix.h b/util/draft/matrix.h deleted file mode 100644 index 154d00b35ea..00000000000 --- a/util/draft/matrix.h +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -template -class TMatrix: TNonCopyable { - // Constructor/Destructor -public: - TMatrix() - : Buf(nullptr) - , Arr(nullptr) - , M(0) - , N(0) - , BufSize(0) - { - } - - TMatrix(size_t m, size_t n) - : Buf(new T[m * n]) - , Arr(Buf) - , M(m) - , N(n) - , BufSize(m * n) - { - } - - TMatrix(size_t m, size_t n, T* buf) - : Buf(nullptr) - , Arr(buf) - , M(m) - , N(n) - , BufSize(m * n) - { - } - - ~TMatrix() { - delete[] Buf; - } - - // Properties/Methods -public: - void Clear() { - M = N = 0; - } - - void ReDim(size_t m, size_t n) { - Y_ASSERT(m >= 1 && n >= 1); - size_t newSize = m * n; - if (newSize > BufSize) { - T* newBuf = new T[newSize]; - delete[] Buf; - Arr = Buf = newBuf; - BufSize = newSize; - } - M = m; - N = n; - } - - size_t Width() const { - return N; - } - - size_t Height() const { - return M; - } - - // Access element matrix[i][j] - T* operator[](size_t i) { - Y_ASSERT(i >= 0 && i < M); - return Arr + i * N; - } - - // Access element matrix[i][j] - const T* operator[](size_t i) const { - Y_ASSERT(i >= 0 && i < M); - return Arr + i * N; - } - - // Access element matrix(i, j) - T& operator()(size_t i, size_t j) { - Y_ASSERT(i >= 0 && i < M && j >= 0 && j < N); - return Arr[i * N + j]; - } - - // Access element matrix(i, j) - const T& operator()(size_t i, size_t j) const { - Y_ASSERT(i >= 0 && i < M && j >= 0 && j < N); - return Arr[i * N + j]; - } - - void Zero() { - memset((void*)Arr, 0, M * N * sizeof(T)); - } - - void Fill(T value) { - for (T *p = Arr, *end = Arr + M * N; p < end; ++p) - *p = value; - } - -private: - T* Buf; - T* Arr; - size_t M, N; - size_t BufSize; -}; diff --git a/util/draft/memory.cpp b/util/draft/memory.cpp deleted file mode 100644 index b31569d4498..00000000000 --- a/util/draft/memory.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "memory.h" diff --git a/util/draft/memory.h b/util/draft/memory.h deleted file mode 100644 index 0a9722bb36e..00000000000 --- a/util/draft/memory.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -template -inline bool IsZero(const T* begin, const T* end) { - return std::find_if(begin, end, [](const T& other) { return other != T(0); }) == end; -} - -template -inline bool IsZero(const char* p) { - size_t sizeInUI64 = Size / 8; - const char* pEndUi64 = p + sizeInUI64 * 8; - if (sizeInUI64 && !IsZero((const ui64*)p, (const ui64*)pEndUi64)) - return false; - return IsZero(pEndUi64, p + Size); -} - -#define IS_ZERO_INTSZ(INT) \ - template <> \ - inline bool IsZero(const char* p) { \ - return (*(INT*)p) == INT(0); \ - } - -IS_ZERO_INTSZ(ui8) -IS_ZERO_INTSZ(ui16) -IS_ZERO_INTSZ(ui32) -IS_ZERO_INTSZ(ui64) - -#undef IS_ZERO_INTSZ - -// If you want to use this to check all fields in a struct make sure it's w/o holes or #pragma pack(1) -template -bool IsZero(const T& t) { - return IsZero((const char*)&t); -} diff --git a/util/draft/memory_ut.cpp b/util/draft/memory_ut.cpp deleted file mode 100644 index 76bee30549f..00000000000 --- a/util/draft/memory_ut.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "memory.h" - -#include - -#pragma pack(1) -struct Y_PACKED TSampleStruct1 { - ui8 A; - ui8 B; -}; - -#pragma pack(1) -struct Y_PACKED TSampleStruct2 { - ui8 A; - ui16 B; - i32 C; -}; - -#pragma pack(1) -struct Y_PACKED TSampleStruct3 { - TSampleStruct2 A; - ui64 B; -}; - -#pragma pack() - -Y_UNIT_TEST_SUITE(TUtilDraftMemoryTest) { - Y_UNIT_TEST(IsZeroTest) { - ui8 a1 = 0; - UNIT_ASSERT(IsZero(a1)); - a1 = 0xF0; - UNIT_ASSERT(!IsZero(a1)); - - i32 a2 = -1; - UNIT_ASSERT(!IsZero(a2)); - a2 = 0; - UNIT_ASSERT(IsZero(a2)); - - double a3 = 0.0; - UNIT_ASSERT(IsZero(a3)); - a3 = 1.e-13; - UNIT_ASSERT(!IsZero(a3)); - - TSampleStruct1 ss1; - ss1.A = 0; - ss1.B = 0; - UNIT_ASSERT(IsZero(ss1)); - ss1.A = 0; - ss1.B = 12; - UNIT_ASSERT(!IsZero(ss1)); - - TSampleStruct2 ss2; - ss2.A = 0; - ss2.B = 100; - ss2.C = 0; - UNIT_ASSERT(!IsZero(ss2)); - ss2.B = 0; - UNIT_ASSERT(IsZero(ss2)); - - TSampleStruct3 ss3; - ss3.A = ss2; - ss3.B = 0; - UNIT_ASSERT(IsZero(ss3)); - ss3.B = 0x030; - UNIT_ASSERT(!IsZero(ss3)); - ss3.B = 0; - ss3.A.C = -789; - UNIT_ASSERT(!IsZero(ss3)); - } -} diff --git a/util/draft/ut/ya.make b/util/draft/ut/ya.make deleted file mode 100644 index bd637f8cdad..00000000000 --- a/util/draft/ut/ya.make +++ /dev/null @@ -1,20 +0,0 @@ -UNITTEST() - -SUBSCRIBER(g:util-subscribers) - -SRCDIR(util/draft) - -PEERDIR( - util/draft -) - -SRCS( - date_ut.cpp - datetime_ut.cpp - holder_vector_ut.cpp - memory_ut.cpp -) - -INCLUDE(${ARCADIA_ROOT}/util/tests/ya_util_tests.inc) - -END()