فهرست منبع

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 سال پیش
والد
کامیت
d91ea7f199
2فایلهای تغییر یافته به همراه30 افزوده شده و 8 حذف شده
  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) {