aboutsummaryrefslogtreecommitdiff
path: root/weed/util
diff options
context:
space:
mode:
authorbingoohuang <bingoo.huang@gmail.com>2021-04-27 10:37:24 +0800
committerbingoohuang <bingoo.huang@gmail.com>2021-04-27 10:37:24 +0800
commitcf552417a7a422d1313c53972fd1175684e758e0 (patch)
tree621d6f4f432cefe75c455939e084193eb7462001 /weed/util
parent31f1cdeac281fb88a3d03743f9796f81e1d74378 (diff)
downloadseaweedfs-cf552417a7a422d1313c53972fd1175684e758e0.tar.xz
seaweedfs-cf552417a7a422d1313c53972fd1175684e758e0.zip
minFreeSpace refactored
Diffstat (limited to 'weed/util')
-rw-r--r--weed/util/bytes.go22
-rw-r--r--weed/util/bytes_test.go26
-rw-r--r--weed/util/minfreespace.go90
-rw-r--r--weed/util/minfreespace_test.go29
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)
+ }
+ }
+}