ronantakizawa/codereview-bench huggingface dataset:
Repository: etcd-io/etcd
File: cache/ringbuffer.go (Go)

Code before:

package cache

type ringBuffer[T any] struct {
	buffer []entry[T]
	// head is the index immediately after the last non-empty entry in the buffer (i.e., the next write position).
	head, tail, entryCount int
}

type entry[T any] struct {
	revision int64
	items    []T
}

type KeyPredicate = func([]byte) bool

func newRingBuffer[T any](capacity int) *ringBuffer[T] {
	// assume capacity > 0 – validated by Cache
	return &ringBuffer[T]{
		buffer: make([]entry[T], capacity),
	}
}

type RevisionOf[T any] func(T) int64

func (r *ringBuffer[T]) Append(items []T, revOf RevisionOf[T]) {
	start := 0
	for end := 1; end < len(items); end++ {
		if revOf(items[end]) != revOf(items[start]) {
			r.append(entry[T]{
				revision: revOf(items[start]),
				items:    items[start:end],
			})
			start = end
		}
	}
	if start < len(items) {
		r.append(entry[T]{
			revision: revOf(items[start]),
			items:    items[start:],
		})
	}
}

func (r *ringBuffer[T]) append(entry entry[T]) {
	if len(entry.items) == 0 {
		return
	}
	if r.entryCount == len(r.buffer) {
		r.tail = (r.tail + 1) % len(r.buffer)
	} else {

Review comment (suggestion):
This function `revOf RevisionOf[T]` should be part of ringBuffer configuration during construction instead of passed on every `Append` call

Code after:

package cache

import "fmt"

type ringBuffer[T any] struct {
	buffer []entry[T]
	// head is the index immediately after the last non-empty entry in the buffer (i.e., the next write position).
	head, tail, size int
	revisionOf       RevisionOf[T]
}

type entry[T any] struct {
	revision int64
	items    []T
}

type (
	KeyPredicate      = func([]byte) bool
	RevisionOf[T any] func(T) int64
	IterFunc[T any]   func(rev int64, items []T) bool
)

func newRingBuffer[T any](capacity int, revisionOf RevisionOf[T]) *ringBuffer[T] {
	// assume capacity > 0 – validated by Cache
	return &ringBuffer[T]{
		buffer:     make([]entry[T], capacity),
		revisionOf: revisionOf,
	}
}

func (r *ringBuffer[T]) Append(items []T) {
	start := 0
	for end := 1; end < len(items); end++ {
		if r.revisionOf(items[end]) != r.revisionOf(items[start]) {
			r.append(entry[T]{
				revision: r.revisionOf(items[start]),
				items:    items[start:end],
			})
			start = end
		}
	}
	if start < len(items) {
		r.append(entry[T]{
			revision: r.revisionOf(items[start]),
			items:    items[start:],
		})
	}
}

func (r *ringBuffer[T]) append(entry entry[T]) {
Repository: etcd-io/etcd
File: cache/ringbuffer.go (Go)

Code before:
			start = end
		}
	}
	if start < len(items) {
		r.append(entry[T]{
			revision: revOf(items[start]),
			items:    items[start:],
		})
	}
}

func (r *ringBuffer[T]) append(entry entry[T]) {
	if len(entry.items) == 0 {
		return
	}
	if r.entryCount == len(r.buffer) {
		r.tail = (r.tail + 1) % len(r.buffer)
	} else {
		r.entryCount++
	}
	r.buffer[r.head] = entry
	r.head = (r.head + 1) % len(r.buffer)
}

// GetFromRev returns all entries with revision >= minRev
func (r *ringBuffer[T]) GetFromRevision(minRev int64) [][]T {
	if r.entryCount == 0 {
		return nil
	}
	firstMatchIdx := r.findFirstRevisionIndex(minRev)
	if firstMatchIdx == r.entryCount {
		return nil
	}
	result := make([][]T, 0, r.entryCount-firstMatchIdx)
	for logicalIdx := firstMatchIdx; logicalIdx < r.entryCount; logicalIdx++ {
		physicalIdx := r.logicalToPhysicalIndex(logicalIdx)
		result = append(result, r.buffer[physicalIdx].items)
	}
	return result
}

