Browse Source

Merge pull request #1850 from yichengq/247

raft: return 0 for term of compacted index
Yicheng Qin 11 years ago
parent
commit
e344774c10
2 changed files with 35 additions and 3 deletions
  1. 3 1
      raft/log.go
  2. 32 2
      raft/log_test.go

+ 3 - 1
raft/log.go

@@ -199,7 +199,9 @@ func (l *raftLog) stableSnapTo(i uint64) { l.unstable.stableSnapTo(i) }
 func (l *raftLog) lastTerm() uint64 { return l.term(l.lastIndex()) }
 func (l *raftLog) lastTerm() uint64 { return l.term(l.lastIndex()) }
 
 
 func (l *raftLog) term(i uint64) uint64 {
 func (l *raftLog) term(i uint64) uint64 {
-	if i > l.lastIndex() {
+	// the valid term range is [index of dummy entry, last index]
+	dummyIndex := l.firstIndex() - 1
+	if i < dummyIndex || i > l.lastIndex() {
 		return 0
 		return 0
 	}
 	}
 
 

+ 32 - 2
raft/log_test.go

@@ -634,7 +634,7 @@ func TestTerm(t *testing.T) {
 	num := uint64(100)
 	num := uint64(100)
 
 
 	storage := NewMemoryStorage()
 	storage := NewMemoryStorage()
-	storage.ApplySnapshot(pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: offset}})
+	storage.ApplySnapshot(pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: offset, Term: 1}})
 	l := newLog(storage)
 	l := newLog(storage)
 	for i = 1; i < num; i++ {
 	for i = 1; i < num; i++ {
 		l.append(pb.Entry{Index: offset + i, Term: i})
 		l.append(pb.Entry{Index: offset + i, Term: i})
@@ -645,7 +645,7 @@ func TestTerm(t *testing.T) {
 		w     uint64
 		w     uint64
 	}{
 	}{
 		{offset - 1, 0},
 		{offset - 1, 0},
-		{offset, 0},
+		{offset, 1},
 		{offset + num/2, num / 2},
 		{offset + num/2, num / 2},
 		{offset + num - 1, num - 1},
 		{offset + num - 1, num - 1},
 		{offset + num, 0},
 		{offset + num, 0},
@@ -659,6 +659,36 @@ func TestTerm(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestTermWithUnstableSnapshot(t *testing.T) {
+	storagesnapi := uint64(100)
+	unstablesnapi := storagesnapi + 5
+
+	storage := NewMemoryStorage()
+	storage.ApplySnapshot(pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: storagesnapi, Term: 1}})
+	l := newLog(storage)
+	l.restore(pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: unstablesnapi, Term: 1}})
+
+	tests := []struct {
+		index uint64
+		w     uint64
+	}{
+		// cannot get term from storage
+		{storagesnapi, 0},
+		// cannot get term from the gap between storage ents and unstable snapshot
+		{storagesnapi + 1, 0},
+		{unstablesnapi - 1, 0},
+		// get term from unstable snapshot index
+		{unstablesnapi, 1},
+	}
+
+	for i, tt := range tests {
+		term := l.term(tt.index)
+		if !reflect.DeepEqual(term, tt.w) {
+			t.Errorf("#%d: at = %d, want %d", i, term, tt.w)
+		}
+	}
+}
+
 func TestSlice(t *testing.T) {
 func TestSlice(t *testing.T) {
 	var i uint64
 	var i uint64
 	offset := uint64(100)
 	offset := uint64(100)