1/*
2 * Copyright 2018-present Facebook, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <folly/stats/detail/SlidingWindow.h>
20
21#include <algorithm>
22
23namespace folly {
24namespace detail {
25
26template <typename BucketT>
27SlidingWindow<BucketT>::SlidingWindow(
28 Function<BucketT(void)> fn,
29 size_t numBuckets)
30 : fn_(std::move(fn)), curHead_(0) {
31 buckets_.reserve(numBuckets);
32 for (size_t i = 0; i < numBuckets; ++i) {
33 buckets_.push_back(fn_());
34 }
35 std::reverse(buckets_.begin(), buckets_.end());
36}
37
38template <typename BucketT>
39SlidingWindow<BucketT>::SlidingWindow(SlidingWindow<BucketT>&& rhs)
40 : fn_(std::move(rhs.fn_)),
41 buckets_(std::move(rhs.buckets_)),
42 curHead_(rhs.curHead_) {}
43
44template <typename BucketT>
45std::vector<BucketT> SlidingWindow<BucketT>::get() const {
46 std::vector<BucketT> buckets;
47 buckets.reserve(buckets_.size());
48 buckets.insert(buckets.end(), buckets_.begin() + curHead_, buckets_.end());
49 buckets.insert(buckets.end(), buckets_.begin(), buckets_.begin() + curHead_);
50 return buckets;
51}
52
53template <typename BucketT>
54BucketT SlidingWindow<BucketT>::front() const {
55 return buckets_[curHead_];
56}
57
58template <typename BucketT>
59void SlidingWindow<BucketT>::set(size_t idx, BucketT bucket) {
60 if (idx < buckets_.size()) {
61 idx = (curHead_ + idx) % buckets_.size();
62 buckets_[idx] = std::move(bucket);
63 }
64}
65
66template <typename BucketT>
67void SlidingWindow<BucketT>::slide(size_t nBuckets) {
68 nBuckets = std::min(nBuckets, buckets_.size());
69 for (size_t i = 0; i < nBuckets; ++i) {
70 if (curHead_ == 0) {
71 curHead_ = buckets_.size() - 1;
72 } else {
73 curHead_--;
74 }
75 buckets_[curHead_] = fn_();
76 }
77}
78
79} // namespace detail
80} // namespace folly
81