// FindAtOrBefore finds the entry with the highest revision that is <= targetRev
func (r *ringBuffer[T]) FindAtOrBefore(targetRev int64) (entry[T], bool) {
	if r.entryCount == 0 {
		var emptyEntry entry[T]
		return emptyEntry, false
	}
	afterTargetIdx := r.findAfterRevisionIndex(targetRev)
	if afterTargetIdx == 0 {
		var emptyEntry entry[T]
		return emptyEntry, false

Review comment (performance):
To make ringBuffer interface cleaner, maybe we could flatten `[][]T` to `[]T` and expect caller to handle batching. We can do that in followup to avoid complicating this PR.

Code after:
	for end := 1; end < len(items); end++ {
		if r.revisionOf(items[end]) != r.revisionOf(items[start]) {
			r.append(entry[T]{
				revision: r.revisionOf(items[start]),
				items:    items[start:end],
			})
			start = end
		}
	}
	if start < len(items) {
		r.append(entry[T]{
			revision: r.revisionOf(items[start]),
			items:    items[start:],
		})
	}
}

func (r *ringBuffer[T]) append(entry entry[T]) {
	if len(entry.items) == 0 {
		return
	}
	if r.size == len(r.buffer) {
		r.tail = (r.tail + 1) % len(r.buffer)
	} else {
		r.size++
	}
	r.buffer[r.head] = entry
	r.head = (r.head + 1) % len(r.buffer)
}

// AscendGreaterOrEqual iterates through entries in ascending order starting from the first entry with revision >= pivot.
// TODO: use binary search on the ring buffer to locate the first entry >= nextRev instead of a full scan
func (r *ringBuffer[T]) AscendGreaterOrEqual(pivot int64, iter IterFunc[T]) {
	if r.size == 0 {
		return
	}

	for n, i := 0, r.tail; n < r.size; n, i = n+1, (i+1)%len(r.buffer) {
		entry := r.buffer[i]

		if entry.items == nil {
			panic(fmt.Sprintf("ringBuffer.AscendGreaterOrEqual: unexpected nil at %d", i))
		}

		if entry.revision < pivot {
			continue
		}

		if !iter(entry.revision, entry.items) {
			return
		}
Repository: etcd-io/etcd
File: cache/ringbuffer.go (Go)

Code before:
	} else {
		r.entryCount++
	}
	r.buffer[r.head] = entry
	r.head = (r.head + 1) % len(r.buffer)
}

// GetFromRev returns all entries with revision >= minRev
func (r *ringBuffer[T]) GetFromRevision(minRev int64) [][]T {
	if r.entryCount == 0 {
		return nil
	}
	firstMatchIdx := r.findFirstRevisionIndex(minRev)
	if firstMatchIdx == r.entryCount {
		return nil
	}
	result := make([][]T, 0, r.entryCount-firstMatchIdx)
	for logicalIdx := firstMatchIdx; logicalIdx < r.entryCount; logicalIdx++ {
		physicalIdx := r.logicalToPhysicalIndex(logicalIdx)
		result = append(result, r.buffer[physicalIdx].items)
	}
	return result
}

// FindAtOrBefore finds the entry with the highest revision that is <= targetRev
func (r *ringBuffer[T]) FindAtOrBefore(targetRev int64) (entry[T], bool) {
	if r.entryCount == 0 {
		var emptyEntry entry[T]
		return emptyEntry, false
	}
	afterTargetIdx := r.findAfterRevisionIndex(targetRev)
	if afterTargetIdx == 0 {
		var emptyEntry entry[T]
		return emptyEntry, false
	}
	physicalIdx := r.logicalToPhysicalIndex(afterTargetIdx - 1)
	return r.buffer[physicalIdx], true
}

// FindAtOrAfter finds the first entry with revision >= targetRev"
func (r *ringBuffer[T]) FindAtOrAfter(targetRev int64) (entry[T], bool) {
	if r.entryCount == 0 {
		var empty entry[T]
		return empty, false
	}

	idx := r.findFirstRevisionIndex(targetRev)
	if idx == r.entryCount {
		var empty entry[T]
		return empty, false
	}

Review comment (suggestion):
If we changed interface to iterators like in btree we could implement `DescendLessOrEqual` method and allow client to stop iteration after first result.

https://github.com/google/btree/blob/aeba20f7a1e1315badec4eca4fdc9f754f5f880a/btree_generic.go#L1040

Code after:
func (r *ringBuffer[T]) append(entry entry[T]) {
	if len(entry.items) == 0 {
		return
	}
	if r.size == len(r.buffer) {
		r.tail = (r.tail + 1) % len(r.buffer)
	} else {
		r.size++
	}
	r.buffer[r.head] = entry
	r.head = (r.head + 1) % len(r.buffer)
}

// AscendGreaterOrEqual iterates through entries in ascending order starting from the first entry with revision >= pivot.
// TODO: use binary search on the ring buffer to locate the first entry >= nextRev instead of a full scan
func (r *ringBuffer[T]) AscendGreaterOrEqual(pivot int64, iter IterFunc[T]) {
	if r.size == 0 {
		return
	}

	for n, i := 0, r.tail; n < r.size; n, i = n+1, (i+1)%len(r.buffer) {
		entry := r.buffer[i]

		if entry.items == nil {
			panic(fmt.Sprintf("ringBuffer.AscendGreaterOrEqual: unexpected nil at %d", i))
		}

		if entry.revision < pivot {
			continue
		}

		if !iter(entry.revision, entry.items) {
			return
		}
	}
}

// AscendLessThan iterates in ascending order over entries with revision < pivot.
func (r *ringBuffer[T]) AscendLessThan(pivot int64, iter IterFunc[T]) {
	if r.size == 0 {
		return
	}

	for n, i := 0, r.tail; n < r.size; n, i = n+1, (i+1)%len(r.buffer) {
		entry := r.buffer[i]

		if entry.items == nil {
			panic(fmt.Sprintf("ringBuffer.AscendLessThan: unexpected nil at %d", i))
		}

		if entry.revision >= pivot {
Repository: etcd-io/etcd
File: cache/ringbuffer.go (Go)

Code before:
			events: events[start:],
		})
	}
}

func (r *ringBuffer) append(b batch) {
	if len(b.events) == 0 {
		return
	}
	if r.size == len(r.buffer) {
		r.tail = (r.tail + 1) % len(r.buffer)
	} else {
		r.size++
	}
	r.buffer[r.head] = b
	r.head = (r.head + 1) % len(r.buffer)
}

// AscendGreaterOrEqual iterates through batches in ascending order starting from the first batch with rev >= pivot.
// TODO: use binary search on the ring buffer to locate the first entry >= nextRev instead of a full scan
func (r *ringBuffer) AscendGreaterOrEqual(pivot int64, iter IterFunc) {
	if r.size == 0 {
		return
	}

	for logicalIdx := 0; logicalIdx < r.size; logicalIdx++ {
		physicalIdx := r.logicalToPhysicalIndex(logicalIdx)
		eventBatch := r.buffer[physicalIdx]

		if eventBatch.events == nil {
			panic(fmt.Sprintf("ringBuffer.AscendGreaterOrEqual: unexpected nil at %d", physicalIdx))
		}

		if eventBatch.rev < pivot {
			continue
		}

		if !iter(eventBatch.rev, eventBatch.events) {
			return
		}
	}
}

func (r *ringBuffer) AscendLessThan(pivot int64, iter IterFunc) {
	if r.size == 0 {
		return
	}

	for logicalIdx := 0; logicalIdx < r.size; logicalIdx++ {
		physicalIdx := r.logicalToPhysicalIndex(logicalIdx)
		eventBatch := r.buffer[physicalIdx]

Review comment (bug):
What's wrong with `for n, i := 0, r.tail; n < r.size; n, i = n+1, (i+1)%len(r.buffer) {`. For me it's more readable to just work on physical index.

Code after:
			events: events[start:],
		})
	}
}

func (r *ringBuffer) append(b batch) {
	if len(b.events) == 0 {
		return
	}
	if r.size == len(r.buffer) {
		r.tail = (r.tail + 1) % len(r.buffer)
	} else {
		r.size++
	}
	r.buffer[r.head] = b
	r.head = (r.head + 1) % len(r.buffer)
}

// AscendGreaterOrEqual iterates through batches in ascending order starting from the first batch with rev >= pivot.
// TODO: use binary search on the ring buffer to locate the first entry >= nextRev instead of a full scan
func (r *ringBuffer) AscendGreaterOrEqual(pivot int64, iter IterFunc) {
	if r.size == 0 {
		return
	}

	for n, i := 0, r.tail; n < r.size; n, i = n+1, (i+1)%len(r.buffer) {
		eventBatch := r.buffer[i]

		if eventBatch.events == nil {
			panic(fmt.Sprintf("ringBuffer.AscendGreaterOrEqual: unexpected nil at %d", i))
		}

		if eventBatch.rev < pivot {
			continue
		}

		if !iter(eventBatch.rev, eventBatch.events) {
			return
		}
	}
}

func (r *ringBuffer) AscendLessThan(pivot int64, iter IterFunc) {
	if r.size == 0 {
		return
	}

	for n, i := 0, r.tail; n < r.size; n, i = n+1, (i+1)%len(r.buffer) {
		eventBatch := r.buffer[i]

		if eventBatch.events == nil {
Repository: etcd-io/etcd
File: cache/ringbuffer_test.go (Go)

Code before:
		},
		{
			name:     "basic_filtering",
			capacity: 5,
			revs:     []int64{1, 2, 3},
			cases: []struct {
				method iterMethod
				pivot  int64
				want   []int64
			}{
				{ascendGTE, 0, []int64{1, 2, 3}},
				{ascendGTE, 2, []int64{2, 3}},
				{ascendGTE, 100, []int64{}},
				{ascendLT, 3, []int64{1, 2}},
				{ascendLT, 1, []int64{}},
				{ascendLT, 100, []int64{1, 2, 3}},
				{descendGT, 1, []int64{3, 2}},
				{descendGT, 3, []int64{}},
				{descendGT, 0, []int64{3, 2, 1}},
				{descendLTE, 2, []int64{2, 1}},
				{descendLTE, 3, []int64{3, 2, 1}},
				{descendLTE, 0, []int64{}},
			},
		},
		{
			name:     "wrapped_buffer",
			capacity: 3,
			revs:     []int64{20, 21, 22, 23, 24}, // stored: 22, 23, 24
			cases: []struct {
				method iterMethod
				pivot  int64
				want   []int64
			}{
				{ascendGTE, 23, []int64{23, 24}},
				{ascendGTE, 0, []int64{22, 23, 24}},
				{ascendLT, 23, []int64{22}},
				{ascendLT, 25, []int64{22, 23, 24}},
				{descendGT, 22, []int64{24, 23}},
				{descendGT, 25, []int64{}},
				{descendLTE, 23, []int64{23, 22}},
				{descendLTE, 24, []int64{24, 23, 22}},
			},
		},
	}

	for _, tt := range tests {
		tt := tt
		t.Run(tt.name, func(t *testing.T) {
			rb := setupRingBuffer(t, tt.capacity, tt.revs)

			for _, tc := range tt.cases {

Review comment (bug):
```suggestion
			name:     "overflowed stores only entries within capacity",
```

Code after:
			capacity:       5,
			setupRevisions: []int64{1, 2, 3},
			cases: []iterTestCase{
				{ascendGTE, 0, []int64{1, 2, 3}},
				{ascendGTE, 2, []int64{2, 3}},
				{ascendGTE, 100, []int64{}},
				{ascendLT, 3, []int64{1, 2}},
				{ascendLT, 1, []int64{}},
				{ascendLT, 100, []int64{1, 2, 3}},
				{descendGT, 1, []int64{3, 2}},
				{descendGT, 3, []int64{}},
				{descendGT, 0, []int64{3, 2, 1}},
				{descendLTE, 2, []int64{2, 1}},
				{descendLTE, 3, []int64{3, 2, 1}},
				{descendLTE, 0, []int64{}},
			},
		},
		{
			name:           "overflowed stores only entries within capacity",
			capacity:       3,
			setupRevisions: []int64{20, 21, 22, 23, 24}, // stored: 22, 23, 24
			cases: []iterTestCase{
				{ascendGTE, 23, []int64{23, 24}},
				{ascendGTE, 0, []int64{22, 23, 24}},
				{ascendLT, 23, []int64{22}},
				{ascendLT, 25, []int64{22, 23, 24}},
				{descendGT, 22, []int64{24, 23}},
				{descendGT, 25, []int64{}},
				{descendLTE, 23, []int64{23, 22}},
				{descendLTE, 24, []int64{24, 23, 22}},
			},
		},
	}

	for _, tt := range tests {
		tt := tt
		t.Run(tt.name, func(t *testing.T) {
			rb := setupRingBuffer(t, tt.capacity, tt.setupRevisions)

			for _, tc := range tt.cases {
				tc := tc
				t.Run(fmt.Sprintf("%s_pivot_%d", tc.method, tc.pivot), func(t *testing.T) {
					got := collectRevisions(rb, tc.method, tc.pivot)
					if diff := cmp.Diff(tc.wantIterRevisions, got); diff != "" {
						t.Fatalf("%s(%d) mismatch (-want +got):\n%s", tc.method, tc.pivot, diff)
					}
				})
			}
		})
	}
}
Repository: etcd-io/etcd
File: cache/ringbuffer_test.go (Go)

Code before:

			latestRev := rb.PeekLatest()
			oldestRev := rb.PeekOldest()

			gotLatestRev := latestRev
			gotOldestRev := oldestRev

			if tt.wantLatestRev != gotLatestRev {
				t.Fatalf("PeekLatest()=%d, want=%d", gotLatestRev, tt.wantLatestRev)
			}
			if tt.wantOldestRev != gotOldestRev {
				t.Fatalf("PeekOldest()=%d, want=%d", gotOldestRev, tt.wantOldestRev)
			}
		})
	}
}

