diff options
author | Determinant <ted.sybil@gmail.com> | 2018-11-11 23:02:59 -0500 |
---|---|---|
committer | Determinant <ted.sybil@gmail.com> | 2018-11-11 23:02:59 -0500 |
commit | dd09443b0b3c0b5d1a8c034644d1065dd25bf5a9 (patch) | |
tree | f770ccffa4ae89bfec00c65e162f4f0d0613c3ae /include/salticidae/buffer.h | |
parent | b7d65ee96221e63c865b1bf8cda79b3021cba412 (diff) |
start debugging multiloops design
Diffstat (limited to 'include/salticidae/buffer.h')
-rw-r--r-- | include/salticidae/buffer.h | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/include/salticidae/buffer.h b/include/salticidae/buffer.h new file mode 100644 index 0000000..3f415c9 --- /dev/null +++ b/include/salticidae/buffer.h @@ -0,0 +1,148 @@ +#ifndef _SALTICIDAE_BUFFER_H +#define _SALTICIDAE_BUFFER_H + +#include <list> + +namespace salticidae { + +class SegBuffer { + public: + struct buffer_entry_t { + bytearray_t data; + bytearray_t::iterator offset; + buffer_entry_t(): offset(data.begin()) {} + buffer_entry_t(bytearray_t &&_data): + data(std::move(_data)), offset(data.begin()) {} + + buffer_entry_t(buffer_entry_t &&other) { + size_t _offset = other.offset - other.data.begin(); + data = std::move(other.data); + offset = data.begin() + _offset; + } + + buffer_entry_t &operator=(buffer_entry_t &&other) { + size_t _offset = other.offset - other.data.begin(); + data = std::move(other.data); + offset = data.begin() + _offset; + return *this; + } + + buffer_entry_t(const buffer_entry_t &other): data(other.data) { + offset = data.begin() + (other.offset - other.data.begin()); + } + + size_t length() const { return data.end() - offset; } + }; + + private: + std::list<buffer_entry_t> buffer; + size_t _size; + + public: + SegBuffer(): _size(0) {} + ~SegBuffer() { clear(); } + + void swap(SegBuffer &other) { + std::swap(buffer, other.buffer); + std::swap(_size, other._size); + } + + SegBuffer(const SegBuffer &other): + buffer(other.buffer), _size(other._size) {} + + SegBuffer(SegBuffer &&other): + buffer(std::move(other.buffer)), _size(other._size) { + other._size = 0; + } + + SegBuffer &operator=(SegBuffer &&other) { + if (this != &other) + { + SegBuffer tmp(std::move(other)); + tmp.swap(*this); + } + return *this; + } + + SegBuffer &operator=(const SegBuffer &other) { + if (this != &other) + { + SegBuffer tmp(other); + tmp.swap(*this); + } + return *this; + } + + void rewind(bytearray_t &&data) { + _size += data.size(); + buffer.push_front(buffer_entry_t(std::move(data))); + } + + void push(bytearray_t &&data) { + _size += data.size(); + buffer.push_back(buffer_entry_t(std::move(data))); + } + + bytearray_t move_pop() { + auto res = std::move(buffer.front().data); + buffer.pop_front(); + _size -= res.size(); + return std::move(res); + } + + bytearray_t pop(size_t len) { + bytearray_t res; + auto i = buffer.begin(); + while (len && i != buffer.end()) + { + size_t copy_len = std::min(i->length(), len); + res.insert(res.end(), i->offset, i->offset + copy_len); + i->offset += copy_len; + len -= copy_len; + if (i->offset == i->data.end()) + i++; + } + buffer.erase(buffer.begin(), i); + _size -= res.size(); + return std::move(res); + } + + size_t size() const { return _size; } + bool empty() const { return buffer.empty(); } + + void clear() { + buffer.clear(); + _size = 0; + } +}; + +struct MPSCWriteBuffer { + using buffer_entry_t = SegBuffer::buffer_entry_t; + using queue_t = MPSCQueueEventDriven<buffer_entry_t>; + queue_t buffer; + + MPSCWriteBuffer() {} + + MPSCWriteBuffer(const SegBuffer &other) = delete; + MPSCWriteBuffer(SegBuffer &&other) = delete; + + void rewind(bytearray_t &&data) { + buffer.rewind(buffer_entry_t(std::move(data))); + } + + void push(bytearray_t &&data) { + buffer.enqueue(buffer_entry_t(std::move(data))); + } + + bytearray_t move_pop() { + buffer_entry_t res; + buffer.try_dequeue(res); + return std::move(res.data); + } + + queue_t &get_queue() { return buffer; } +}; + +} + +#endif |