adds base 10 memory sizes (#1061)

This commit is contained in:
Natalie Villasana 2019-01-15 17:17:37 -05:00 committed by GitHub
parent 01e4811a6f
commit a7d3a8ded7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 132 additions and 25 deletions

View File

@ -10,15 +10,22 @@ import (
"strings"
)
// different sizes
// base 2 and base 10 sizes
const (
B Size = 1 << (10 * iota)
KB
MB
GB
TB
PB
EB
KiB
MiB
GiB
TiB
PiB
EiB
KB Size = 1e3
MB Size = 1e6
GB Size = 1e9
TB Size = 1e12
PB Size = 1e15
EB Size = 1e18
)
// Size implements flag.Value for collecting memory size in bytes
@ -36,6 +43,24 @@ func (size Size) Int64() int64 { return int64(size) }
// Float64 returns bytes size as float64
func (size Size) Float64() float64 { return float64(size) }
// KiB returns size in kibibytes
func (size Size) KiB() float64 { return size.Float64() / KiB.Float64() }
// MiB returns size in mebibytes
func (size Size) MiB() float64 { return size.Float64() / MiB.Float64() }
// GiB returns size in gibibytes
func (size Size) GiB() float64 { return size.Float64() / GiB.Float64() }
// TiB returns size in tebibytes
func (size Size) TiB() float64 { return size.Float64() / TiB.Float64() }
// PiB returns size in pebibytes
func (size Size) PiB() float64 { return size.Float64() / PiB.Float64() }
// EiB returns size in exbibytes
func (size Size) EiB() float64 { return size.Float64() / EiB.Float64() }
// KB returns size in kilobytes
func (size Size) KB() float64 { return size.Float64() / KB.Float64() }
@ -51,7 +76,7 @@ func (size Size) TB() float64 { return size.Float64() / TB.Float64() }
// PB returns size in petabytes
func (size Size) PB() float64 { return size.Float64() / PB.Float64() }
// EB returns size in etabytes
// EB returns size in exabytes
func (size Size) EB() float64 { return size.Float64() / EB.Float64() }
// String converts size to a string
@ -60,6 +85,30 @@ func (size Size) String() string {
return "0"
}
switch {
case size >= EiB*2/3:
return fmt.Sprintf("%.1f EiB", size.EiB())
case size >= PiB*2/3:
return fmt.Sprintf("%.1f PiB", size.PiB())
case size >= TiB*2/3:
return fmt.Sprintf("%.1f TiB", size.TiB())
case size >= GiB*2/3:
return fmt.Sprintf("%.1f GiB", size.GiB())
case size >= MiB*2/3:
return fmt.Sprintf("%.1f MiB", size.MiB())
case size >= KiB*2/3:
return fmt.Sprintf("%.1f KiB", size.KiB())
}
return strconv.Itoa(size.Int()) + " B"
}
// Base10String converts size to a string
func (size Size) Base10String() string {
if size == 0 {
return "0"
}
switch {
case size >= EB*2/3:
return fmt.Sprintf("%.1f EB", size.EB())
@ -110,18 +159,30 @@ func (size *Size) Set(s string) error {
}
switch suffix {
case "EB", "EIB":
case "EB":
*size = Size(v * EB.Float64())
case "PB", "PIB":
case "EIB":
*size = Size(v * EiB.Float64())
case "PB":
*size = Size(v * PB.Float64())
case "TB", "TIB":
case "PIB":
*size = Size(v * PiB.Float64())
case "TB":
*size = Size(v * TB.Float64())
case "GB", "GIB":
case "TIB":
*size = Size(v * TiB.Float64())
case "GB":
*size = Size(v * GB.Float64())
case "MB", "MIB":
case "GIB":
*size = Size(v * GiB.Float64())
case "MB":
*size = Size(v * MB.Float64())
case "KB", "KIB":
case "MIB":
*size = Size(v * MiB.Float64())
case "KB":
*size = Size(v * KB.Float64())
case "KIB":
*size = Size(v * KiB.Float64())
case "B", "":
*size = Size(v)
default:

View File

@ -10,20 +10,66 @@ import (
)
const (
eb = 1 << 60
pb = 1 << 50
tb = 1 << 40
gb = 1 << 30
mb = 1 << 20
kb = 1 << 10
eib = 1 << 60
pib = 1 << 50
tib = 1 << 40
gib = 1 << 30
mib = 1 << 20
kib = 1 << 10
eb = 1e18
pb = 1e15
tb = 1e12
gb = 1e9
mb = 1e6
kb = 1e3
)
func TestSize(t *testing.T) {
func TestBase2Size(t *testing.T) {
var tests = []struct {
size memory.Size
text string
}{
// basics
{1 * eib, "1.0 EiB"},
{1 * pib, "1.0 PiB"},
{1 * tib, "1.0 TiB"},
{1 * gib, "1.0 GiB"},
{1 * mib, "1.0 MiB"},
{1 * kib, "1.0 KiB"},
{1, "1 B"},
// complicated
{68 * tib, "68.0 TiB"},
{256 * mib, "256.0 MiB"},
{500, "500 B"},
{5, "5 B"},
{1, "1 B"},
{0, "0"},
}
for i, test := range tests {
if test.size.String() != test.text {
t.Errorf("%d. invalid text got %v expected %v", i, test.size.String(), test.text)
}
var size memory.Size
err := size.Set(test.text)
if err != nil {
t.Errorf("%d. got error %v", i, err)
}
if test.size != size {
t.Errorf("%d. invalid size got %d expected %d", i, size, test.size)
}
}
}
func TestBase10Size(t *testing.T) {
var tests = []struct {
size memory.Size
text string
}{
// basics
{1 * pb, "1.0 PB"},
{1 * eb, "1.0 EB"},
{1 * tb, "1.0 TB"},
{1 * gb, "1.0 GB"},
{1 * mb, "1.0 MB"},
@ -39,7 +85,7 @@ func TestSize(t *testing.T) {
}
for i, test := range tests {
if test.size.String() != test.text {
if test.size.Base10String() != test.text {
t.Errorf("%d. invalid text got %v expected %v", i, test.size.String(), test.text)
}
@ -69,9 +115,9 @@ func TestParse(t *testing.T) {
{1 * gb, "1.0 gB"},
{1 * mb, "1.0 Mb"},
{1 * kb, "1.0 kb"},
{1 * kb, "1.0kib"},
{1 * pb, "1.0pib"},
{1 * eb, "1.0eib"},
{1 * kib, "1.0kib"},
{1 * pib, "1.0pib"},
{1 * eib, "1.0eib"},
{1, "1.00"},
// without B suffix
{1 * tb, "1.00T"},