func TestIterationMethods(t *testing.T) {
	tests := []struct {
		name     string
		capacity int
		revs     []int64
		cases    []struct {
			method iterMethod
			pivot  int64
			want   []int64
		}
	}{
		{
			name:     "empty_buffer",
			capacity: 4,
			revs:     nil,
			cases: []struct {
				method iterMethod
				pivot  int64
				want   []int64
			}{
				{ascendGTE, 0, []int64{}},
				{ascendLT, 10, []int64{}},
				{descendGT, 0, []int64{}},
				{descendLTE, 10, []int64{}},
			},
		},
		{
			name:     "basic_filtering",
			capacity: 5,
			revs:     []int64{1, 2, 3},
			cases: []struct {
				method iterMethod
				pivot  int64
				want   []int64

Review comment (suggestion):
```suggestion
			wantIterRevisions   []int64
```

Code after:

			latestRev := rb.PeekLatest()
			oldestRev := rb.PeekOldest()

			gotLatestRev := latestRev
			gotOldestRev := oldestRev

			if tt.wantLatestRev != gotLatestRev {
				t.Fatalf("PeekLatest()=%d, want=%d", gotLatestRev, tt.wantLatestRev)
			}
			if tt.wantOldestRev != gotOldestRev {
				t.Fatalf("PeekOldest()=%d, want=%d", gotOldestRev, tt.wantOldestRev)
			}
		})
	}
}

