Skip to content

Commit

Permalink
negative add unit has been fixed (#4481)
Browse files Browse the repository at this point in the history
  • Loading branch information
dorooleg authored May 16, 2024
1 parent 19a2355 commit f9b9e70
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,38 @@ Y_UNIT_TEST_SUITE(TGenerateTests) {
}
)", {"year"}), yexception, "Location path 1971/ is composed by different projection value sets { ${year} = 1971-01-01 } and { ${year} = 1971-01-02 }");;
}

Y_UNIT_TEST(SuccessGenerateDateWithNegativeNow) {
auto generator = CreatePathGenerator(R"(
{
"projection.enabled" : true,
"projection.city.type" : "enum",
"projection.city.values" : "MSK,SPB",
"projection.code.type" : "date",
"projection.code.min" : "NOW - 3 DAYS",
"projection.code.max" : "NOW",
"projection.code.format" : "%F",
"projection.code.interval" : 1,
"projection.code.unit" : "DAYS",
"storage.location.template" : "/${city}/${code}/"
}
)", {"city", "code"});
auto nowBefore = TInstant::Now();
auto rules = generator->GetRules();
auto nowAfter = TInstant::Now();

TSet<TString> items;
for (auto from = std::min(nowBefore, nowAfter) - TDuration::Days(3); from <= std::max(nowBefore, nowAfter); from += TDuration::Days(1)) {
items.insert("MSK/" + from.FormatLocalTime("%F") + "/");
items.insert("SPB/" + from.FormatLocalTime("%F") + "/");
}

UNIT_ASSERT_VALUES_EQUAL(rules.size(), 8);
for (const auto& rule: rules) {
UNIT_ASSERT(items.contains(rule.Path));
UNIT_ASSERT_VALUES_EQUAL(rule.ColumnValues.size(), 2);
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ bool IsOverflow(ui64 a, ui64 b) {
return b > diff;
}

bool IsOverflow(ui64 a, i64 b) {
return b > 0 ? IsOverflow(a, (ui64)b) : a < (ui64)-b;
}

TDuration FromUnit(int64_t interval, IPathGenerator::EIntervalUnit unit) {
switch (unit) {
case IPathGenerator::EIntervalUnit::MILLISECONDS:
Expand Down Expand Up @@ -203,13 +207,17 @@ TInstant AddUnit(TInstant current, int64_t interval, IPathGenerator::EIntervalUn
return DoAddYears(current, interval);
}

const TDuration delta = FromUnit(abs(interval), unit);
if (delta.GetValue() > std::numeric_limits<i64>::max()) {
ythrow yexception() << "Interval is overflowed";
}

const TDuration delta = FromUnit(interval, unit);
if (IsOverflow(current.GetValue(), delta.GetValue())) {
const i64 deltaValue = (interval > 0 ? 1LL : -1LL) * delta.GetValue();
if (IsOverflow(current.GetValue(), deltaValue)) {
ythrow yexception() << "Timestamp is overflowed";
}

return current + delta;
return interval > 0 ? current + delta : current - delta;
}

TInstant ParseDate(const TString& dateStr, const TInstant& now) {
Expand Down

0 comments on commit f9b9e70

Please sign in to comment.