Skip to content
This repository has been archived by the owner on Mar 28, 2020. It is now read-only.

fix sort, with a helper so the sort is done 'naturally' #2099

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 61 additions & 1 deletion pkg/backup/backup_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import (
"crypto/tls"
"fmt"
"sort"
"strconv"
"strings"
"time"
"unicode"

"github.com/coreos/etcd-operator/pkg/backup/writer"
"github.com/coreos/etcd-operator/pkg/util/constants"
Expand Down Expand Up @@ -83,13 +86,70 @@ func (bm *BackupManager) SaveSnap(ctx context.Context, s3Path string, isPeriodic
}

// EnsureMaxBackup to ensure the number of snapshot is under maxcount
// We need to naturally sort it, help functions below:
type Compare func(str1, str2 string) bool

func (cmp Compare) Sort(strs []string) {
strSort := &strSorter{
strs: strs,
cmp: cmp,
}
sort.Sort(strSort)
}

type strSorter struct {
strs []string
cmp func(str1, str2 string) bool
}

// Thanks to https://www.socketloop.com/tutorials/golang-natural-string-sorting-example
func extractNumberFromString(str string, size int) (num float64) {

strSlice := make([]string, 0)
for _, v := range str {
if unicode.IsDigit(v) {
strSlice = append(strSlice, string(v))
}
}

if size == 0 { // default
num, err := strconv.ParseFloat(strings.Join(strSlice, ""), 64)
if err != nil {
fmt.Errorf("failed: %v", err)
}

return num
} else {
num, err := strconv.ParseFloat(strSlice[size-1], 64)
if err != nil {
fmt.Errorf("failed: %v", err)
}

return num
}
}

func (s *strSorter) Len() int { return len(s.strs) }

func (s *strSorter) Swap(i, j int) { s.strs[i], s.strs[j] = s.strs[j], s.strs[i] }

func (s *strSorter) Less(i, j int) bool { return s.cmp(s.strs[i], s.strs[j]) }

// if the number of snapshot exceeded than maxcount, delete oldest snapshot
func (bm *BackupManager) EnsureMaxBackup(ctx context.Context, basePath string, maxCount int) error {
savedSnapShots, err := bm.bw.List(ctx, basePath)
if err != nil {
return fmt.Errorf("failed to get exisiting snapshots: %v", err)
}
sort.Sort(sort.Reverse(sort.StringSlice(savedSnapShots)))

// closure order for natural string number sorting
compareStringNumber := func(str1, str2 string) bool {
// switch this <> around to change the order (asc vs des)
return extractNumberFromString(str1, 0) > extractNumberFromString(str2, 0)
}
// this is sorted on the etcd revision number, the smaller the number the older it is
Compare(compareStringNumber).Sort(savedSnapShots)

for i, snapshotPath := range savedSnapShots {
if i < maxCount {
continue
Expand Down