Skip to content

Commit

Permalink
util: optimize RingBuffer implementation
Browse files Browse the repository at this point in the history
Slight optimization for RingBuffer that will allocate the exact array,
and manually keep track of the head and tail pointers.
  • Loading branch information
trevnorris committed Feb 15, 2024
1 parent f3261fc commit 2074ce1
Showing 1 changed file with 34 additions and 17 deletions.
51 changes: 34 additions & 17 deletions src/nsolid/nsolid_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,44 +198,61 @@ template <typename T>
class RingBuffer {
public:
NSOLID_DELETE_DEFAULT_CONSTRUCTORS(RingBuffer)
explicit RingBuffer(size_t s) : size_(s) {
explicit RingBuffer(size_t s)
: capacity_(s),
head_(0),
tail_(0),
is_full_(false) {
buffer_ = new T[s];
}

bool empty() const {
return buffer_.empty();
~RingBuffer() {
delete[] buffer_;
}

const T& front() const {
return buffer_.front();
bool empty() const {
return (!is_full_ && (head_ == tail_));
}

// Make sure to check empty() first otherwise an invalid value will be
// returned.
T& front() {
return buffer_.front();
return buffer_[head_];
}

void pop() {
buffer_.pop();
if (empty())
return;
head_ = (head_ + 1) % capacity_;
is_full_ = false;
}

void push(const T& value) {
if (buffer_.size() == size_) {
buffer_.pop();
void push(T& value) {
buffer_[tail_] = value;
tail_ = (tail_ + 1) % capacity_;

if (is_full_) {
head_ = (head_ + 1) % capacity_;
}

buffer_.push(value);
is_full_ = tail_ == head_;
}

void push(T&& value) {
if (buffer_.size() == size_) {
buffer_.pop();
}
buffer_[tail_] = value;
tail_ = (tail_ + 1) % capacity_;

buffer_.push(value);
if (is_full_)
head_ = (head_ + 1) % capacity_;
is_full_ = tail_ == head_;
}

private:
const size_t size_;
std::queue<T> buffer_;
T* buffer_;
size_t capacity_;
size_t head_;
size_t tail_;
bool is_full_;
};

} // namespace utils
Expand Down

0 comments on commit 2074ce1

Please sign in to comment.