RingBuffer - buffer on heap instead of stack
Summary: RingBuffer - buffer in vector Reviewers: mislav.bradac, buda, dgleich Reviewed By: mislav.bradac Differential Revision: https://phabricator.memgraph.io/D952
This commit is contained in:
parent
196b17417a
commit
f2aad117cf
@ -6,6 +6,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "glog/logging.h"
|
#include "glog/logging.h"
|
||||||
|
|
||||||
@ -17,10 +18,11 @@
|
|||||||
*
|
*
|
||||||
* @tparam TElement - type of element the buffer tracks.
|
* @tparam TElement - type of element the buffer tracks.
|
||||||
*/
|
*/
|
||||||
template <typename TElement, int capacity>
|
template <typename TElement>
|
||||||
class RingBuffer {
|
class RingBuffer {
|
||||||
public:
|
public:
|
||||||
RingBuffer() = default;
|
RingBuffer(int capacity) : buffer_(capacity) {}
|
||||||
|
|
||||||
RingBuffer(const RingBuffer &) = delete;
|
RingBuffer(const RingBuffer &) = delete;
|
||||||
RingBuffer(RingBuffer &&) = delete;
|
RingBuffer(RingBuffer &&) = delete;
|
||||||
RingBuffer &operator=(const RingBuffer &) = delete;
|
RingBuffer &operator=(const RingBuffer &) = delete;
|
||||||
@ -31,9 +33,9 @@ class RingBuffer {
|
|||||||
while (true) {
|
while (true) {
|
||||||
{
|
{
|
||||||
std::lock_guard<SpinLock> guard(lock_);
|
std::lock_guard<SpinLock> guard(lock_);
|
||||||
if (size_ < capacity) {
|
if (size_ < buffer_.size()) {
|
||||||
buffer_[write_pos_++] = TElement(std::forward<TArgs>(args)...);
|
buffer_[write_pos_++] = TElement(std::forward<TArgs>(args)...);
|
||||||
write_pos_ %= capacity;
|
write_pos_ %= buffer_.size();
|
||||||
size_++;
|
size_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -52,12 +54,12 @@ class RingBuffer {
|
|||||||
size_--;
|
size_--;
|
||||||
std::experimental::optional<TElement> result(
|
std::experimental::optional<TElement> result(
|
||||||
std::move(buffer_[read_pos_++]));
|
std::move(buffer_[read_pos_++]));
|
||||||
read_pos_ %= capacity;
|
read_pos_ %= buffer_.size();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TElement buffer_[capacity];
|
std::vector<TElement> buffer_;
|
||||||
SpinLock lock_;
|
SpinLock lock_;
|
||||||
int read_pos_{0};
|
int read_pos_{0};
|
||||||
int write_pos_{0};
|
int write_pos_{0};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
class RingBufferMultiThreaded : public benchmark::Fixture {
|
class RingBufferMultiThreaded : public benchmark::Fixture {
|
||||||
protected:
|
protected:
|
||||||
RingBuffer<int, 1024> buffer;
|
RingBuffer<int> buffer{1024};
|
||||||
};
|
};
|
||||||
|
|
||||||
BENCHMARK_DEFINE_F(RingBufferMultiThreaded, MT)(benchmark::State &st) {
|
BENCHMARK_DEFINE_F(RingBufferMultiThreaded, MT)(benchmark::State &st) {
|
||||||
|
@ -13,7 +13,7 @@ TEST(RingBuffer, MultithreadedUsage) {
|
|||||||
|
|
||||||
std::unordered_set<int> consumed;
|
std::unordered_set<int> consumed;
|
||||||
SpinLock consumed_lock;
|
SpinLock consumed_lock;
|
||||||
RingBuffer<int, 20> buffer;
|
RingBuffer<int> buffer{20};
|
||||||
|
|
||||||
std::vector<std::thread> producers;
|
std::vector<std::thread> producers;
|
||||||
for (int i = 0; i < producer_count; i++)
|
for (int i = 0; i < producer_count; i++)
|
||||||
@ -61,7 +61,7 @@ TEST(RingBuffer, MultithreadedUsage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(RingBuffer, ComplexValues) {
|
TEST(RingBuffer, ComplexValues) {
|
||||||
RingBuffer<std::vector<int>, 10> buffer;
|
RingBuffer<std::vector<int>> buffer{10};
|
||||||
std::vector<int> element;
|
std::vector<int> element;
|
||||||
for (int i = 0 ; i < 5 ; i++) {
|
for (int i = 0 ; i < 5 ; i++) {
|
||||||
element.emplace_back(i);
|
element.emplace_back(i);
|
||||||
@ -78,7 +78,7 @@ TEST(RingBuffer, ComplexValues) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(RingBuffer, NonCopyable) {
|
TEST(RingBuffer, NonCopyable) {
|
||||||
RingBuffer<std::unique_ptr<std::string>, 10> buffer;
|
RingBuffer<std::unique_ptr<std::string>> buffer{10};
|
||||||
buffer.emplace(new std::string("string"));
|
buffer.emplace(new std::string("string"));
|
||||||
buffer.emplace(new std::string("kifla"));
|
buffer.emplace(new std::string("kifla"));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user