Selaa lähdekoodia

raft/tracker: visit Progress in stable order

This is helpful for upcoming testing work which allows datadriven
testing of the interaction of multiple nodes. This testing requires
determinism to work correctly.
Tobias Schottdorf 6 vuotta sitten
vanhempi
commit
1b3e0821a7
2 muutettua tiedostoa jossa 32 lisäystä ja 7 poistoa
  1. 4 4
      raft/quorum/majority.go
  2. 28 3
      raft/tracker/tracker.go

+ 4 - 4
raft/quorum/majority.go

@@ -139,12 +139,12 @@ func (c MajorityConfig) CommittedIndex(l AckedIndexer) Index {
 	// performance is a lesser concern (additionally the performance
 	// performance is a lesser concern (additionally the performance
 	// implications of an allocation here are far from drastic).
 	// implications of an allocation here are far from drastic).
 	var stk [7]uint64
 	var stk [7]uint64
-	srt := []uint64(stk[:])
-
-	if cap(srt) < n {
+	var srt []uint64
+	if len(stk) >= n {
+		srt = stk[:n]
+	} else {
 		srt = make([]uint64, n)
 		srt = make([]uint64, n)
 	}
 	}
-	srt = srt[:n]
 
 
 	{
 	{
 		// Fill the slice with the indexes observed. Any unused slots will be
 		// Fill the slice with the indexes observed. Any unused slots will be

+ 28 - 3
raft/tracker/tracker.go

@@ -166,10 +166,35 @@ func (p *ProgressTracker) Committed() uint64 {
 	return uint64(p.Voters.CommittedIndex(matchAckIndexer(p.Progress)))
 	return uint64(p.Voters.CommittedIndex(matchAckIndexer(p.Progress)))
 }
 }
 
 
-// Visit invokes the supplied closure for all tracked progresses.
+func insertionSort(sl []uint64) {
+	a, b := 0, len(sl)
+	for i := a + 1; i < b; i++ {
+		for j := i; j > a && sl[j] < sl[j-1]; j-- {
+			sl[j], sl[j-1] = sl[j-1], sl[j]
+		}
+	}
+}
+
+// Visit invokes the supplied closure for all tracked progresses in stable order.
 func (p *ProgressTracker) Visit(f func(id uint64, pr *Progress)) {
 func (p *ProgressTracker) Visit(f func(id uint64, pr *Progress)) {
-	for id, pr := range p.Progress {
-		f(id, pr)
+	n := len(p.Progress)
+	// We need to sort the IDs and don't want to allocate since this is hot code.
+	// The optimization here mirrors that in `(MajorityConfig).CommittedIndex`,
+	// see there for details.
+	var sl [7]uint64
+	ids := sl[:]
+	if len(sl) >= n {
+		ids = sl[:n]
+	} else {
+		ids = make([]uint64, n)
+	}
+	for id := range p.Progress {
+		n--
+		ids[n] = id
+	}
+	insertionSort(ids)
+	for _, id := range ids {
+		f(id, p.Progress[id])
 	}
 	}
 }
 }