Browse Source

Merge pull request #2621 from yichengq/fix-inflight

raft: fix freeTo fails to free
Yicheng Qin 10 years ago
parent
commit
422cb7cb06
2 changed files with 30 additions and 8 deletions
  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.
 // freeTo frees the inflights smaller or equal to the given `to` flight.
 func (in *inflights) freeTo(to uint64) {
 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
 			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]) }
 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) {
 	if !reflect.DeepEqual(in, wantIn3) {
 		t.Fatalf("in = %+v, want %+v", 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) {
 func TestInflightFreeFirstOne(t *testing.T) {