storj/internal/memory/size.go
Alexander Leitner bfde515391
Clean up Storage node setup (#1013)
* Edit config on Setup

* Default to 1TiB storage space and 500GiB bandwidth

* Use human readable formats

* Use memory

* units of 1024 are measured with KiB/MiB etc

* pkg/cfgstruct: allow values to be configured with human readable sizes

Change-Id: Ic4e9ae461516d1d26fb81f6e44c5ac5cfccf777f

* Modify tests

* Removed comments

* More merge conflict stuff resolved

* Fix lint

* test fixin

Change-Id: I3a008206bf03a4446da19f642a2f9c1f9acaae36

* Remove commented code but secretly leave it in the histroy forever

* Move flag definition to struct
2019-01-14 16:19:15 -05:00

136 lines
2.9 KiB
Go

// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package memory
import (
"errors"
"fmt"
"strconv"
"strings"
)
// different sizes
const (
B Size = 1 << (10 * iota)
KB
MB
GB
TB
PB
EB
)
// Size implements flag.Value for collecting memory size in bytes
type Size int64
// Int returns bytes size as int
func (size Size) Int() int { return int(size) }
// Int32 returns bytes size as int32
func (size Size) Int32() int32 { return int32(size) }
// Int64 returns bytes size as int64
func (size Size) Int64() int64 { return int64(size) }
// Float64 returns bytes size as float64
func (size Size) Float64() float64 { return float64(size) }
// KB returns size in kilobytes
func (size Size) KB() float64 { return size.Float64() / KB.Float64() }
// MB returns size in megabytes
func (size Size) MB() float64 { return size.Float64() / MB.Float64() }
// GB returns size in gigabytes
func (size Size) GB() float64 { return size.Float64() / GB.Float64() }
// TB returns size in terabytes
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
func (size Size) EB() float64 { return size.Float64() / EB.Float64() }
// String converts size to a string
func (size Size) String() string {
if size == 0 {
return "0"
}
switch {
case size >= EB*2/3:
return fmt.Sprintf("%.1f EB", size.EB())
case size >= PB*2/3:
return fmt.Sprintf("%.1f PB", size.PB())
case size >= TB*2/3:
return fmt.Sprintf("%.1f TB", size.TB())
case size >= GB*2/3:
return fmt.Sprintf("%.1f GB", size.GB())
case size >= MB*2/3:
return fmt.Sprintf("%.1f MB", size.MB())
case size >= KB*2/3:
return fmt.Sprintf("%.1f KB", size.KB())
}
return strconv.Itoa(size.Int()) + " B"
}
func isLetter(b byte) bool {
return ('a' <= b && b <= 'z') || ('A' <= b && b <= 'Z')
}
// Set updates value from string
func (size *Size) Set(s string) error {
if s == "" {
return errors.New("empty size")
}
p := len(s)
for isLetter(s[p-1]) {
p--
if p < 0 {
return errors.New("p out of bounds")
}
}
value, suffix := s[:p], s[p:]
suffix = strings.ToUpper(suffix)
if suffix == "" || suffix[len(suffix)-1] != 'B' {
suffix += "B"
}
value = strings.TrimSpace(value)
v, err := strconv.ParseFloat(value, 64)
if err != nil {
return err
}
switch suffix {
case "EB", "EIB":
*size = Size(v * EB.Float64())
case "PB", "PIB":
*size = Size(v * PB.Float64())
case "TB", "TIB":
*size = Size(v * TB.Float64())
case "GB", "GIB":
*size = Size(v * GB.Float64())
case "MB", "MIB":
*size = Size(v * MB.Float64())
case "KB", "KIB":
*size = Size(v * KB.Float64())
case "B", "":
*size = Size(v)
default:
return fmt.Errorf("unknown suffix %q", suffix)
}
return nil
}
// Type implements pflag.Value
func (Size) Type() string { return "memory.Size" }