Skip to content

Commit

Permalink
pw_ring_buffer: Add a decrement operator
Browse files Browse the repository at this point in the history
Bug: b/375653884
Change-Id: Ibe7db3526eba7a4a6a6cf5dca32464599027ccf1
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/244555
Presubmit-Verified: CQ Bot Account <[email protected]>
Commit-Queue: Dave Roth <[email protected]>
Lint: Lint 🤖 <[email protected]>
Docs-Not-Needed: Dave Roth <[email protected]>
Reviewed-by: Wyatt Hepler <[email protected]>
  • Loading branch information
davexroth authored and CQ Bot Account committed Oct 29, 2024
1 parent 9e54847 commit b901805
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
29 changes: 29 additions & 0 deletions pw_ring_buffer/prefixed_entry_ring_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,35 @@ iterator& iterator::operator++() {
return *this;
}

iterator& iterator::operator--() {
PW_DCHECK_OK(iteration_status_);
PW_DCHECK_INT_NE(entry_count_, 0);

Result<EntryInfo> info = ring_buffer_->RawFrontEntryInfo(read_idx_);
if (!info.status().ok()) {
SkipToEnd(info.status());
return *this;
}

// It is guaranteed that the buffer is deringed at this point.
read_idx_ -= info.value().preamble_bytes + info.value().data_bytes;
entry_count_++;

// If read_idx_ is larger that the total bytes, it's wrapped
// as the iterator has decremented past the last element.
if (read_idx_ > ring_buffer_->TotalSizeBytes()) {
SkipToEnd(Status::DataLoss());
return *this;
}

info = ring_buffer_->RawFrontEntryInfo(read_idx_);
if (!info.status().ok()) {
SkipToEnd(info.status());
return *this;
}
return *this;
}

const Entry& iterator::operator*() const {
PW_DCHECK_OK(iteration_status_);
PW_DCHECK_INT_NE(entry_count_, 0);
Expand Down
34 changes: 34 additions & 0 deletions pw_ring_buffer/prefixed_entry_ring_buffer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,40 @@ TEST(PrefixedEntryRingBuffer, Iterator) {
EXPECT_EQ(validated_entries, entry_count);
}

TEST(PrefixedEntryRingBuffer, IteratorDecrement) {
PrefixedEntryRingBuffer ring;
byte test_buffer[kTestBufferSize];
EXPECT_EQ(ring.SetBuffer(test_buffer), OkStatus());

// Fill up the ring buffer with a constant value.
size_t entry_count = 0;
while (TryPushBack<size_t>(ring, entry_count).ok()) {
entry_count++;
}

// Move the iterator to the last element.
iterator begin_it = ring.begin();
iterator it = ring.begin();
for (size_t i = 0; i < entry_count - 1; ++i) {
it++;
}

// Decrement iterator to the beginning, checking each value
size_t validated_entries = entry_count - 1;
do {
EXPECT_TRUE(it.status().ok());
EXPECT_EQ(GetEntry<size_t>(it->buffer), validated_entries);
it--;
validated_entries--;
} while (it != begin_it);

EXPECT_EQ(validated_entries, static_cast<size_t>(0));

--it;
EXPECT_EQ(ring.end(), it);
EXPECT_EQ(Status::DataLoss(), it.status());
}

TEST(PrefixedEntryRingBuffer, EntriesSizeWhenBufferFull) {
PrefixedEntryRingBuffer ring;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,13 @@ class PrefixedEntryRingBufferMulti {
return original;
}

iterator& operator--();
iterator operator--(int) {
iterator original = *this;
--*this;
return original;
}

// Returns entry at current position.
const Entry& operator*() const;
const Entry* operator->() const { return &operator*(); }
Expand Down

0 comments on commit b901805

Please sign in to comment.