From 598915193ae44ccac9a88cee99d2ca5204dee215 Mon Sep 17 00:00:00 2001 From: Marcel Meyer Date: Mon, 26 May 2025 20:37:49 +0200 Subject: [PATCH] refactor: use slices package for sorting (#10136) Few more complicated usages of the sort packages are left. ### Purpose Make progress towards replacing the sort package with slices package. --- cmd/syncthing/crash_reporting.go | 6 ++-- lib/api/tokenmanager.go | 4 +-- lib/config/config.go | 5 ++- lib/config/deviceconfiguration.go | 6 ++-- lib/config/folderconfiguration.go | 6 ++-- lib/db/meta_test.go | 6 ++-- lib/db/set_test.go | 45 +++++++++++--------------- lib/model/blockpullreorderer.go | 6 ++-- lib/model/blockpullreorderer_test.go | 6 ++-- lib/model/folder.go | 6 ++-- lib/model/folder_recvenc.go | 7 ++-- lib/model/folder_recvonly.go | 7 ++-- lib/model/folder_sendrecv.go | 20 +++--------- lib/model/queue.go | 33 ++++++++----------- lib/scanner/walk_test.go | 21 ++++-------- lib/versioner/empty_dir_tracker.go | 7 ++-- script/authors.go | 48 ++++++++++------------------ test/util.go | 20 +++--------- 18 files changed, 107 insertions(+), 152 deletions(-) diff --git a/cmd/syncthing/crash_reporting.go b/cmd/syncthing/crash_reporting.go index c71dc007c..279ae11f7 100644 --- a/cmd/syncthing/crash_reporting.go +++ b/cmd/syncthing/crash_reporting.go @@ -14,7 +14,7 @@ import ( "net/http" "os" "path/filepath" - "sort" + "slices" "strings" "time" ) @@ -37,7 +37,9 @@ func uploadPanicLogs(ctx context.Context, urlBase, dir string) { return } - sort.Sort(sort.Reverse(sort.StringSlice(files))) + slices.SortFunc(files, func(a, b string) int { + return strings.Compare(b, a) + }) for _, file := range files { if strings.Contains(file, ".reported.") { // We've already sent this file. It'll be cleaned out at some diff --git a/lib/api/tokenmanager.go b/lib/api/tokenmanager.go index 904b070bd..77c57a581 100644 --- a/lib/api/tokenmanager.go +++ b/lib/api/tokenmanager.go @@ -117,8 +117,8 @@ func (m *tokenManager) saveLocked() { for token, expiry := range m.tokens.Tokens { tokens = append(tokens, tokenExpiry{token, expiry}) } - slices.SortFunc(tokens, func(i, j tokenExpiry) int { - return int(i.expiry - j.expiry) + slices.SortFunc(tokens, func(a, b tokenExpiry) int { + return int(a.expiry - b.expiry) }) // Remove the oldest tokens. for _, token := range tokens[:len(tokens)-m.maxItems] { diff --git a/lib/config/config.go b/lib/config/config.go index 740054726..78951be89 100644 --- a/lib/config/config.go +++ b/lib/config/config.go @@ -18,7 +18,6 @@ import ( "os" "reflect" "slices" - "sort" "strconv" "strings" @@ -338,8 +337,8 @@ func (cfg *Configuration) prepareDeviceList() map[protocol.DeviceID]*DeviceConfi // - sorted by ID // Happen before preparting folders as that needs a correct device list. cfg.Devices = ensureNoDuplicateOrEmptyIDDevices(cfg.Devices) - sort.Slice(cfg.Devices, func(a, b int) bool { - return cfg.Devices[a].DeviceID.Compare(cfg.Devices[b].DeviceID) == -1 + slices.SortFunc(cfg.Devices, func(a, b DeviceConfiguration) int { + return a.DeviceID.Compare(b.DeviceID) }) // Build a list of available devices diff --git a/lib/config/deviceconfiguration.go b/lib/config/deviceconfiguration.go index d91722764..b12514175 100644 --- a/lib/config/deviceconfiguration.go +++ b/lib/config/deviceconfiguration.go @@ -8,7 +8,7 @@ package config import ( "fmt" - "sort" + "slices" "github.com/syncthing/syncthing/lib/protocol" ) @@ -100,8 +100,8 @@ func sortedObservedFolderSlice(input map[string]ObservedFolder) []ObservedFolder for _, folder := range input { output = append(output, folder) } - sort.Slice(output, func(i, j int) bool { - return output[i].Time.Before(output[j].Time) + slices.SortFunc(output, func(a, b ObservedFolder) int { + return a.Time.Compare(b.Time) }) return output } diff --git a/lib/config/folderconfiguration.go b/lib/config/folderconfiguration.go index 715bff8c9..0d23b1397 100644 --- a/lib/config/folderconfiguration.go +++ b/lib/config/folderconfiguration.go @@ -15,7 +15,7 @@ import ( "fmt" "path" "path/filepath" - "sort" + "slices" "strings" "time" @@ -291,8 +291,8 @@ func (f *FolderConfiguration) prepare(myID protocol.DeviceID, existingDevices ma f.Devices = ensureDevicePresent(f.Devices, myID) f.Devices = ensureNoUntrustedTrustingSharing(f, f.Devices, existingDevices) - sort.Slice(f.Devices, func(a, b int) bool { - return f.Devices[a].DeviceID.Compare(f.Devices[b].DeviceID) == -1 + slices.SortFunc(f.Devices, func(a, b FolderDeviceConfiguration) int { + return a.DeviceID.Compare(b.DeviceID) }) if f.RescanIntervalS > MaxRescanIntervalS { diff --git a/lib/db/meta_test.go b/lib/db/meta_test.go index e68257a70..e56e9302a 100644 --- a/lib/db/meta_test.go +++ b/lib/db/meta_test.go @@ -8,7 +8,7 @@ package db import ( "math/bits" - "sort" + "slices" "testing" "github.com/syncthing/syncthing/lib/events" @@ -71,8 +71,8 @@ func TestMetaDevices(t *testing.T) { } // Check that we got the two devices we expect - sort.Slice(devs, func(a, b int) bool { - return devs[a].Compare(devs[b]) == -1 + slices.SortFunc(devs, func(a, b protocol.DeviceID) int { + return a.Compare(b) }) if devs[0] != d1 { t.Error("first device should be d1") diff --git a/lib/db/set_test.go b/lib/db/set_test.go index 459d9531e..36cef101b 100644 --- a/lib/db/set_test.go +++ b/lib/db/set_test.go @@ -11,7 +11,8 @@ import ( "fmt" "os" "path/filepath" - "sort" + "slices" + "strings" "testing" "time" @@ -102,16 +103,8 @@ func needList(t testing.TB, s *db.FileSet, n protocol.DeviceID) []protocol.FileI type fileList []protocol.FileInfo -func (l fileList) Len() int { - return len(l) -} - -func (l fileList) Less(a, b int) bool { - return l[a].Name < l[b].Name -} - -func (l fileList) Swap(a, b int) { - l[a], l[b] = l[b], l[a] +func compareByName(a, b protocol.FileInfo) int { + return strings.Compare(a.Name, b.Name) } func (l fileList) String() string { @@ -218,7 +211,7 @@ func TestGlobalSet(t *testing.T) { t.Helper() g := fileList(globalList(t, m)) - sort.Sort(g) + slices.SortFunc(g, compareByName) if fmt.Sprint(g) != fmt.Sprint(expectedGlobal) { t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal) @@ -255,7 +248,7 @@ func TestGlobalSet(t *testing.T) { } h := fileList(haveList(t, m, protocol.LocalDeviceID)) - sort.Sort(h) + slices.SortFunc(h, compareByName) if fmt.Sprint(h) != fmt.Sprint(localTot) { t.Errorf("Have incorrect (local);\n A: %v !=\n E: %v", h, localTot) @@ -292,14 +285,14 @@ func TestGlobalSet(t *testing.T) { } h = fileList(haveList(t, m, remoteDevice0)) - sort.Sort(h) + slices.SortFunc(h, compareByName) if fmt.Sprint(h) != fmt.Sprint(remoteTot) { t.Errorf("Have incorrect (remote);\n A: %v !=\n E: %v", h, remoteTot) } n := fileList(needList(t, m, protocol.LocalDeviceID)) - sort.Sort(n) + slices.SortFunc(n, compareByName) if fmt.Sprint(n) != fmt.Sprint(expectedLocalNeed) { t.Errorf("Need incorrect (local);\n A: %v !=\n E: %v", n, expectedLocalNeed) @@ -308,7 +301,7 @@ func TestGlobalSet(t *testing.T) { checkNeed(t, m, protocol.LocalDeviceID, expectedLocalNeed) n = fileList(needList(t, m, remoteDevice0)) - sort.Sort(n) + slices.SortFunc(n, compareByName) if fmt.Sprint(n) != fmt.Sprint(expectedRemoteNeed) { t.Errorf("Need incorrect (remote);\n A: %v !=\n E: %v", n, expectedRemoteNeed) @@ -428,14 +421,14 @@ func TestGlobalSet(t *testing.T) { check() h := fileList(haveList(t, m, remoteDevice1)) - sort.Sort(h) + slices.SortFunc(h, compareByName) if fmt.Sprint(h) != fmt.Sprint(secRemote) { t.Errorf("Have incorrect (secRemote);\n A: %v !=\n E: %v", h, secRemote) } n := fileList(needList(t, m, remoteDevice1)) - sort.Sort(n) + slices.SortFunc(n, compareByName) if fmt.Sprint(n) != fmt.Sprint(expectedSecRemoteNeed) { t.Errorf("Need incorrect (secRemote);\n A: %v !=\n E: %v", n, expectedSecRemoteNeed) @@ -475,7 +468,7 @@ func TestNeedWithInvalid(t *testing.T) { replace(s, remoteDevice1, remote1Have) need := fileList(needList(t, s, protocol.LocalDeviceID)) - sort.Sort(need) + slices.SortFunc(need, compareByName) if fmt.Sprint(need) != fmt.Sprint(expectedNeed) { t.Errorf("Need incorrect;\n A: %v !=\n E: %v", need, expectedNeed) @@ -503,7 +496,7 @@ func TestUpdateToInvalid(t *testing.T) { replace(s, protocol.LocalDeviceID, localHave) have := fileList(haveList(t, s, protocol.LocalDeviceID)) - sort.Sort(have) + slices.SortFunc(have, compareByName) if fmt.Sprint(have) != fmt.Sprint(localHave) { t.Errorf("Have incorrect before invalidation;\n A: %v !=\n E: %v", have, localHave) @@ -519,8 +512,8 @@ func TestUpdateToInvalid(t *testing.T) { s.Update(protocol.LocalDeviceID, append(fileList{}, localHave[1], localHave[4])) - have = fileList(haveList(t, s, protocol.LocalDeviceID)) - sort.Sort(have) + have = haveList(t, s, protocol.LocalDeviceID) + slices.SortFunc(have, compareByName) if fmt.Sprint(have) != fmt.Sprint(localHave) { t.Errorf("Have incorrect after invalidation;\n A: %v !=\n E: %v", have, localHave) @@ -605,7 +598,7 @@ func TestGlobalReset(t *testing.T) { replace(m, protocol.LocalDeviceID, local) g := globalList(t, m) - sort.Sort(fileList(g)) + slices.SortFunc(g, compareByName) if diff, equal := messagediff.PrettyDiff(local, g); !equal { t.Errorf("Global incorrect;\nglobal: %v\n!=\nlocal: %v\ndiff:\n%s", g, local, diff) @@ -615,7 +608,7 @@ func TestGlobalReset(t *testing.T) { replace(m, remoteDevice0, nil) g = globalList(t, m) - sort.Sort(fileList(g)) + slices.SortFunc(g, compareByName) if diff, equal := messagediff.PrettyDiff(local, g); !equal { t.Errorf("Global incorrect;\nglobal: %v\n!=\nlocal: %v\ndiff:\n%s", g, local, diff) @@ -653,8 +646,8 @@ func TestNeed(t *testing.T) { need := needList(t, m, protocol.LocalDeviceID) - sort.Sort(fileList(need)) - sort.Sort(fileList(shouldNeed)) + slices.SortFunc(need, compareByName) + slices.SortFunc(shouldNeed, compareByName) if fmt.Sprint(need) != fmt.Sprint(shouldNeed) { t.Errorf("Need incorrect;\n%v !=\n%v", need, shouldNeed) diff --git a/lib/model/blockpullreorderer.go b/lib/model/blockpullreorderer.go index c2292c279..838fa869d 100644 --- a/lib/model/blockpullreorderer.go +++ b/lib/model/blockpullreorderer.go @@ -7,7 +7,7 @@ package model import ( - "sort" + "slices" "github.com/syncthing/syncthing/lib/config" "github.com/syncthing/syncthing/lib/protocol" @@ -52,8 +52,8 @@ type standardBlockPullReorderer struct { func newStandardBlockPullReorderer(id protocol.DeviceID, otherDevices []protocol.DeviceID) *standardBlockPullReorderer { allDevices := append(otherDevices, id) - sort.Slice(allDevices, func(i, j int) bool { - return allDevices[i].Compare(allDevices[j]) == -1 + slices.SortFunc(allDevices, func(a, b protocol.DeviceID) int { + return a.Compare(b) }) // Find our index myIndex := -1 diff --git a/lib/model/blockpullreorderer_test.go b/lib/model/blockpullreorderer_test.go index 049c16640..ac24fdeb0 100644 --- a/lib/model/blockpullreorderer_test.go +++ b/lib/model/blockpullreorderer_test.go @@ -8,7 +8,7 @@ package model import ( "reflect" - "sort" + "slices" "testing" "github.com/syncthing/syncthing/lib/protocol" @@ -65,8 +65,8 @@ func Test_inOrderBlockPullReorderer_Reorder(t *testing.T) { func Test_standardBlockPullReorderer_Reorder(t *testing.T) { // Order the devices, so we know their ordering ahead of time. devices := []protocol.DeviceID{myID, device1, device2} - sort.Slice(devices, func(i, j int) bool { - return devices[i].Compare(devices[j]) == -1 + slices.SortFunc(devices, func(a, b protocol.DeviceID) int { + return a.Compare(b) }) blocks := func(i ...int) []protocol.BlockInfo { diff --git a/lib/model/folder.go b/lib/model/folder.go index a0c342158..863721c2c 100644 --- a/lib/model/folder.go +++ b/lib/model/folder.go @@ -13,7 +13,7 @@ import ( "math/rand" "path/filepath" "slices" - "sort" + "strings" "time" "github.com/syncthing/syncthing/lib/config" @@ -1201,7 +1201,9 @@ func (f *folder) Errors() []FileError { errors := make([]FileError, scanLen+len(f.pullErrors)) copy(errors[:scanLen], f.scanErrors) copy(errors[scanLen:], f.pullErrors) - sort.Sort(fileErrorList(errors)) + slices.SortFunc(errors, func(a, b FileError) int { + return strings.Compare(a.Path, b.Path) + }) return errors } diff --git a/lib/model/folder_recvenc.go b/lib/model/folder_recvenc.go index 2892be116..7e3cd09de 100644 --- a/lib/model/folder_recvenc.go +++ b/lib/model/folder_recvenc.go @@ -8,7 +8,8 @@ package model import ( "fmt" - "sort" + "slices" + "strings" "github.com/syncthing/syncthing/lib/config" "github.com/syncthing/syncthing/lib/db" @@ -112,7 +113,9 @@ func (f *receiveEncryptedFolder) revertHandleDirs(dirs []string, snap *db.Snapsh go f.pullScannerRoutine(scanChan) defer close(scanChan) - sort.Sort(sort.Reverse(sort.StringSlice(dirs))) + slices.SortFunc(dirs, func(a, b string) int { + return strings.Compare(b, a) + }) for _, dir := range dirs { if err := f.deleteDirOnDisk(dir, snap, scanChan); err != nil { f.newScanError(dir, fmt.Errorf("deleting unexpected dir: %w", err)) diff --git a/lib/model/folder_recvonly.go b/lib/model/folder_recvonly.go index 501a61e34..eca6ebb44 100644 --- a/lib/model/folder_recvonly.go +++ b/lib/model/folder_recvonly.go @@ -7,7 +7,8 @@ package model import ( - "sort" + "slices" + "strings" "time" "github.com/syncthing/syncthing/lib/config" @@ -207,7 +208,9 @@ func (q *deleteQueue) handle(fi protocol.FileInfo, snap *db.Snapshot) (bool, err func (q *deleteQueue) flush(snap *db.Snapshot) ([]string, error) { // Process directories from the leaves inward. - sort.Sort(sort.Reverse(sort.StringSlice(q.dirs))) + slices.SortFunc(q.dirs, func(a, b string) int { + return strings.Compare(b, a) + }) var firstError error var deleted []string diff --git a/lib/model/folder_sendrecv.go b/lib/model/folder_sendrecv.go index 613aa1ca2..790a6b734 100644 --- a/lib/model/folder_sendrecv.go +++ b/lib/model/folder_sendrecv.go @@ -14,7 +14,7 @@ import ( "fmt" "io" "path/filepath" - "sort" + "slices" "strconv" "strings" "time" @@ -1867,7 +1867,9 @@ func (f *sendReceiveFolder) moveForConflict(name, lastModBy string, scanChan cha if f.MaxConflicts > -1 { matches := existingConflicts(name, f.mtimefs) if len(matches) > f.MaxConflicts { - sort.Sort(sort.Reverse(sort.StringSlice(matches))) + slices.SortFunc(matches, func(a, b string) int { + return strings.Compare(b, a) + }) for _, match := range matches[f.MaxConflicts:] { if gerr := f.mtimefs.Remove(match); gerr != nil { l.Debugln(f, "removing extra conflict", gerr) @@ -2206,20 +2208,6 @@ type FileError struct { Err string `json:"error"` } -type fileErrorList []FileError - -func (l fileErrorList) Len() int { - return len(l) -} - -func (l fileErrorList) Less(a, b int) bool { - return l[a].Path < l[b].Path -} - -func (l fileErrorList) Swap(a, b int) { - l[a], l[b] = l[b], l[a] -} - func conflictName(name, lastModBy string) string { ext := filepath.Ext(name) return name[:len(name)-len(ext)] + time.Now().Format(".sync-conflict-20060102-150405-") + lastModBy + ext diff --git a/lib/model/queue.go b/lib/model/queue.go index 16ac83c94..cc68b9f85 100644 --- a/lib/model/queue.go +++ b/lib/model/queue.go @@ -7,7 +7,8 @@ package model import ( - "sort" + "cmp" + "slices" "time" "github.com/syncthing/syncthing/lib/rand" @@ -157,40 +158,34 @@ func (q *jobQueue) SortSmallestFirst() { q.mut.Lock() defer q.mut.Unlock() - sort.Sort(smallestFirst(q.queued)) + slices.SortFunc(q.queued, func(a, b jobQueueEntry) int { + return cmp.Compare(a.size, b.size) + }) } func (q *jobQueue) SortLargestFirst() { q.mut.Lock() defer q.mut.Unlock() - sort.Sort(sort.Reverse(smallestFirst(q.queued))) + slices.SortFunc(q.queued, func(a, b jobQueueEntry) int { + return cmp.Compare(b.size, a.size) + }) } func (q *jobQueue) SortOldestFirst() { q.mut.Lock() defer q.mut.Unlock() - sort.Sort(oldestFirst(q.queued)) + slices.SortFunc(q.queued, func(a, b jobQueueEntry) int { + return cmp.Compare(a.modified, b.modified) + }) } func (q *jobQueue) SortNewestFirst() { q.mut.Lock() defer q.mut.Unlock() - sort.Sort(sort.Reverse(oldestFirst(q.queued))) + slices.SortFunc(q.queued, func(a, b jobQueueEntry) int { + return cmp.Compare(b.modified, a.modified) + }) } - -// The usual sort.Interface boilerplate - -type smallestFirst []jobQueueEntry - -func (q smallestFirst) Len() int { return len(q) } -func (q smallestFirst) Less(a, b int) bool { return q[a].size < q[b].size } -func (q smallestFirst) Swap(a, b int) { q[a], q[b] = q[b], q[a] } - -type oldestFirst []jobQueueEntry - -func (q oldestFirst) Len() int { return len(q) } -func (q oldestFirst) Less(a, b int) bool { return q[a].modified < q[b].modified } -func (q oldestFirst) Swap(a, b int) { q[a], q[b] = q[b], q[a] } diff --git a/lib/scanner/walk_test.go b/lib/scanner/walk_test.go index 266399244..d924f2357 100644 --- a/lib/scanner/walk_test.go +++ b/lib/scanner/walk_test.go @@ -16,7 +16,8 @@ import ( "os" "path/filepath" rdebug "runtime/debug" - "sort" + "slices" + "strings" "sync" "testing" @@ -145,7 +146,7 @@ func TestWalk(t *testing.T) { } tmp = append(tmp, f.File) } - sort.Sort(fileList(tmp)) + slices.SortFunc(fileList(tmp), compareByName) files := fileList(tmp).testfiles() if diff, equal := messagediff.PrettyDiff(testdata, files); !equal { @@ -584,23 +585,15 @@ func walkDir(fs fs.Filesystem, dir string, cfiler CurrentFiler, matcher *ignore. tmp = append(tmp, f.File) } } - sort.Sort(fileList(tmp)) + slices.SortFunc(fileList(tmp), compareByName) return tmp } type fileList []protocol.FileInfo -func (l fileList) Len() int { - return len(l) -} - -func (l fileList) Less(a, b int) bool { - return l[a].Name < l[b].Name -} - -func (l fileList) Swap(a, b int) { - l[a], l[b] = l[b], l[a] +func compareByName(a, b protocol.FileInfo) int { + return strings.Compare(a.Name, b.Name) } func (l fileList) testfiles() testfileList { @@ -825,7 +818,7 @@ func TestIssue4841(t *testing.T) { } files = append(files, f.File) } - sort.Sort(fileList(files)) + slices.SortFunc(fileList(files), compareByName) if len(files) != 1 { t.Fatalf("Expected 1 file, got %d: %v", len(files), files) diff --git a/lib/versioner/empty_dir_tracker.go b/lib/versioner/empty_dir_tracker.go index fc1603df2..963e5f0fd 100644 --- a/lib/versioner/empty_dir_tracker.go +++ b/lib/versioner/empty_dir_tracker.go @@ -8,7 +8,8 @@ package versioner import ( "path/filepath" - "sort" + "slices" + "strings" "github.com/syncthing/syncthing/lib/fs" ) @@ -37,7 +38,9 @@ func (t emptyDirTracker) emptyDirs() []string { for dir := range t { empty = append(empty, dir) } - sort.Sort(sort.Reverse(sort.StringSlice(empty))) + slices.SortFunc(empty, func(a, b string) int { + return strings.Compare(b, a) + }) return empty } diff --git a/script/authors.go b/script/authors.go index 73fc8e5e2..ca128295d 100644 --- a/script/authors.go +++ b/script/authors.go @@ -14,6 +14,7 @@ package main import ( "bytes" + "cmp" "fmt" "io" "log" @@ -21,7 +22,7 @@ import ( "os" "os/exec" "regexp" - "sort" + "slices" "strings" ) @@ -102,7 +103,17 @@ func main() { // Write author names in GUI about modal getContributions(authors) - sort.Sort(byContributions(authors)) + + // Sort by contributions + slices.SortFunc(authors, func(a, b author) int { + // Sort first by log10(commits), then by name. This means that we first get + // an alphabetic list of people with >= 1000 commits, then a list of people + // with >= 100 commits, and so on. + if a.log10commits != b.log10commits { + return cmp.Compare(b.log10commits, a.log10commits) + } + return strings.Compare(a.name, b.name) + }) var lines []string for _, author := range authors { @@ -125,7 +136,10 @@ func main() { // Write AUTHORS file - sort.Sort(byName(authors)) + // Sort by author name + slices.SortFunc(authors, func(a, b author) int { + return strings.Compare(strings.ToLower(a.name), strings.ToLower(b.name)) + }) out, err := os.Create("AUTHORS") if err != nil { @@ -298,34 +312,6 @@ func allAuthors() map[string]string { return names } -type byContributions []author - -func (l byContributions) Len() int { return len(l) } - -// Sort first by log10(commits), then by name. This means that we first get -// an alphabetic list of people with >= 1000 commits, then a list of people -// with >= 100 commits, and so on. -func (l byContributions) Less(a, b int) bool { - if l[a].log10commits != l[b].log10commits { - return l[a].log10commits > l[b].log10commits - } - return l[a].name < l[b].name -} - -func (l byContributions) Swap(a, b int) { l[a], l[b] = l[b], l[a] } - -type byName []author - -func (l byName) Len() int { return len(l) } - -func (l byName) Less(a, b int) bool { - aname := strings.ToLower(l[a].name) - bname := strings.ToLower(l[b].name) - return aname < bname -} - -func (l byName) Swap(a, b int) { l[a], l[b] = l[b], l[a] } - // A simple string set type type stringSet map[string]struct{} diff --git a/test/util.go b/test/util.go index c0aab73fd..81548bdb1 100644 --- a/test/util.go +++ b/test/util.go @@ -20,7 +20,7 @@ import ( "os" "path/filepath" "runtime" - "sort" + "slices" "strings" "testing" "time" @@ -375,7 +375,9 @@ func mergeDirectoryContents(c ...[]fileInfo) []fileInfo { i++ } - sort.Sort(fileInfoList(res)) + slices.SortFunc(res, func(a, b fileInfo) int { + return strings.Compare(a.name, b.name) + }) return res } @@ -404,20 +406,6 @@ func (f fileInfo) String() string { return fmt.Sprintf("%s %04o %d %x", f.name, f.mode, f.mod, f.hash) } -type fileInfoList []fileInfo - -func (l fileInfoList) Len() int { - return len(l) -} - -func (l fileInfoList) Less(a, b int) bool { - return l[a].name < l[b].name -} - -func (l fileInfoList) Swap(a, b int) { - l[a], l[b] = l[b], l[a] -} - func startWalker(dir string, res chan<- fileInfo, abort <-chan struct{}) chan error { walker := func(path string, info os.FileInfo, err error) error { if err != nil {