瀏覽代碼

raft: make unstable.entries immutable; copy the entries at bad path

Xiang Li 11 年之前
父節點
當前提交
d214e87aee
共有 3 個文件被更改,包括 18 次插入14 次删除
  1. 1 2
      raft/log.go
  2. 15 10
      raft/log_unstable.go
  3. 2 2
      raft/storage.go

+ 1 - 2
raft/log.go

@@ -123,8 +123,7 @@ func (l *raftLog) unstableEntries() []pb.Entry {
 	if len(l.unstable.entries) == 0 {
 		return nil
 	}
-	// copy unstable entries to an empty slice
-	return append([]pb.Entry{}, l.unstable.entries...)
+	return l.unstable.entries
 }
 
 // nextEnts returns all the available entries for execution.

+ 15 - 10
raft/log_unstable.go

@@ -98,18 +98,23 @@ func (u *unstable) restore(s pb.Snapshot) {
 	u.snapshot = &s
 }
 
-func (u *unstable) resetEntries(offset uint64) {
-	u.entries = nil
-	u.offset = offset
-}
-
 func (u *unstable) truncateAndAppend(after uint64, ents []pb.Entry) {
-	if after < u.offset {
-		// The log is being truncated to before our current unstable
-		// portion, so discard it and reset unstable.
-		u.resetEntries(after + 1)
+	switch {
+	case after < u.offset:
+		// The log is being truncated to before our current offset
+		// portion, so set the offset and replace the entries
+		u.offset = after + 1
+		u.entries = ents
+	case after == u.offset+uint64(len(u.entries))-1:
+		// after is the last index in the u.entries
+		// directly append
+		u.entries = append(u.entries, ents...)
+	default:
+		// truncate to after and copy to u.entries
+		// then append
+		u.entries = append([]pb.Entry{}, u.slice(u.offset, after+1)...)
+		u.entries = append(u.entries, ents...)
 	}
-	u.entries = append(u.slice(u.offset, after+1), ents...)
 }
 
 func (u *unstable) slice(lo uint64, hi uint64) []pb.Entry {

+ 2 - 2
raft/storage.go

@@ -184,8 +184,8 @@ func (ms *MemoryStorage) Append(entries []pb.Entry) {
 	if offset < 0 {
 		return
 	}
-	if uint64(len(ms.ents)) >= offset {
-		ms.ents = ms.ents[:offset]
+	if uint64(len(ms.ents)) > offset {
+		ms.ents = append([]pb.Entry{}, ms.ents[:offset]...)
 	}
 	ms.ents = append(ms.ents, entries...)
 }