func TestIterationMethods(t *testing.T) {
	type iterTestCase struct {
		method            iterMethod
		pivot             int64
		wantIterRevisions []int64
	}
	tests := []struct {
		name           string
		capacity       int
		setupRevisions []int64
		cases          []iterTestCase
	}{
		{
			name:           "empty_buffer",
			capacity:       4,
			setupRevisions: nil,
			cases: []iterTestCase{
				{ascendGTE, 0, []int64{}},
				{ascendLT, 10, []int64{}},
				{descendGT, 0, []int64{}},
				{descendLTE, 10, []int64{}},
			},
		},
		{
			name:           "basic_filtering",
			capacity:       5,
			setupRevisions: []int64{1, 2, 3},
			cases: []iterTestCase{
				{ascendGTE, 0, []int64{1, 2, 3}},
				{ascendGTE, 2, []int64{2, 3}},
				{ascendGTE, 100, []int64{}},
				{ascendLT, 3, []int64{1, 2}},
				{ascendLT, 1, []int64{}},
				{ascendLT, 100, []int64{1, 2, 3}},
Repository: etcd-io/etcd
File: cache/ringbuffer_test.go (Go)

Code before:
				rb.Append(batch)
			}

			latestRev := rb.PeekLatest()
			oldestRev := rb.PeekOldest()

			gotLatestRev := latestRev
			gotOldestRev := oldestRev

			if tt.wantLatestRev != gotLatestRev {
				t.Fatalf("PeekLatest()=%d, want=%d", gotLatestRev, tt.wantLatestRev)
			}
			if tt.wantOldestRev != gotOldestRev {
				t.Fatalf("PeekOldest()=%d, want=%d", gotOldestRev, tt.wantOldestRev)
			}
		})
	}
}

