| 134 | } |
| 135 | |
| 136 | class TDayNoToYearLookupTable { |
| 137 | static constexpr int TableSize = 128; |
| 138 | // lookup table for years in [StartYear, StartYear + TableSize] range |
| 139 | ui16 DaysSinceEpoch[TableSize] = {}; |
| 140 | |
| 141 | public: |
| 142 | static constexpr int StartYear = 1970; |
| 143 | static constexpr int StartDays = (StartYear - UNIX_TIME_BASE_YEAR) * DAYS_IN_YEAR + LeapYearCount(StartYear - 1) - LeapYearCount(UNIX_TIME_BASE_YEAR - 1); |
| 144 | static constexpr i64 MinTimestamp = StartDays * static_cast<i64>(SECONDS_PER_DAY); |
| 145 | static constexpr i64 MaxTimestamp = MinTimestamp + static_cast<i64>(TableSize) * DAYS_IN_LEAP_YEAR * SECONDS_PER_DAY - 1; |
| 146 | constexpr TDayNoToYearLookupTable() { |
| 147 | ui16 daysAccumulated = 0; |
| 148 | |
| 149 | for (int year = StartYear; year < StartYear + TableSize; ++year) { |
| 150 | daysAccumulated += YearSize(year); |
| 151 | DaysSinceEpoch[year - StartYear] = daysAccumulated; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | // lookup year by days since epoch, decrement day counter to the corresponding amount of days. |
| 156 | // The method returns the last year in the table, if year is too big |
| 157 | int FindYear(ui32& days) const { |
| 158 | const ui32 yearIndex = days / DAYS_IN_LEAP_YEAR; |
| 159 | |
| 160 | // we can miss by at most 1 year |
| 161 | Y_ASSERT(yearIndex < TableSize); |
| 162 | if (const auto diff = DaysSinceEpoch[yearIndex]; diff <= days) { |
| 163 | days -= diff; |
| 164 | return static_cast<int>(yearIndex + StartYear + 1); |
| 165 | } |
| 166 | |
| 167 | if (yearIndex > 0) { |
| 168 | days -= DaysSinceEpoch[yearIndex - 1]; |
| 169 | } |
| 170 | |
| 171 | return static_cast<int>(yearIndex + StartYear); |
| 172 | } |
| 173 | }; |
| 174 | |
| 175 | constexpr TDayNoToYearLookupTable DAYS_TO_YEAR_LOOKUP; |
| 176 | } // namespace |
nothing calls this directly
no test coverage detected