diff --git a/pkg/units/size.go b/pkg/units/size.go index 027886e5f3..50e8ec6c81 100644 --- a/pkg/units/size.go +++ b/pkg/units/size.go @@ -7,6 +7,11 @@ import ( "strings" ) +const ( + decimalKUnit = 1000 + binaryKUnit = 1024 +) + var sizeRegex *regexp.Regexp func init() { @@ -30,9 +35,23 @@ func HumanSize(size int64) string { return fmt.Sprintf("%.4g %s", sizef, bytePrefixes[i]) } -// FromHumanSize returns an integer from a human-readable specification of a size -// using SI standard (eg. "44kB", "17MB") +// FromHumanSize returns an integer from a human-readable specification of a +// size using SI standard (eg. "44kB", "17MB") func FromHumanSize(size string) (int64, error) { + return parseSize(size, decimalKUnit) +} + +// Parses a human-readable string representing an amount of RAM +// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and +// returns the number of bytes, or -1 if the string is unparseable. +// Units are case-insensitive, and the 'b' suffix is optional. +func RAMInBytes(size string) (int64, error) { + return parseSize(size, binaryKUnit) +} + +// Parses the human-readable size string into the amount it represents given +// the desired kilo unit [decimalKiloUnit=1000|binaryKiloUnit=1024] +func parseSize(size string, kUnit int64) (int64, error) { matches := sizeRegex.FindStringSubmatch(size) if len(matches) != 3 { @@ -44,54 +63,20 @@ func FromHumanSize(size string) (int64, error) { return -1, err } - unit := strings.ToLower(matches[2]) + unitPrefix := strings.ToLower(matches[2]) - switch unit { + switch unitPrefix { case "k": - theSize *= 1000 + theSize *= kUnit case "m": - theSize *= 1000 * 1000 + theSize *= kUnit * kUnit case "g": - theSize *= 1000 * 1000 * 1000 + theSize *= kUnit * kUnit * kUnit case "t": - theSize *= 1000 * 1000 * 1000 * 1000 + theSize *= kUnit * kUnit * kUnit * kUnit case "p": - theSize *= 1000 * 1000 * 1000 * 1000 * 1000 + theSize *= kUnit * kUnit * kUnit * kUnit * kUnit } return theSize, nil } - -// Parses a human-readable string representing an amount of RAM -// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and -// returns the number of bytes, or -1 if the string is unparseable. -// Units are case-insensitive, and the 'b' suffix is optional. -func RAMInBytes(size string) (int64, error) { - matches := sizeRegex.FindStringSubmatch(size) - - if len(matches) != 3 { - return -1, fmt.Errorf("Invalid size: '%s'", size) - } - - memLimit, err := strconv.ParseInt(matches[1], 10, 0) - if err != nil { - return -1, err - } - - unit := strings.ToLower(matches[2]) - - switch unit { - case "k": - memLimit *= 1024 - case "m": - memLimit *= 1024 * 1024 - case "g": - memLimit *= 1024 * 1024 * 1024 - case "t": - memLimit *= 1024 * 1024 * 1024 * 1024 - case "p": - memLimit *= 1024 * 1024 * 1024 * 1024 * 1024 - } - - return memLimit, nil -}