func TestIterationMethods(t *testing.T) {
	tests := []struct {
		name     string
		capacity int
		revs     []int64
		cases    []struct {
			method iterMethod
			pivot  int64
			want   []int64
		}
	}{
		{
			name:     "empty_buffer",
			capacity: 4,
			revs:     nil,
			cases: []struct {
				method iterMethod
				pivot  int64
				want   []int64
			}{
				{ascendGTE, 0, []int64{}},
				{ascendLT, 10, []int64{}},
				{descendGT, 0, []int64{}},
				{descendLTE, 10, []int64{}},
			},
		},
		{
			name:     "basic_filtering",
			capacity: 5,
			revs:     []int64{1, 2, 3},
			cases: []struct {
				method iterMethod

Review comment (suggestion):
```suggestion
func TestIterationMethods(t *testing.T) {
	type iterTestCase struct {
		method iterMethod
		pivot  int64
		wantRevisions   []int64
	}
	tests := []struct {
```
Don't repeat definition of anonymous struct, it reduces readability adding needless code code.

Code after:
				rb.Append(batch)
			}

			latestRev := rb.PeekLatest()
			oldestRev := rb.PeekOldest()

			gotLatestRev := latestRev
			gotOldestRev := oldestRev

			if tt.wantLatestRev != gotLatestRev {
				t.Fatalf("PeekLatest()=%d, want=%d", gotLatestRev, tt.wantLatestRev)
			}
			if tt.wantOldestRev != gotOldestRev {
				t.Fatalf("PeekOldest()=%d, want=%d", gotOldestRev, tt.wantOldestRev)
			}
		})
	}
}

func TestIterationMethods(t *testing.T) {
	type iterTestCase struct {
		method            iterMethod
		pivot             int64
		wantIterRevisions []int64
	}
	tests := []struct {
		name           string
		capacity       int
		setupRevisions []int64
		cases          []iterTestCase
	}{
		{
			name:           "empty_buffer",
			capacity:       4,
			setupRevisions: nil,
			cases: []iterTestCase{
				{ascendGTE, 0, []int64{}},
				{ascendLT, 10, []int64{}},
				{descendGT, 0, []int64{}},
				{descendLTE, 10, []int64{}},
			},
		},
		{
			name:           "basic_filtering",
			capacity:       5,
			setupRevisions: []int64{1, 2, 3},
			cases: []iterTestCase{
				{ascendGTE, 0, []int64{1, 2, 3}},
				{ascendGTE, 2, []int64{2, 3}},
				{ascendGTE, 100, []int64{}},
				{ascendLT, 3, []int64{1, 2}},
Repository: etcd-io/etcd
File: cache/ringbuffer_test.go (Go)

Code before:
					}
				})
			}
		})
	}
}

