// Copyright 2019 The LevelDB-Go and Pebble Authors. All rights reserved. Use // of this source code is governed by a BSD-style license that can be found in // the LICENSE file. package humanize import ( "fmt" "math" "github.com/cockroachdb/redact" ) func logn(n, b float64) float64 { return math.Log(n) / math.Log(b) } func humanate(s uint64, base float64, suffixes []string) string { if s < 10 { return fmt.Sprintf("%d%s", s, suffixes[0]) } e := math.Floor(logn(float64(s), base)) suffix := suffixes[int(e)] val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10 f := "%.0f%s" if val < 10 { f = "%.1f%s" } return fmt.Sprintf(f, val, suffix) } type config struct { base float64 suffix []string } // Bytes produces human readable representations of byte values in IEC units. var Bytes = config{1024, []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"}} // Count produces human readable representations of unitless values in SI units. var Count = config{1000, []string{"", "K", "M", "G", "T", "P", "E"}} // Int64 produces a human readable representation of the value. func (c *config) Int64(s int64) FormattedString { if s < 0 { return FormattedString("-" + humanate(uint64(-s), c.base, c.suffix)) } return FormattedString(humanate(uint64(s), c.base, c.suffix)) } // Uint64 produces a human readable representation of the value. func (c *config) Uint64(s uint64) FormattedString { return FormattedString(humanate(s, c.base, c.suffix)) } // FormattedString represents a human readable representation of a value. It // implements the redact.SafeValue interface to signal that it represents a // a string that does not need to be redacted. type FormattedString string var _ redact.SafeValue = FormattedString("") // SafeValue implements redact.SafeValue. func (fs FormattedString) SafeValue() {} // String implements fmt.Stringer. func (fs FormattedString) String() string { return string(fs) }