aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/sliding_window
diff options
context:
space:
mode:
authorAnton Samokhvalov <pg83@yandex.ru>2022-02-10 16:45:17 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:17 +0300
commitd3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch)
treedd4bd3ca0f36b817e96812825ffaf10d645803f2 /library/cpp/sliding_window
parent72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff)
downloadydb-d3a398281c6fd1d3672036cb2d63f842d2cb28c5.tar.gz
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/sliding_window')
-rw-r--r--library/cpp/sliding_window/sliding_window.h390
-rw-r--r--library/cpp/sliding_window/sliding_window_ut.cpp126
2 files changed, 258 insertions, 258 deletions
diff --git a/library/cpp/sliding_window/sliding_window.h b/library/cpp/sliding_window/sliding_window.h
index 2613fd46ea..180bdf93d0 100644
--- a/library/cpp/sliding_window/sliding_window.h
+++ b/library/cpp/sliding_window/sliding_window.h
@@ -11,214 +11,214 @@
#include <limits>
namespace NSlidingWindow {
- namespace NPrivate {
- template <class TValueType_, class TCmp, TValueType_ initialValue> // std::less for max, std::greater for min
- struct TMinMaxOperationImpl {
- using TValueType = TValueType_;
- using TValueVector = TVector<TValueType>;
-
- static constexpr TValueType InitialValue() {
- return initialValue;
- }
-
- // Updates value in current bucket and returns window value
- static TValueType UpdateBucket(TValueType windowValue, TValueVector& buckets, size_t index, TValueType newVal) {
- Y_ASSERT(index < buckets.size());
- TCmp cmp;
- TValueType& curVal = buckets[index];
- if (cmp(curVal, newVal)) {
- curVal = newVal;
- if (cmp(windowValue, newVal)) {
- windowValue = newVal;
- }
- }
- return windowValue;
+ namespace NPrivate {
+ template <class TValueType_, class TCmp, TValueType_ initialValue> // std::less for max, std::greater for min
+ struct TMinMaxOperationImpl {
+ using TValueType = TValueType_;
+ using TValueVector = TVector<TValueType>;
+
+ static constexpr TValueType InitialValue() {
+ return initialValue;
}
- static TValueType ClearBuckets(TValueType windowValue, TValueVector& buckets, const size_t firstElemIndex, const size_t bucketsToClear) {
- Y_ASSERT(!buckets.empty());
- Y_ASSERT(firstElemIndex < buckets.size());
- Y_ASSERT(bucketsToClear <= buckets.size());
- TCmp cmp;
-
- bool needRecalc = false;
- size_t current = firstElemIndex;
- const size_t arraySize = buckets.size();
- for (size_t i = 0; i < bucketsToClear; ++i) {
- TValueType& curVal = buckets[current];
- if (!needRecalc && windowValue == curVal) {
- needRecalc = true;
- }
- curVal = InitialValue();
- current = (current + 1) % arraySize;
+ // Updates value in current bucket and returns window value
+ static TValueType UpdateBucket(TValueType windowValue, TValueVector& buckets, size_t index, TValueType newVal) {
+ Y_ASSERT(index < buckets.size());
+ TCmp cmp;
+ TValueType& curVal = buckets[index];
+ if (cmp(curVal, newVal)) {
+ curVal = newVal;
+ if (cmp(windowValue, newVal)) {
+ windowValue = newVal;
+ }
}
- if (needRecalc) {
- windowValue = InitialValue();
- for (size_t i = 0; i < firstElemIndex; ++i) {
- const TValueType val = buckets[i];
- if (cmp(windowValue, val)) {
- windowValue = val;
- }
- }
- for (size_t i = current, size = buckets.size(); i < size; ++i) {
- const TValueType val = buckets[i];
- if (cmp(windowValue, val)) {
- windowValue = val;
- }
- }
+ return windowValue;
+ }
+
+ static TValueType ClearBuckets(TValueType windowValue, TValueVector& buckets, const size_t firstElemIndex, const size_t bucketsToClear) {
+ Y_ASSERT(!buckets.empty());
+ Y_ASSERT(firstElemIndex < buckets.size());
+ Y_ASSERT(bucketsToClear <= buckets.size());
+ TCmp cmp;
+
+ bool needRecalc = false;
+ size_t current = firstElemIndex;
+ const size_t arraySize = buckets.size();
+ for (size_t i = 0; i < bucketsToClear; ++i) {
+ TValueType& curVal = buckets[current];
+ if (!needRecalc && windowValue == curVal) {
+ needRecalc = true;
+ }
+ curVal = InitialValue();
+ current = (current + 1) % arraySize;
+ }
+ if (needRecalc) {
+ windowValue = InitialValue();
+ for (size_t i = 0; i < firstElemIndex; ++i) {
+ const TValueType val = buckets[i];
+ if (cmp(windowValue, val)) {
+ windowValue = val;
+ }
+ }
+ for (size_t i = current, size = buckets.size(); i < size; ++i) {
+ const TValueType val = buckets[i];
+ if (cmp(windowValue, val)) {
+ windowValue = val;
+ }
+ }
}
- return windowValue;
+ return windowValue;
}
- };
-
+ };
+
}
- template <class TValueType>
- using TMaxOperation = NPrivate::TMinMaxOperationImpl<TValueType, std::less<TValueType>, std::numeric_limits<TValueType>::min()>;
-
- template <class TValueType>
- using TMinOperation = NPrivate::TMinMaxOperationImpl<TValueType, std::greater<TValueType>, std::numeric_limits<TValueType>::max()>;
-
- template <class TValueType_>
- struct TSumOperation {
- using TValueType = TValueType_;
- using TValueVector = TVector<TValueType>;
-
- static constexpr TValueType InitialValue() {
- return TValueType(); // zero
- }
-
- // Updates value in current bucket and returns window value
- static TValueType UpdateBucket(TValueType windowValue, TValueVector& buckets, size_t index, TValueType newVal) {
- Y_ASSERT(index < buckets.size());
- buckets[index] += newVal;
- windowValue += newVal;
- return windowValue;
- }
-
- static TValueType ClearBuckets(TValueType windowValue, TValueVector& buckets, size_t firstElemIndex, size_t bucketsToClear) {
- Y_ASSERT(!buckets.empty());
- Y_ASSERT(firstElemIndex < buckets.size());
- Y_ASSERT(bucketsToClear <= buckets.size());
-
- const size_t arraySize = buckets.size();
- for (size_t i = 0; i < bucketsToClear; ++i) {
- TValueType& curVal = buckets[firstElemIndex];
- windowValue -= curVal;
- curVal = InitialValue();
- firstElemIndex = (firstElemIndex + 1) % arraySize;
- }
- return windowValue;
+ template <class TValueType>
+ using TMaxOperation = NPrivate::TMinMaxOperationImpl<TValueType, std::less<TValueType>, std::numeric_limits<TValueType>::min()>;
+
+ template <class TValueType>
+ using TMinOperation = NPrivate::TMinMaxOperationImpl<TValueType, std::greater<TValueType>, std::numeric_limits<TValueType>::max()>;
+
+ template <class TValueType_>
+ struct TSumOperation {
+ using TValueType = TValueType_;
+ using TValueVector = TVector<TValueType>;
+
+ static constexpr TValueType InitialValue() {
+ return TValueType(); // zero
}
- };
-
- /////////////////////////////////////////////////////////////////////////////////////////
- // TSlidingWindow
- /////////////////////////////////////////////////////////////////////////////////////////
- template <class TOperation, class TMutexImpl = TFakeMutex>
- class TSlidingWindow {
- public:
- using TValueType = typename TOperation::TValueType;
+
+ // Updates value in current bucket and returns window value
+ static TValueType UpdateBucket(TValueType windowValue, TValueVector& buckets, size_t index, TValueType newVal) {
+ Y_ASSERT(index < buckets.size());
+ buckets[index] += newVal;
+ windowValue += newVal;
+ return windowValue;
+ }
+
+ static TValueType ClearBuckets(TValueType windowValue, TValueVector& buckets, size_t firstElemIndex, size_t bucketsToClear) {
+ Y_ASSERT(!buckets.empty());
+ Y_ASSERT(firstElemIndex < buckets.size());
+ Y_ASSERT(bucketsToClear <= buckets.size());
+
+ const size_t arraySize = buckets.size();
+ for (size_t i = 0; i < bucketsToClear; ++i) {
+ TValueType& curVal = buckets[firstElemIndex];
+ windowValue -= curVal;
+ curVal = InitialValue();
+ firstElemIndex = (firstElemIndex + 1) % arraySize;
+ }
+ return windowValue;
+ }
+ };
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // TSlidingWindow
+ /////////////////////////////////////////////////////////////////////////////////////////
+ template <class TOperation, class TMutexImpl = TFakeMutex>
+ class TSlidingWindow {
+ public:
+ using TValueType = typename TOperation::TValueType;
using TValueVector = TVector<TValueType>;
using TSizeType = typename TValueVector::size_type;
- public:
+ public:
TSlidingWindow(const TDuration& length, TSizeType partsNum)
- : Mutex()
- , Buckets(partsNum, TOperation::InitialValue()) // vector of size partsNum initialized with initial value
- , WindowValue(TOperation::InitialValue())
- , FirstElem(0)
- , PeriodStart()
- , Length(length)
- , MicroSecondsPerBucket(length.MicroSeconds() / partsNum)
- {
- }
-
- TSlidingWindow(const TSlidingWindow& w)
- : Mutex()
- {
- TGuard<TMutexImpl> guard(&w.Mutex);
- Buckets = w.Buckets;
- WindowValue = w.WindowValue;
- FirstElem = w.FirstElem;
- PeriodStart = w.PeriodStart;
- Length = w.Length;
- MicroSecondsPerBucket = w.MicroSecondsPerBucket;
- }
-
- TSlidingWindow(TSlidingWindow&&) = default;
-
- TSlidingWindow& operator=(TSlidingWindow&&) = default;
- TSlidingWindow& operator=(const TSlidingWindow&) = delete;
-
- // Period of time
- const TDuration& GetDuration() const {
- return Length;
- }
-
- // Update window with new value and time
- TValueType Update(TValueType val, TInstant t) {
- TGuard<TMutexImpl> guard(&Mutex);
- AdvanceTime(t);
- UpdateCurrentBucket(val);
- return WindowValue;
- }
-
- // Update just time, without new values
- TValueType Update(TInstant t) {
- TGuard<TMutexImpl> guard(&Mutex);
- AdvanceTime(t);
- return WindowValue;
- }
-
- // Get current window value (without updating current time)
- TValueType GetValue() const {
- TGuard<TMutexImpl> guard(&Mutex);
- return WindowValue;
+ : Mutex()
+ , Buckets(partsNum, TOperation::InitialValue()) // vector of size partsNum initialized with initial value
+ , WindowValue(TOperation::InitialValue())
+ , FirstElem(0)
+ , PeriodStart()
+ , Length(length)
+ , MicroSecondsPerBucket(length.MicroSeconds() / partsNum)
+ {
}
- private:
- void UpdateCurrentBucket(TValueType val) {
- const TSizeType arraySize = Buckets.size();
- const TSizeType pos = (FirstElem + arraySize - 1) % arraySize;
- WindowValue = TOperation::UpdateBucket(WindowValue, Buckets, pos, val);
+ TSlidingWindow(const TSlidingWindow& w)
+ : Mutex()
+ {
+ TGuard<TMutexImpl> guard(&w.Mutex);
+ Buckets = w.Buckets;
+ WindowValue = w.WindowValue;
+ FirstElem = w.FirstElem;
+ PeriodStart = w.PeriodStart;
+ Length = w.Length;
+ MicroSecondsPerBucket = w.MicroSecondsPerBucket;
+ }
+
+ TSlidingWindow(TSlidingWindow&&) = default;
+
+ TSlidingWindow& operator=(TSlidingWindow&&) = default;
+ TSlidingWindow& operator=(const TSlidingWindow&) = delete;
+
+ // Period of time
+ const TDuration& GetDuration() const {
+ return Length;
}
- void AdvanceTime(const TInstant& time) {
- if (time < PeriodStart + Length) {
- return;
- }
-
- if (PeriodStart.MicroSeconds() == 0) {
- PeriodStart = time - Length;
- return;
- }
-
- const TInstant& newPeriodStart = time - Length;
- const ui64 tmDiff = (newPeriodStart - PeriodStart).MicroSeconds();
- const TSizeType bucketsDiff = tmDiff / MicroSecondsPerBucket;
- const TSizeType arraySize = Buckets.size();
- const TSizeType buckets = Min(bucketsDiff, arraySize);
-
- WindowValue = TOperation::ClearBuckets(WindowValue, Buckets, FirstElem, buckets);
- FirstElem = (FirstElem + buckets) % arraySize;
- PeriodStart += TDuration::MicroSeconds(bucketsDiff * MicroSecondsPerBucket);
-
- // Check that PeriodStart lags behind newPeriodStart
- // (which is actual, uptodate, precise and equal to time - Length) not more
- // then MicroSecondsPerBucket
- Y_ASSERT(newPeriodStart >= PeriodStart);
- Y_ASSERT((newPeriodStart - PeriodStart).MicroSeconds() <= MicroSecondsPerBucket);
- }
-
-
- mutable TMutexImpl Mutex;
- TValueVector Buckets;
- TValueType WindowValue;
- TSizeType FirstElem;
- TInstant PeriodStart;
- TDuration Length;
- ui64 MicroSecondsPerBucket;
- };
-
-}
+ // Update window with new value and time
+ TValueType Update(TValueType val, TInstant t) {
+ TGuard<TMutexImpl> guard(&Mutex);
+ AdvanceTime(t);
+ UpdateCurrentBucket(val);
+ return WindowValue;
+ }
+
+ // Update just time, without new values
+ TValueType Update(TInstant t) {
+ TGuard<TMutexImpl> guard(&Mutex);
+ AdvanceTime(t);
+ return WindowValue;
+ }
+
+ // Get current window value (without updating current time)
+ TValueType GetValue() const {
+ TGuard<TMutexImpl> guard(&Mutex);
+ return WindowValue;
+ }
+
+ private:
+ void UpdateCurrentBucket(TValueType val) {
+ const TSizeType arraySize = Buckets.size();
+ const TSizeType pos = (FirstElem + arraySize - 1) % arraySize;
+ WindowValue = TOperation::UpdateBucket(WindowValue, Buckets, pos, val);
+ }
+
+ void AdvanceTime(const TInstant& time) {
+ if (time < PeriodStart + Length) {
+ return;
+ }
+
+ if (PeriodStart.MicroSeconds() == 0) {
+ PeriodStart = time - Length;
+ return;
+ }
+
+ const TInstant& newPeriodStart = time - Length;
+ const ui64 tmDiff = (newPeriodStart - PeriodStart).MicroSeconds();
+ const TSizeType bucketsDiff = tmDiff / MicroSecondsPerBucket;
+ const TSizeType arraySize = Buckets.size();
+ const TSizeType buckets = Min(bucketsDiff, arraySize);
+
+ WindowValue = TOperation::ClearBuckets(WindowValue, Buckets, FirstElem, buckets);
+ FirstElem = (FirstElem + buckets) % arraySize;
+ PeriodStart += TDuration::MicroSeconds(bucketsDiff * MicroSecondsPerBucket);
+
+ // Check that PeriodStart lags behind newPeriodStart
+ // (which is actual, uptodate, precise and equal to time - Length) not more
+ // then MicroSecondsPerBucket
+ Y_ASSERT(newPeriodStart >= PeriodStart);
+ Y_ASSERT((newPeriodStart - PeriodStart).MicroSeconds() <= MicroSecondsPerBucket);
+ }
+
+
+ mutable TMutexImpl Mutex;
+ TValueVector Buckets;
+ TValueType WindowValue;
+ TSizeType FirstElem;
+ TInstant PeriodStart;
+ TDuration Length;
+ ui64 MicroSecondsPerBucket;
+ };
+
+}
diff --git a/library/cpp/sliding_window/sliding_window_ut.cpp b/library/cpp/sliding_window/sliding_window_ut.cpp
index 35f04b21b2..1e7343a8d3 100644
--- a/library/cpp/sliding_window/sliding_window_ut.cpp
+++ b/library/cpp/sliding_window/sliding_window_ut.cpp
@@ -9,40 +9,40 @@ Y_UNIT_TEST_SUITE(TSlidingWindowTest) {
TSlidingWindow<TMaxOperation<unsigned>> w(TDuration::Minutes(5), 5);
TInstant start = TInstant::MicroSeconds(TDuration::Hours(1).MicroSeconds());
TInstant now = start;
- w.Update(5, start); // ~ ~ ~ ~ 5
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(5, start); // ~ ~ ~ ~ 5
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
now += TDuration::Minutes(1) + TDuration::Seconds(1);
- w.Update(5, now); // 5 ~ ~ ~ 5
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(5, now); // 5 ~ ~ ~ 5
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
now += TDuration::Minutes(1);
- w.Update(3, now); // 5 3 ~ ~ 5
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(3, now); // 5 3 ~ ~ 5
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
now += TDuration::Minutes(3);
- w.Update(2, now); // 5 3 ~ ~ 2
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(2, now); // 5 3 ~ ~ 2
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
now += TDuration::Minutes(1);
- w.Update(2, now); // 2 3 ~ ~ 2
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 3); // ^
+ w.Update(2, now); // 2 3 ~ ~ 2
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 3); // ^
now += TDuration::Minutes(1);
- w.Update(2, now); // 2 2 ~ ~ 2
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 2); // ^
+ w.Update(2, now); // 2 2 ~ ~ 2
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 2); // ^
now += TDuration::Minutes(5);
- w.Update(1, now); // ~ 1 ~ ~ ~
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 1); // ^
+ w.Update(1, now); // ~ 1 ~ ~ ~
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 1); // ^
// update current bucket
- w.Update(2, now); // ~ 2 ~ ~ ~
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 2); // ^
+ w.Update(2, now); // ~ 2 ~ ~ ~
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 2); // ^
- w.Update(1, now + TDuration::Seconds(30)); // ~ 2 ~ ~ ~
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 2); // ^
+ w.Update(1, now + TDuration::Seconds(30)); // ~ 2 ~ ~ ~
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 2); // ^
// test idle
now += TDuration::Minutes(1);
- w.Update(now); // ~ 2 ~ ~ ~
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 2); // ^
+ w.Update(now); // ~ 2 ~ ~ ~
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 2); // ^
- now += TDuration::Minutes(5); // ~ ~ ~ ~ ~
+ now += TDuration::Minutes(5); // ~ ~ ~ ~ ~
UNIT_ASSERT_VALUES_EQUAL(w.Update(now), 0);
}
@@ -50,40 +50,40 @@ Y_UNIT_TEST_SUITE(TSlidingWindowTest) {
TSlidingWindow<TMinOperation<unsigned>> w(TDuration::Minutes(5), 5);
TInstant start = TInstant::MicroSeconds(TDuration::Hours(1).MicroSeconds());
TInstant now = start;
- w.Update(5, start); // ~ ~ ~ ~ 5
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(5, start); // ~ ~ ~ ~ 5
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
now += TDuration::Minutes(1) + TDuration::Seconds(1);
- w.Update(5, now); // 5 ~ ~ ~ 5
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(5, now); // 5 ~ ~ ~ 5
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
now += TDuration::Minutes(1);
- w.Update(7, now); // 5 7 ~ ~ 5
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(7, now); // 5 7 ~ ~ 5
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
now += TDuration::Minutes(3);
- w.Update(8, now); // 5 7 ~ ~ 8
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(8, now); // 5 7 ~ ~ 8
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
now += TDuration::Minutes(1);
- w.Update(8, now); // 8 7 ~ ~ 8
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 7); // ^
+ w.Update(8, now); // 8 7 ~ ~ 8
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 7); // ^
now += TDuration::Minutes(1);
- w.Update(8, now); // 8 8 ~ ~ 8
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 8); // ^
+ w.Update(8, now); // 8 8 ~ ~ 8
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 8); // ^
now += TDuration::Minutes(5);
- w.Update(6, now); // ~ 6 ~ ~ ~
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 6); // ^
+ w.Update(6, now); // ~ 6 ~ ~ ~
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 6); // ^
// update current bucket
- w.Update(5, now); // ~ 5 ~ ~ ~
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(5, now); // ~ 5 ~ ~ ~
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
- w.Update(6, now + TDuration::Seconds(30)); // ~ 5 ~ ~ ~
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(6, now + TDuration::Seconds(30)); // ~ 5 ~ ~ ~
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
// test idle
now += TDuration::Minutes(1);
- w.Update(now); // ~ 5 ~ ~ ~
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(now); // ~ 5 ~ ~ ~
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
- now += TDuration::Minutes(5); // ~ ~ ~ ~ ~
+ now += TDuration::Minutes(5); // ~ ~ ~ ~ ~
UNIT_ASSERT_VALUES_EQUAL(w.Update(now), std::numeric_limits<unsigned>::max());
}
@@ -93,40 +93,40 @@ Y_UNIT_TEST_SUITE(TSlidingWindowTest) {
TInstant start = TInstant::MicroSeconds(TDuration::Hours(1).MicroSeconds());
TInstant now = start;
- w.Update(5, start); // 0 0 0 0 5
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
+ w.Update(5, start); // 0 0 0 0 5
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 5); // ^
now += TDuration::Minutes(1) + TDuration::Seconds(1);
- w.Update(5, now); // 5 0 0 0 5
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 10); // ^
+ w.Update(5, now); // 5 0 0 0 5
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 10); // ^
now += TDuration::Minutes(1);
- w.Update(3, now); // 5 3 0 0 5
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 13); // ^
+ w.Update(3, now); // 5 3 0 0 5
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 13); // ^
now += TDuration::Minutes(3);
- w.Update(2, now); // 5 3 0 0 2
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 10); // ^
+ w.Update(2, now); // 5 3 0 0 2
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 10); // ^
now += TDuration::Minutes(1);
- w.Update(2, now); // 2 3 0 0 2
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 7); // ^
+ w.Update(2, now); // 2 3 0 0 2
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 7); // ^
now += TDuration::Minutes(1);
- w.Update(2, now); // 2 2 0 0 2
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 6); // ^
+ w.Update(2, now); // 2 2 0 0 2
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 6); // ^
now += TDuration::Minutes(5);
- w.Update(1, now); // 0 1 0 0 0
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 1); // ^
+ w.Update(1, now); // 0 1 0 0 0
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 1); // ^
// update current bucket
- w.Update(2, now); // 0 3 0 0 0
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 3); // ^
+ w.Update(2, now); // 0 3 0 0 0
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 3); // ^
- w.Update(1, now + TDuration::Seconds(30)); // 0 4 0 0 0
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 4); // ^
+ w.Update(1, now + TDuration::Seconds(30)); // 0 4 0 0 0
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 4); // ^
// test idle
now += TDuration::Minutes(1);
- w.Update(now); // 0 4 0 0 0
- UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 4); // ^
+ w.Update(now); // 0 4 0 0 0
+ UNIT_ASSERT_VALUES_EQUAL(w.GetValue(), 4); // ^
- now += TDuration::Minutes(5); // 0 0 0 0 0
+ now += TDuration::Minutes(5); // 0 0 0 0 0
UNIT_ASSERT_VALUES_EQUAL(w.Update(now), 0);
}
}