完成主要交互、高性能组件、国际化和A型传感器数据包接收
This commit is contained in:
82
src/ringbuffer.h
Normal file
82
src/ringbuffer.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef RINGBUFFER_H
|
||||
#define RINGBUFFER_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
template<typename T>
|
||||
class RingBuffer {
|
||||
|
||||
public:
|
||||
explicit RingBuffer(size_t capacity, T initValue = T{})
|
||||
: m_capacity(capacity)
|
||||
, m_data(capacity, initValue) {}
|
||||
|
||||
inline void push(const T& v) {
|
||||
const uint64_t w = m_write.fetch_add(1, std::memory_order_relaxed);
|
||||
m_data[w % m_capacity] = v;
|
||||
const uint64_t newSize = std::min<uint64_t>(w + 1, m_capacity);
|
||||
m_size.store(newSize, std::memory_order_release);
|
||||
}
|
||||
|
||||
inline uint64_t size() const {
|
||||
return m_size.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
inline uint64_t capacity() const {
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
inline uint64_t oldestGlobalIndex() const {
|
||||
const uint64_t w = m_write.load(std::memory_order_acquire);
|
||||
const uint64_t s = size();
|
||||
return (w >= s) ? (w - s) : 0;
|
||||
}
|
||||
|
||||
inline uint64_t newestGlobalIndex() const {
|
||||
const uint64_t w = m_write.load(std::memory_order_acquire);
|
||||
return (w > 0) ? (w - 1) : 0;
|
||||
}
|
||||
|
||||
inline bool readByGlobalIndex(uint64_t gidx, T& out) const {
|
||||
const uint64_t oldest = oldestGlobalIndex();
|
||||
const uint64_t newest = newestGlobalIndex();
|
||||
if (gidx < oldest || gidx > newest)
|
||||
return false;
|
||||
|
||||
out = m_data[gidx % m_capacity];
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void reset() {
|
||||
m_write.store(0, std::memory_order_release);
|
||||
m_size.store(0, std::memory_order_release);
|
||||
}
|
||||
|
||||
inline void readRange(uint64_t gidx, uint64_t count, std::vector<T>& out) const {
|
||||
out.clear();
|
||||
out.reserve(count);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
T v{};
|
||||
if (readByGlobalIndex(gidx, v)) {
|
||||
out.push_back(v);
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t m_capacity;
|
||||
std::vector<T> m_data;
|
||||
std::atomic<uint64_t> m_write{0};
|
||||
std::atomic<uint64_t> m_size{0};
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user