Kaynağa Gözat

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 yıl önce
ebeveyn
işleme
d91ea7f199
2 değiştirilmiş dosya ile 30 ekleme ve 8 silme
  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) {