raft: fix freeTo fails to free
@@ -202,17 +202,25 @@ func (in *inflights) add(inflight uint64) {
// freeTo frees the inflights smaller or equal to the given `to` flight.
func (in *inflights) freeTo(to uint64) {
- for i := in.start; i < in.start+in.count; i++ {
- idx := i
- if i >= in.size {
- idx -= in.size
- }
- if to < in.buffer[idx] {
- in.count -= i - in.start
- in.start = idx
+ if in.count == 0 || to < in.buffer[in.start] {
+ // out of the left side of the window
+ return
+ }
+
+ i, idx := 0, in.start
+ for i = 0; i < in.count; i++ {
+ if to < in.buffer[idx] { // found the first large inflight
break
}
+ // increase index and maybe rotate
+ if idx += 1; idx >= in.size {
+ idx -= in.size
+ // free i inflights and set new start index
+ in.count -= i
+ in.start = idx
func (in *inflights) freeFirstOne() { in.freeTo(in.buffer[in.start]) }
@@ -151,6 +151,20 @@ func TestInflightFreeTo(t *testing.T) {
if !reflect.DeepEqual(in, wantIn3) {
t.Fatalf("in = %+v, want %+v", in, wantIn3)
+ in.freeTo(14)
+ wantIn4 := &inflights{
+ start: 5,
+ count: 0,
+ size: 10,
+ // ↓
+ buffer: []uint64{10, 11, 12, 13, 14, 5, 6, 7, 8, 9},
+ if !reflect.DeepEqual(in, wantIn4) {
+ t.Fatalf("in = %+v, want %+v", in, wantIn4)
func TestInflightFreeFirstOne(t *testing.T) {