Return successorModTime in quorum when available (#17925)

This commit is contained in:
Krishnan Parthasarathi 2023-09-04 08:24:17 -07:00 committed by GitHub
parent 380a59520b
commit 71c32e9b48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 10 deletions

View File

@ -382,14 +382,39 @@ func findFileInfoInQuorum(ctx context.Context, metaArr []FileInfo, modTime time.
return FileInfo{}, errErasureReadQuorum return FileInfo{}, errErasureReadQuorum
} }
// Find the successor mod time in quorum, otherwise leave the
// candidate's successor modTime as found
succModTimeMap := make(map[time.Time]int)
var candidate FileInfo
var found bool
for i, hash := range metaHashes { for i, hash := range metaHashes {
if hash == maxHash { if hash == maxHash {
if metaArr[i].IsValid() { if metaArr[i].IsValid() {
return metaArr[i], nil if !found {
candidate = metaArr[i]
found = true
} }
succModTimeMap[metaArr[i].SuccessorModTime]++
}
}
}
var succModTime time.Time
var smodTimeQuorum bool
for smodTime, count := range succModTimeMap {
if count >= quorum {
smodTimeQuorum = true
succModTime = smodTime
break
} }
} }
if found {
if smodTimeQuorum {
candidate.SuccessorModTime = succModTime
candidate.IsLatest = succModTime.IsZero()
}
return candidate, nil
}
return FileInfo{}, errErasureReadQuorum return FileInfo{}, errErasureReadQuorum
} }

View File

@ -158,7 +158,7 @@ func TestObjectToPartOffset(t *testing.T) {
} }
func TestFindFileInfoInQuorum(t *testing.T) { func TestFindFileInfoInQuorum(t *testing.T) {
getNFInfo := func(n int, quorum int, t int64, dataDir string) []FileInfo { getNFInfo := func(n int, quorum int, t int64, dataDir string, succModTimes []time.Time) []FileInfo {
fi := newFileInfo("test", 8, 8) fi := newFileInfo("test", 8, 8)
fi.AddObjectPart(1, "etag", 100, 100, UTCNow(), nil, nil) fi.AddObjectPart(1, "etag", 100, 100, UTCNow(), nil, nil)
fi.ModTime = time.Unix(t, 0) fi.ModTime = time.Unix(t, 0)
@ -167,6 +167,10 @@ func TestFindFileInfoInQuorum(t *testing.T) {
for i := range fis { for i := range fis {
fis[i] = fi fis[i] = fi
fis[i].Erasure.Index = i + 1 fis[i].Erasure.Index = i + 1
if succModTimes != nil {
fis[i].SuccessorModTime = succModTimes[i]
fis[i].IsLatest = succModTimes[i].IsZero()
}
quorum-- quorum--
if quorum == 0 { if quorum == 0 {
break break
@ -175,39 +179,79 @@ func TestFindFileInfoInQuorum(t *testing.T) {
return fis return fis
} }
commonSuccModTime := time.Date(2023, time.August, 25, 0, 0, 0, 0, time.UTC)
succModTimesInQuorum := make([]time.Time, 16)
succModTimesNoQuorum := make([]time.Time, 16)
for i := 0; i < 16; i++ {
if i < 4 {
continue
}
succModTimesInQuorum[i] = commonSuccModTime
if i < 9 {
continue
}
succModTimesNoQuorum[i] = commonSuccModTime
}
tests := []struct { tests := []struct {
fis []FileInfo fis []FileInfo
modTime time.Time modTime time.Time
succmodTimes []time.Time
expectedErr error expectedErr error
expectedQuorum int expectedQuorum int
expectedSuccModTime time.Time
expectedIsLatest bool
}{ }{
{ {
fis: getNFInfo(16, 16, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21"), fis: getNFInfo(16, 16, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21", nil),
modTime: time.Unix(1603863445, 0), modTime: time.Unix(1603863445, 0),
expectedErr: nil, expectedErr: nil,
expectedQuorum: 8, expectedQuorum: 8,
}, },
{ {
fis: getNFInfo(16, 7, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21"), fis: getNFInfo(16, 7, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21", nil),
modTime: time.Unix(1603863445, 0), modTime: time.Unix(1603863445, 0),
expectedErr: errErasureReadQuorum, expectedErr: errErasureReadQuorum,
expectedQuorum: 8, expectedQuorum: 8,
}, },
{ {
fis: getNFInfo(16, 16, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21"), fis: getNFInfo(16, 16, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21", nil),
modTime: time.Unix(1603863445, 0), modTime: time.Unix(1603863445, 0),
expectedErr: errErasureReadQuorum, expectedErr: errErasureReadQuorum,
expectedQuorum: 0, expectedQuorum: 0,
}, },
{
fis: getNFInfo(16, 16, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21", succModTimesInQuorum),
modTime: time.Unix(1603863445, 0),
expectedErr: nil,
expectedQuorum: 12,
expectedSuccModTime: commonSuccModTime,
expectedIsLatest: false,
},
{
fis: getNFInfo(16, 16, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21", succModTimesNoQuorum),
modTime: time.Unix(1603863445, 0),
expectedErr: nil,
expectedQuorum: 12,
expectedSuccModTime: time.Time{},
expectedIsLatest: true,
},
} }
for _, test := range tests { for _, test := range tests {
test := test test := test
t.Run("", func(t *testing.T) { t.Run("", func(t *testing.T) {
_, err := findFileInfoInQuorum(context.Background(), test.fis, test.modTime, "", test.expectedQuorum) fi, err := findFileInfoInQuorum(context.Background(), test.fis, test.modTime, "", test.expectedQuorum)
if err != test.expectedErr { if err != test.expectedErr {
t.Errorf("Expected %s, got %s", test.expectedErr, err) t.Errorf("Expected %s, got %s", test.expectedErr, err)
} }
if test.succmodTimes != nil {
if !test.expectedSuccModTime.Equal(fi.SuccessorModTime) {
t.Errorf("Expected successor mod time to be %v but got %v", test.expectedSuccModTime, fi.SuccessorModTime)
}
if test.expectedIsLatest != fi.IsLatest {
t.Errorf("Expected IsLatest to be %v but got %v", test.expectedIsLatest, fi.IsLatest)
}
}
}) })
} }
} }