From 8fd07bcd51cf45c17353543ff041858e70a36072 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 24 Apr 2023 13:28:18 -0700 Subject: [PATCH] simplify sort.Sort by using sort.Slice (#17066) --- cmd/admin-handlers_test.go | 4 +-- cmd/erasure-metadata.go | 9 +---- cmd/erasure.go | 13 ++----- cmd/net.go | 32 +++++++---------- cmd/object-api-datatypes.go | 7 ---- cmd/object-multipart-handlers.go | 4 ++- internal/bucket/lifecycle/lifecycle.go | 48 ++++++++++---------------- 7 files changed, 39 insertions(+), 78 deletions(-) diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go index ffe0e93ab..25c247094 100644 --- a/cmd/admin-handlers_test.go +++ b/cmd/admin-handlers_test.go @@ -479,8 +479,8 @@ func TestTopLockEntries(t *testing.T) { if len(exp) != len(got) { return 0, false } - sort.Sort(byResourceUID{exp}) - sort.Sort(byResourceUID{got}) + sort.Slice(exp, byResourceUID{exp}.Less) + sort.Slice(got, byResourceUID{got}.Less) // printEntries(exp) // printEntries(got) for i, e := range exp { diff --git a/cmd/erasure-metadata.go b/cmd/erasure-metadata.go index 6650dd6fc..67b3a92c8 100644 --- a/cmd/erasure-metadata.go +++ b/cmd/erasure-metadata.go @@ -42,13 +42,6 @@ const minIOErasureUpgraded = "x-minio-internal-erasure-upgraded" const erasureAlgorithm = "rs-vandermonde" -// byObjectPartNumber is a collection satisfying sort.Interface. -type byObjectPartNumber []ObjectPartInfo - -func (t byObjectPartNumber) Len() int { return len(t) } -func (t byObjectPartNumber) Swap(i, j int) { t[i], t[j] = t[j], t[i] } -func (t byObjectPartNumber) Less(i, j int) bool { return t[i].Number < t[j].Number } - // AddChecksumInfo adds a checksum of a part. func (e *ErasureInfo) AddChecksumInfo(ckSumInfo ChecksumInfo) { for i, sum := range e.Checksums { @@ -308,7 +301,7 @@ func (fi *FileInfo) AddObjectPart(partNumber int, partETag string, partSize, act fi.Parts = append(fi.Parts, partInfo) // Parts in FileInfo should be in sorted order by part number. - sort.Sort(byObjectPartNumber(fi.Parts)) + sort.Slice(fi.Parts, func(i, j int) bool { return fi.Parts[i].Number < fi.Parts[j].Number }) } // ObjectToPartOffset - translate offset of an object to offset of its individual part. diff --git a/cmd/erasure.go b/cmd/erasure.go index 29536e196..18b095ac9 100644 --- a/cmd/erasure.go +++ b/cmd/erasure.go @@ -94,15 +94,6 @@ func (er erasureObjects) defaultWQuorum() int { return dataCount } -// byDiskTotal is a collection satisfying sort.Interface. -type byDiskTotal []madmin.Disk - -func (d byDiskTotal) Len() int { return len(d) } -func (d byDiskTotal) Swap(i, j int) { d[i], d[j] = d[j], d[i] } -func (d byDiskTotal) Less(i, j int) bool { - return d[i].TotalSpace < d[j].TotalSpace -} - func diskErrToDriveState(err error) (state string) { switch { case errors.Is(err, errDiskNotFound) || errors.Is(err, context.DeadlineExceeded): @@ -245,7 +236,9 @@ func getStorageInfo(disks []StorageAPI, endpoints []Endpoint) StorageInfo { disksInfo := getDisksInfo(disks, endpoints) // Sort so that the first element is the smallest. - sort.Sort(byDiskTotal(disksInfo)) + sort.Slice(disksInfo, func(i, j int) bool { + return disksInfo[i].TotalSpace < disksInfo[j].TotalSpace + }) storageInfo := StorageInfo{ Disks: disksInfo, diff --git a/cmd/net.go b/cmd/net.go index 97d9cf865..b40c4244d 100644 --- a/cmd/net.go +++ b/cmd/net.go @@ -111,25 +111,6 @@ func getHostIP(host string) (ipList set.StringSet, err error) { return ipList, err } -// byLastOctetValue implements sort.Interface used in sorting a list -// of ip address by their last octet value in descending order. -type byLastOctetValue []net.IP - -func (n byLastOctetValue) Len() int { return len(n) } -func (n byLastOctetValue) Swap(i, j int) { n[i], n[j] = n[j], n[i] } -func (n byLastOctetValue) Less(i, j int) bool { - // This case is needed when all ips in the list - // have same last octets, Following just ensures that - // 127.0.0.1 is moved to the end of the list. - if n[i].IsLoopback() { - return false - } - if n[j].IsLoopback() { - return true - } - return []byte(n[i].To4())[3] > []byte(n[j].To4())[3] -} - // sortIPs - sort ips based on higher octects. // The logic to sort by last octet is implemented to // prefer CIDRs with higher octects, this in-turn skips the @@ -152,7 +133,18 @@ func sortIPs(ipList []string) []string { } } - sort.Sort(byLastOctetValue(ipV4s)) + sort.Slice(ipV4s, func(i, j int) bool { + // This case is needed when all ips in the list + // have same last octets, Following just ensures that + // 127.0.0.1 is moved to the end of the list. + if ipV4s[i].IsLoopback() { + return false + } + if ipV4s[j].IsLoopback() { + return true + } + return []byte(ipV4s[i].To4())[3] > []byte(ipV4s[j].To4())[3] + }) var ips []string for _, ip := range ipV4s { diff --git a/cmd/object-api-datatypes.go b/cmd/object-api-datatypes.go index db7536228..bbd8cc1f4 100644 --- a/cmd/object-api-datatypes.go +++ b/cmd/object-api-datatypes.go @@ -552,13 +552,6 @@ type CompletePart struct { ChecksumSHA256 string } -// CompletedParts - is a collection satisfying sort.Interface. -type CompletedParts []CompletePart - -func (a CompletedParts) Len() int { return len(a) } -func (a CompletedParts) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a CompletedParts) Less(i, j int) bool { return a[i].PartNumber < a[j].PartNumber } - // CompleteMultipartUpload - represents list of parts which are completed, this is sent by the // client during CompleteMultipartUpload request. type CompleteMultipartUpload struct { diff --git a/cmd/object-multipart-handlers.go b/cmd/object-multipart-handlers.go index 68aa458d8..3269f1427 100644 --- a/cmd/object-multipart-handlers.go +++ b/cmd/object-multipart-handlers.go @@ -890,7 +890,9 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedXML), r.URL) return } - if !sort.IsSorted(CompletedParts(complMultipartUpload.Parts)) { + if !sort.SliceIsSorted(complMultipartUpload.Parts, func(i, j int) bool { + return complMultipartUpload.Parts[i].PartNumber < complMultipartUpload.Parts[j].PartNumber + }) { writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPartOrder), r.URL) return } diff --git a/internal/bucket/lifecycle/lifecycle.go b/internal/bucket/lifecycle/lifecycle.go index ac90930a0..45d2b16a4 100644 --- a/internal/bucket/lifecycle/lifecycle.go +++ b/internal/bucket/lifecycle/lifecycle.go @@ -293,35 +293,6 @@ type Event struct { StorageClass string } -type lifecycleEvents []Event - -func (es lifecycleEvents) Len() int { - return len(es) -} - -func (es lifecycleEvents) Swap(i, j int) { - es[i], es[j] = es[j], es[i] -} - -func (es lifecycleEvents) Less(i, j int) bool { - if es[i].Due.Equal(es[j].Due) { - // Prefer Expiration over Transition for both current and noncurrent - // versions - switch es[i].Action { - case DeleteAction, DeleteVersionAction: - return true - } - switch es[j].Action { - case DeleteAction, DeleteVersionAction: - return false - } - return true - } - - // Prefer earlier occurring event - return es[i].Due.Before(es[j].Due) -} - // Eval returns the lifecycle event applicable now. func (lc Lifecycle) Eval(obj ObjectOpts) Event { return lc.eval(obj, time.Now().UTC()) @@ -451,7 +422,24 @@ func (lc Lifecycle) eval(obj ObjectOpts, now time.Time) Event { } if len(events) > 0 { - sort.Sort(lifecycleEvents(events)) + sort.Slice(events, func(i, j int) bool { + if events[i].Due.Equal(events[j].Due) { + // Prefer Expiration over Transition for both current + // and noncurrent versions + switch events[i].Action { + case DeleteAction, DeleteVersionAction: + return true + } + switch events[j].Action { + case DeleteAction, DeleteVersionAction: + return false + } + return true + } + + // Prefer earlier occurring event + return events[i].Due.Before(events[j].Due) + }) return events[0] }