aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/containers/ring_buffer/ring_buffer.h
blob: 41220dcf6bf4b05825b460c62ff7fd3a3a6ff57d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#pragma once

#include <util/generic/vector.h>
#include <util/system/yassert.h>

template <typename T>
class TSimpleRingBuffer {
public:
    TSimpleRingBuffer(size_t maxSize)
        : MaxSize(maxSize)
    {
        Items.reserve(MaxSize);
    }

    TSimpleRingBuffer(const TSimpleRingBuffer&) = default;
    TSimpleRingBuffer(TSimpleRingBuffer&&) = default;

    TSimpleRingBuffer& operator=(const TSimpleRingBuffer&) = default;
    TSimpleRingBuffer& operator=(TSimpleRingBuffer&&) = default;

    // First available item
    size_t FirstIndex() const {
        return Begin;
    }

    size_t AvailSize() const {
        return Items.size();
    }

    // Total number of items inserted
    size_t TotalSize() const {
        return FirstIndex() + AvailSize();
    }

    bool IsAvail(size_t index) const {
        return index >= FirstIndex() && index < TotalSize();
    }

    const T& operator[](size_t index) const {
        Y_ASSERT(IsAvail(index));
        return Items[RealIndex(index)];
    }

    T& operator[](size_t index) {
        Y_ASSERT(IsAvail(index));
        return Items[RealIndex(index)];
    }

    void PushBack(const T& t) {
        if (Items.size() < MaxSize) {
            Items.push_back(t);
        } else {
            Items[RealIndex(Begin)] = t;
            Begin += 1;
        }
    }

    void Clear() {
        Items.clear();
        Begin = 0;
    }

private:
    size_t RealIndex(size_t index) const {
        return index % MaxSize;
    }

private:
    size_t MaxSize;
    size_t Begin = 0;
    TVector<T> Items;
};

template <typename T, size_t maxSize>
class TStaticRingBuffer: public TSimpleRingBuffer<T> {
public:
    TStaticRingBuffer()
        : TSimpleRingBuffer<T>(maxSize)
    {
    }
};