diff options
| author | bingoohuang <bingoo.huang@gmail.com> | 2021-04-27 10:37:24 +0800 |
|---|---|---|
| committer | bingoohuang <bingoo.huang@gmail.com> | 2021-04-27 10:37:24 +0800 |
| commit | cf552417a7a422d1313c53972fd1175684e758e0 (patch) | |
| tree | 621d6f4f432cefe75c455939e084193eb7462001 /weed/util | |
| parent | 31f1cdeac281fb88a3d03743f9796f81e1d74378 (diff) | |
| download | seaweedfs-cf552417a7a422d1313c53972fd1175684e758e0.tar.xz seaweedfs-cf552417a7a422d1313c53972fd1175684e758e0.zip | |
minFreeSpace refactored
Diffstat (limited to 'weed/util')
| -rw-r--r-- | weed/util/bytes.go | 22 | ||||
| -rw-r--r-- | weed/util/bytes_test.go | 26 | ||||
| -rw-r--r-- | weed/util/minfreespace.go | 90 | ||||
| -rw-r--r-- | weed/util/minfreespace_test.go | 29 |
4 files changed, 124 insertions, 43 deletions
diff --git a/weed/util/bytes.go b/weed/util/bytes.go index 260e5067e..26da91033 100644 --- a/weed/util/bytes.go +++ b/weed/util/bytes.go @@ -5,7 +5,6 @@ import ( "crypto/md5" "crypto/rand" "encoding/base64" - "errors" "fmt" "io" "math" @@ -176,23 +175,12 @@ func EmptyTo(s, to string) string { return s } -var ErrMinFreeSpaceBadValue = errors.New("minFreeSpace is invalid") - -// ParseMinFreeSpace parses min free space expression s as percentage like 1,10 or human readable size like 10G -func ParseMinFreeSpace(s string) (float32, error) { - if value, e := strconv.ParseFloat(s, 32); e == nil { - if value < 0 || value > 100 { - return 0, ErrMinFreeSpaceBadValue - } - return float32(value), nil - } else if directSize, e2 := ParseBytes(s); e2 == nil { - if directSize <= 100 { - return 0, ErrMinFreeSpaceBadValue - } - return float32(directSize), nil +// IfElse works like b ? this : that. +func IfElse(b bool, this, that string) string { + if b { + return this } - - return 0, ErrMinFreeSpaceBadValue + return that } // ParseBytes parses a string representation of bytes into the number diff --git a/weed/util/bytes_test.go b/weed/util/bytes_test.go index 4a9c25e52..d9269cadb 100644 --- a/weed/util/bytes_test.go +++ b/weed/util/bytes_test.go @@ -2,32 +2,6 @@ package util import "testing" -func TestParseMinFreeSpace(t *testing.T) { - tests := []struct { - in string - ok bool - value float32 - }{ - {in: "42", ok: true, value: 42}, - {in: "-1", ok: false, value: 0}, - {in: "101", ok: false, value: 0}, - {in: "100B", ok: false, value: 0}, - {in: "100Ki", ok: true, value: 100 * 1024}, - {in: "100GiB", ok: true, value: 100 * 1024 * 1024 * 1024}, - {in: "42M", ok: true, value: 42 * 1000 * 1000}, - } - - for _, p := range tests { - got, err := ParseMinFreeSpace(p.in) - if p.ok != (err == nil) { - t.Errorf("failed to test %v", p.in) - } - if p.ok && err == nil && got != p.value { - t.Errorf("failed to test %v", p.in) - } - } -} - func TestByteParsing(t *testing.T) { tests := []struct { in string diff --git a/weed/util/minfreespace.go b/weed/util/minfreespace.go new file mode 100644 index 000000000..c802bf6dd --- /dev/null +++ b/weed/util/minfreespace.go @@ -0,0 +1,90 @@ +package util + +import ( + "errors" + "fmt" + "github.com/chrislusf/seaweedfs/weed/glog" + "strconv" + "strings" +) + +// MinFreeSpaceType is the type of MinFreeSpace. +type MinFreeSpaceType int + +const ( + // AsPercent set the MinFreeSpaceType to a percentage value from 0 to 100. + AsPercent MinFreeSpaceType = iota + // AsBytes set the MinFreeSpaceType to a absolute value bytes. + AsBytes +) + +// MinFreeSpace is type that defines the limit for the minimum free space. +type MinFreeSpace struct { + Type MinFreeSpaceType + Bytes uint64 + Percent float32 + Raw string +} + +// IsLow tells whether the free space is low or not. +func (s MinFreeSpace) IsLow(freeBytes uint64, freePercent float32) (yes bool, desc string) { + switch s.Type { + case AsPercent: + yes = freePercent < s.Percent + op := IfElse(yes, "<", ">=") + return yes, fmt.Sprintf("disk free %.2f%% %s required %.2f%%", freePercent, op, s.Percent) + case AsBytes: + yes = freeBytes < s.Bytes + op := IfElse(yes, "<", ">=") + return yes, fmt.Sprintf("disk free %s %s required %s", + BytesToHumanReadable(freeBytes), op, BytesToHumanReadable(s.Bytes)) + } + + return false, "" +} + +// String returns a string representation of MinFreeSpace. +func (s MinFreeSpace) String() string { + switch s.Type { + case AsPercent: + return fmt.Sprintf("%.2f%%", s.Percent) + default: + return s.Raw + } +} + +// MustParseMinFreeSpace parses comma-separated argument for min free space setting. +// minFreeSpace has the high priority than minFreeSpacePercent if it is set. +func MustParseMinFreeSpace(minFreeSpace string, minFreeSpacePercent string) (spaces []MinFreeSpace) { + ss := strings.Split(EmptyTo(minFreeSpace, minFreeSpacePercent), ",") + for _, freeString := range ss { + if vv, e := ParseMinFreeSpace(freeString); e == nil { + spaces = append(spaces, *vv) + } else { + glog.Fatalf("The value specified in -minFreeSpace not a valid value %s", freeString) + } + } + + return spaces +} + +var ErrMinFreeSpaceBadValue = errors.New("minFreeSpace is invalid") + +// ParseMinFreeSpace parses min free space expression s as percentage like 1,10 or human readable size like 10G +func ParseMinFreeSpace(s string) (*MinFreeSpace, error) { + if percent, e := strconv.ParseFloat(s, 32); e == nil { + if percent < 0 || percent > 100 { + return nil, ErrMinFreeSpaceBadValue + } + return &MinFreeSpace{Type: AsPercent, Percent: float32(percent), Raw: s}, nil + } + + if directSize, e := ParseBytes(s); e == nil { + if directSize <= 100 { + return nil, ErrMinFreeSpaceBadValue + } + return &MinFreeSpace{Type: AsBytes, Bytes: directSize, Raw: s}, nil + } + + return nil, ErrMinFreeSpaceBadValue +} diff --git a/weed/util/minfreespace_test.go b/weed/util/minfreespace_test.go new file mode 100644 index 000000000..eec1942dd --- /dev/null +++ b/weed/util/minfreespace_test.go @@ -0,0 +1,29 @@ +package util + +import "testing" + +func TestParseMinFreeSpace(t *testing.T) { + tests := []struct { + in string + ok bool + value *MinFreeSpace + }{ + {in: "42", ok: true, value: &MinFreeSpace{Type: AsPercent, Percent: 42, Raw: "42"}}, + {in: "-1", ok: false, value: nil}, + {in: "101", ok: false, value: nil}, + {in: "100B", ok: false, value: nil}, + {in: "100Ki", ok: true, value: &MinFreeSpace{Type: AsBytes, Bytes: 100 * 1024, Raw: "100Ki"}}, + {in: "100GiB", ok: true, value: &MinFreeSpace{Type: AsBytes, Bytes: 100 * 1024 * 1024 * 1024, Raw: "100GiB"}}, + {in: "42M", ok: true, value: &MinFreeSpace{Type: AsBytes, Bytes: 42 * 1000 * 1000, Raw: "42M"}}, + } + + for _, p := range tests { + got, err := ParseMinFreeSpace(p.in) + if p.ok != (err == nil) { + t.Errorf("failed to test %v", p.in) + } + if p.ok && err == nil && *got != *p.value { + t.Errorf("failed to test %v", p.in) + } + } +} |
