Bladeren bron

raft: fix freeTo fails to free

If freeTo is called when to is set to the lastest inflight, freeTo
fails to free the slots.
Yicheng Qin 11 jaren geleden
bovenliggende
commit
d91ea7f199
2 gewijzigde bestanden met toevoegingen van 30 en 8 verwijderingen
  1. 16 8
      raft/progress.go
  2. 14 0
      raft/progress_test.go

+ 16 - 8
raft/progress.go

@@ -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]) }

+ 14 - 0
raft/progress_test.go

@@ -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) {