-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathring_buffer.cpp
More file actions
117 lines (89 loc) · 4.06 KB
/
ring_buffer.cpp
File metadata and controls
117 lines (89 loc) · 4.06 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//
// Created by pengx on 2026/2/10.
//
#include "ring_buffer.hpp"
#include <algorithm>
RingBuffer::RingBuffer(const size_t capacity) : _buffer(capacity), _capacity(capacity) {}
size_t RingBuffer::write(const uint8_t* data, const size_t len) {
if (!data || len == 0)
return 0;
const size_t write_pos = _write_pos.load(std::memory_order_relaxed);
const size_t read_pos = _read_pos.load(std::memory_order_acquire);
const size_t writable = (read_pos > write_pos) ? (read_pos - write_pos - 1) : (_capacity - write_pos + read_pos);
const size_t to_write = std::min(len, writable);
if (to_write == 0)
return 0;
// 第一段:从write_pos到末尾
const size_t first_part = std::min(to_write, _capacity - write_pos);
std::memcpy(_buffer.data() + write_pos, data, first_part);
// 第二段:从开头
if (first_part < to_write) {
std::memcpy(_buffer.data(), data + first_part, to_write - first_part);
}
_write_pos.store((write_pos + to_write) % _capacity, std::memory_order_release);
return to_write;
}
size_t RingBuffer::read(uint8_t* data, const size_t len) {
if (!data || len == 0)
return 0;
const size_t read_pos = _read_pos.load(std::memory_order_relaxed);
const size_t write_pos = _write_pos.load(std::memory_order_acquire);
const size_t readable = (write_pos >= read_pos) ? (write_pos - read_pos) : (_capacity - read_pos + write_pos);
const size_t to_read = std::min(len, readable);
if (to_read == 0)
return 0;
// 第一段:从read_pos到末尾
const size_t first_part = std::min(to_read, _capacity - read_pos);
std::memcpy(data, _buffer.data() + read_pos, first_part);
// 第二段:从开头
if (first_part < to_read) {
std::memcpy(data + first_part, _buffer.data(), to_read - first_part);
}
_read_pos.store((read_pos + to_read) % _capacity, std::memory_order_release);
return to_read;
}
size_t RingBuffer::discard(const size_t len) {
if (len == 0)
return 0;
const size_t read_pos = _read_pos.load(std::memory_order_relaxed);
const size_t write_pos = _write_pos.load(std::memory_order_acquire);
const size_t readable = (write_pos >= read_pos) ? (write_pos - read_pos) : (_capacity - read_pos + write_pos);
const size_t to_discard = std::min(len, readable);
if (to_discard == 0)
return 0;
_read_pos.store((read_pos + to_discard) % _capacity, std::memory_order_release);
return to_discard;
}
size_t RingBuffer::peek(void* data, const size_t len, const size_t offset) const {
if (!data || len == 0)
return 0;
const size_t read_pos = _read_pos.load(std::memory_order_relaxed);
const size_t write_pos = _write_pos.load(std::memory_order_acquire);
const size_t readable = (write_pos >= read_pos) ? (write_pos - read_pos) : (_capacity - read_pos + write_pos);
if (readable < offset + len) {
return 0; // 数据不够
}
// 计算实际读取位置(考虑offset)
const size_t peek_pos = (read_pos + offset) % _capacity;
// 计算第一段可读取的长度(到缓冲区末尾)
const size_t first_part = std::min(len, _capacity - peek_pos);
std::memcpy(data, _buffer.data() + peek_pos, first_part);
if (first_part < len) {
std::memcpy(static_cast<uint8_t*>(data) + first_part, _buffer.data(), len - first_part);
}
return len;
}
size_t RingBuffer::readable_size() const {
const size_t read_pos = _read_pos.load(std::memory_order_relaxed);
const size_t write_pos = _write_pos.load(std::memory_order_acquire);
return (write_pos >= read_pos) ? (write_pos - read_pos) : (_capacity - read_pos + write_pos);
}
size_t RingBuffer::writable_size() const {
const size_t read_pos = _read_pos.load(std::memory_order_acquire);
const size_t write_pos = _write_pos.load(std::memory_order_relaxed);
return (read_pos > write_pos) ? (read_pos - write_pos - 1) : (_capacity - write_pos + read_pos);
}
void RingBuffer::clear() {
_read_pos.store(0, std::memory_order_release);
_write_pos.store(0, std::memory_order_release);
}