bingoohuang
4 years ago
10 changed files with 147 additions and 77 deletions
-
2unmaintained/repeated_vacuum/repeated_vacuum.go
-
9weed/command/server.go
-
26weed/command/volume.go
-
2weed/server/volume_server.go
-
14weed/storage/disk_location.go
-
4weed/storage/store.go
-
22weed/util/bytes.go
-
26weed/util/bytes_test.go
-
90weed/util/minfreespace.go
-
29weed/util/minfreespace_test.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 |
||||
|
} |
@ -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) |
||||
|
} |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue