1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef ECMASCRIPT_BASE_GC_RING_BUFFER_H
17#define ECMASCRIPT_BASE_GC_RING_BUFFER_H
18
19#include <array>
20
21#include "libpandabase/macros.h"
22
23namespace panda::ecmascript::base {
24// GC Ring Buffer is base tool class. It will be used to collect the data of the last N GCs. The max length is
25// fixed, so we call it a GC ring buffer. In this class, we define the functions to push data, count the length,
26// return the sum and reset data.
27template<typename T, int N>
28class GCRingBuffer {
29public:
30    GCRingBuffer() = default;
31    ~GCRingBuffer() = default;
32    NO_COPY_SEMANTIC(GCRingBuffer);
33    NO_MOVE_SEMANTIC(GCRingBuffer);
34
35    void Push(const T &value)
36    {
37        if (count_ == N) {
38            elements_[start_++] = value;
39            if (start_ == N) {
40                start_ = 0;
41            }
42        } else {
43            ASSERT(start_ == 0);
44            elements_[count_++] = value;
45        }
46    }
47
48    int Count() const
49    {
50        return count_;
51    }
52
53    // This function will return the sum of the elements_. The parameter callback
54    // should define the sum function of data type T.
55    template<typename Callback>
56    T Sum(Callback callback, const T &initial) const
57    {
58        T result = initial;
59        for (int i = 0; i < count_; i++) {
60            result = callback(result, elements_[i]);
61        }
62        return result;
63    }
64
65    void Reset()
66    {
67        start_ = count_ = 0;
68    }
69
70private:
71    std::array<T, N> elements_;
72    int start_ {0};
73    int count_ {0};
74};
75}  // namespace panda::ecmascript::base
76
77#endif  // ECMASCRIPT_BASE_GC_RING_BUFFER_H