authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-11 18:49:16-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-03-11 18:49:16-07:00
logda5b16f9e2b76534b1cab9093566693482084360
tree1cb23ffd7a396728a64033b44d10c7ee0b939b57
parentcb4e087fda07a3bec296d1e75da6416112fa2fd1
parent6fe2b4077896218083f778e926217f596a58a550
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19238 from dweiller/ring-buffer

std.RingBuffer: minor cleanup and doc improvements

1 files changed, 19 insertions(+), 14 deletions(-)

lib/std/RingBuffer.zig+19-14
......@@ -74,6 +74,7 @@ pub fn writeSlice(self: *RingBuffer, bytes: []const u8) Error!void {
7474/// bytes will be overwritten.
7575/// Uses memcpy and so `bytes` must not overlap ring buffer data.
7676pub fn writeSliceAssumeCapacity(self: *RingBuffer, bytes: []const u8) void {
77 assert(bytes.len <= self.data.len);
7778 const data_start = self.mask(self.write_index);
7879 const part1_data_end = @min(data_start + bytes.len, self.data.len);
7980 const part1_len = part1_data_end - data_start;
......@@ -104,6 +105,7 @@ pub fn writeSliceForwards(self: *RingBuffer, bytes: []const u8) Error!void {
104105/// bytes will be overwritten.
105106/// Uses copyForwards and can write slices from this RingBuffer into itself.
106107pub fn writeSliceForwardsAssumeCapacity(self: *RingBuffer, bytes: []const u8) void {
108 assert(bytes.len <= self.data.len);
107109 const data_start = self.mask(self.write_index);
108110 const part1_data_end = @min(data_start + bytes.len, self.data.len);
109111 const part1_len = part1_data_end - data_start;
......@@ -148,18 +150,15 @@ pub fn readFirst(self: *RingBuffer, dest: []u8, length: usize) Error!void {
148150/// Uses memcpy and so `dest` must not overlap ring buffer data.
149151pub fn readFirstAssumeLength(self: *RingBuffer, dest: []u8, length: usize) void {
150152 assert(length <= self.len() and length <= dest.len);
151 const data_start = self.mask(self.read_index);
152 const part1_data_end = @min(self.data.len, data_start + length);
153 const part1_len = part1_data_end - data_start;
154 const part2_len = length - part1_len;
155 @memcpy(dest[0..part1_len], self.data[data_start..part1_data_end]);
156 @memcpy(dest[part1_len..length], self.data[0..part2_len]);
153 const slice = self.sliceAt(self.read_index, length);
154 slice.copyTo(dest);
157155 self.read_index = self.mask2(self.read_index + length);
158156}
159157
160158/// Reads last `length` bytes written to the ring buffer into `dest`; Returns
161159/// Error.ReadLengthInvalid if length greater than ring or dest length
162160/// Uses memcpy and so `dest` must not overlap ring buffer data.
161/// Reduces write index by `length`.
163162pub fn readLast(self: *RingBuffer, dest: []u8, length: usize) Error!void {
164163 if (length > self.len() or length > dest.len) return error.ReadLengthInvalid;
165164 self.readLastAssumeLength(dest, length);
......@@ -168,15 +167,15 @@ pub fn readLast(self: *RingBuffer, dest: []u8, length: usize) Error!void {
168167/// Reads last `length` bytes written to the ring buffer into `dest`;
169168/// Asserts that length not greater than ring buffer or dest length
170169/// Uses memcpy and so `dest` must not overlap ring buffer data.
170/// Reduces write index by `length`.
171171pub fn readLastAssumeLength(self: *RingBuffer, dest: []u8, length: usize) void {
172172 assert(length <= self.len() and length <= dest.len);
173 const data_start = self.mask(self.write_index + self.data.len - length);
174 const part1_data_end = @min(self.data.len, data_start + length);
175 const part1_len = part1_data_end - data_start;
176 const part2_len = length - part1_len;
177 @memcpy(dest[0..part1_len], self.data[data_start..part1_data_end]);
178 @memcpy(dest[part1_len..length], self.data[0..part2_len]);
179 self.write_index = if (self.write_index >= self.data.len) self.write_index - length else data_start;
173 const slice = self.sliceLast(length);
174 slice.copyTo(dest);
175 self.write_index = if (self.write_index >= self.data.len)
176 self.write_index - length
177 else
178 self.mask(self.write_index + self.data.len - length);
180179}
181180
182181/// Returns `true` if the ring buffer is empty and `false` otherwise.
......@@ -189,7 +188,7 @@ pub fn isFull(self: RingBuffer) bool {
189188 return self.mask2(self.write_index + self.data.len) == self.read_index;
190189}
191190
192/// Returns the length
191/// Returns the length of data available for reading
193192pub fn len(self: RingBuffer) usize {
194193 const wrap_offset = 2 * self.data.len * @intFromBool(self.write_index < self.read_index);
195194 const adjusted_write_index = self.write_index + wrap_offset;
......@@ -202,6 +201,12 @@ pub fn len(self: RingBuffer) usize {
202201pub const Slice = struct {
203202 first: []u8,
204203 second: []u8,
204
205 /// Copy data from `self` into `dest`
206 pub fn copyTo(self: Slice, dest: []u8) void {
207 @memcpy(dest[0..self.first.len], self.first);
208 @memcpy(dest[self.first.len..][0..self.second.len], self.second);
209 }
205210};
206211
207212/// Returns a `Slice` for the region of the ring buffer starting at