func TestIterationWithBatching(t *testing.T) {
	rb := newRingBuffer(6)
	events := []*clientv3.Event{
		{Kv: &mvccpb.KeyValue{Key: []byte("key-a"), ModRevision: 5}},
		{Kv: &mvccpb.KeyValue{Key: []byte("key-b-1"), ModRevision: 10}},
		{Kv: &mvccpb.KeyValue{Key: []byte("key-b-2"), ModRevision: 10}},
		{Kv: &mvccpb.KeyValue{Key: []byte("key-b-3"), ModRevision: 10}},
		{Kv: &mvccpb.KeyValue{Key: []byte("key-c"), ModRevision: 12}},
	}

	rb.Append(events)

	tests := []struct {
		name      string
		method    iterMethod
		pivot     int64
		want      []int64
		wantSizes []int
		expected  string
	}{
		{
			name:      "ascending_gte_includes_batched_revision",
			method:    ascendGTE,
			pivot:     10,
			want:      []int64{10, 12},
			wantSizes: []int{3, 1},
			expected:  "Should include rev 10 (with 3 batched events) and rev 12",
		},
		{
			name:      "ascending_lt_stops_before_batched_revision",
			method:    ascendLT,
			pivot:     10,
			want:      []int64{5},
			wantSizes: []int{1},
			expected:  "Should only include rev 5, stopping before the batched rev 10",
		},
		{
			name:      "all_revisions_with_proper_batch_sizes",
			method:    ascendGTE,
			pivot:     0,
			want:      []int64{5, 10, 12},
			wantSizes: []int{1, 3, 1},
			expected:  "Should include all revisions with correct event counts per batch",
		},

Review comment (suggestion):
```suggestion
```

Not needed, what is expected should be reflected in naming of the test case fields

Code after:
		{Kv: &mvccpb.KeyValue{Key: []byte("key-b-1"), ModRevision: 10}},
		{Kv: &mvccpb.KeyValue{Key: []byte("key-b-2"), ModRevision: 10}},
		{Kv: &mvccpb.KeyValue{Key: []byte("key-b-3"), ModRevision: 10}},
		{Kv: &mvccpb.KeyValue{Key: []byte("key-c"), ModRevision: 12}},
	}

	rb.Append(events)

	tests := []struct {
		name   string
		method iterMethod
		pivot  int64
		want   [][]*clientv3.Event
	}{
		{
			name:   "ascending_gte_includes_batched_revision",
			method: ascendGTE,
			pivot:  10,
			want: [][]*clientv3.Event{
				{
					{Kv: &mvccpb.KeyValue{Key: []byte("key-b-1"), ModRevision: 10}},
					{Kv: &mvccpb.KeyValue{Key: []byte("key-b-2"), ModRevision: 10}},
					{Kv: &mvccpb.KeyValue{Key: []byte("key-b-3"), ModRevision: 10}},
				},
				{
					{Kv: &mvccpb.KeyValue{Key: []byte("key-c"), ModRevision: 12}},
				},
			},
		},
		{
			name:   "ascending_lt_stops_before_batched_revision",
			method: ascendLT,
			pivot:  10,
			want: [][]*clientv3.Event{
				{
					{Kv: &mvccpb.KeyValue{Key: []byte("key-a"), ModRevision: 5}},
				},
			},
		},
		{
			name:   "all_revisions_with_proper_batch_sizes",
			method: ascendGTE,
			pivot:  0,
			want: [][]*clientv3.Event{
				{
					{Kv: &mvccpb.KeyValue{Key: []byte("key-a"), ModRevision: 5}},
				},
				{
					{Kv: &mvccpb.KeyValue{Key: []byte("key-b-1"), ModRevision: 10}},
					{Kv: &mvccpb.KeyValue{Key: []byte("key-b-2"), ModRevision: 10}},
					{Kv: &mvccpb.KeyValue{Key: []byte("key-b-3"), ModRevision: 10}},