Documentation
¶
Index ¶
- Constants
- Variables
- type CanonicalValue
- type Format
- type Quantity
- func MustParse(str string) Quantity
- func NewDecimalQuantity(b inf.Dec, format Format) *Quantity
- func NewMilliQuantity(value int64, format Format) *Quantity
- func NewQuantity(value int64, format Format) *Quantity
- func NewScaledQuantity(value int64, scale Scale) *Quantity
- func ParseQuantity(str string) (Quantity, error)
- func (q *Quantity) AsApproximateFloat64() float64
- func (q *Quantity) AsCanonicalBytes(out []byte) (result []byte, exponent int32)
- func (q *Quantity) AsDec() *inf.Dec
- func (q *Quantity) AsInt64() (int64, bool)
- func (q *Quantity) AsScale(scale Scale) (CanonicalValue, bool)
- func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte)
- func (q *Quantity) Cmp(y Quantity) int
- func (q *Quantity) CmpInt64(y int64) int
- func (q Quantity) DeepCopy() Quantity
- func (q *Quantity) IsZero() bool
- func (q Quantity) MarshalJSON() ([]byte, error)
- func (q *Quantity) MilliValue() int64
- func (q *Quantity) ScaledValue(scale Scale) int64
- func (q *Quantity) Set(value int64)
- func (q *Quantity) SetMilli(value int64)
- func (q *Quantity) SetScaled(value int64, scale Scale)
- func (q *Quantity) String() string
- func (q *Quantity) ToDec() *Quantity
- func (q Quantity) ToUnstructured() interface{}
- func (q *Quantity) UnmarshalJSON(value []byte) error
- func (q *Quantity) Value() int64
- type Scale
Constants ¶
const ( DecimalExponent = Format("DecimalExponent") // e.g., 12e6 BinarySI = Format("BinarySI") // e.g., 12Mi (12 * 2^20) DecimalSI = Format("DecimalSI") // e.g., 12M (12 * 10^6) )
Variables ¶
var ( // Errors that could happen while parsing a string. ErrFormatWrong = errors.New("quantities must match the regular expression '" + splitREString + "'") ErrNumeric = errors.New("unable to parse numeric part of quantity") ErrSuffix = errors.New("unable to parse quantity's suffix") )
var (
Zero = int64Amount{}
)
Functions ¶
This section is empty.
Types ¶
type CanonicalValue ¶
type CanonicalValue interface { // AsCanonicalBytes returns a byte array representing the string representation // of the value mantissa and an int32 representing its exponent in base-10. Callers may // pass a byte slice to the method to avoid allocations. AsCanonicalBytes(out []byte) ([]byte, int32) // AsCanonicalBase1024Bytes returns a byte array representing the string representation // of the value mantissa and an int32 representing its exponent in base-1024. Callers // may pass a byte slice to the method to avoid allocations. AsCanonicalBase1024Bytes(out []byte) ([]byte, int32) }
CanonicalValue allows a quantity amount to be converted to a string.
type Quantity ¶
type Quantity struct { // Change Format at will. See the comment for Canonicalize for // more details. Format // contains filtered or unexported fields }
Quantity is a fixed-point representation of a number. It provides convenient marshalling/unmarshalling in JSON and YAML, in addition to String() and AsInt64() accessors.
The serialization format is:
<quantity> ::= <signedNumber><suffix>
(Note that <suffix> may be empty, from the "" case in <decimalSI>.)
<digit> ::= 0 | 1 | ... | 9 <digits> ::= <digit> | <digit><digits> <number> ::= <digits> | <digits>.<digits> | <digits>. | .<digits> <sign> ::= "+" | "-" <signedNumber> ::= <number> | <sign><number> <suffix> ::= <binarySI> | <decimalExponent> | <decimalSI> <binarySI> ::= Ki | Mi | Gi | Ti | Pi | Ei
(International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)
<decimalSI> ::= m | "" | k | M | G | T | P | E
(Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
<decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
No matter which of the three exponent forms is used, no quantity may represent a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal places. Numbers larger or more precise will be capped or rounded up. (E.g.: 0.1m will rounded up to 1m.) This may be extended in the future if we require larger or smaller quantities.
When a Quantity is parsed from a string, it will remember the type of suffix it had, and will use the same type again when it is serialized.
Before serializing, Quantity will be put in "canonical form". This means that Exponent/suffix will be adjusted up or down (with a corresponding increase or decrease in Mantissa) such that:
a. No precision is lost b. No fractional digits will be emitted c. The exponent (or suffix) is as large as possible.
The sign will be omitted unless the number is negative.
Examples:
1.5 will be serialized as "1500m" 1.5Gi will be serialized as "1536Mi"
Note that the quantity will NEVER be internally represented by a floating point number. That is the whole point of this exercise.
Non-canonical values will still parse as long as they are well formed, but will be re-emitted in their canonical form. (So always use canonical form, or don't diff.)
This format is intended to make it difficult to use these numbers without writing some sort of special handling code in the hopes that that will cause implementors to also use a fixed point implementation.
+protobuf=true +protobuf.embed=string +protobuf.options.marshal=false +protobuf.options.(gogoproto.goproto_stringer)=false +k8s:deepcopy-gen=true +k8s:openapi-gen=true
func MustParse ¶
MustParse turns the given string into a quantity or panics; for tests or other cases where you know the string is valid.
func NewDecimalQuantity ¶
NewDecimalQuantity returns a new Quantity representing the given value in the given format.
func NewMilliQuantity ¶
NewMilliQuantity returns a new Quantity representing the given value * 1/1000 in the given format. Note that BinarySI formatting will round fractional values, and will be changed to DecimalSI for values x where (-1 < x < 1) && (x != 0).
func NewQuantity ¶
NewQuantity returns a new Quantity representing the given value in the given format.
func NewScaledQuantity ¶
NewScaledQuantity returns a new Quantity representing the given value * 10^scale in DecimalSI format.
func ParseQuantity ¶
ParseQuantity turns str into a Quantity, or returns an error.
func (*Quantity) AsApproximateFloat64 ¶
AsApproximateFloat64 returns a float64 representation of the quantity which may lose precision. If the value of the quantity is outside the range of a float64 +Inf/-Inf will be returned.
func (*Quantity) AsCanonicalBytes ¶
AsCanonicalBytes returns the canonical byte representation of this quantity as a mantissa and base 10 exponent. The out byte slice may be passed to the method to avoid an extra allocation.
func (*Quantity) AsInt64 ¶
AsInt64 returns a representation of the current value as an int64 if a fast conversion is possible. If false is returned, callers must use the inf.Dec form of this quantity.
func (*Quantity) AsScale ¶
func (q *Quantity) AsScale(scale Scale) (CanonicalValue, bool)
AsScale returns the current value, rounded up to the provided scale, and returns false if the scale resulted in a loss of precision.
func (*Quantity) CanonicalizeBytes ¶
CanonicalizeBytes returns the canonical form of q and its suffix (see comment on Quantity).
Note about BinarySI:
- If q.Format is set to BinarySI and q.Amount represents a non-zero value between -1 and +1, it will be emitted as if q.Format were DecimalSI.
- Otherwise, if q.Format is set to BinarySI, fractional parts of q.Amount will be rounded up. (1.1i becomes 2i.)
func (*Quantity) Cmp ¶
Cmp returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the quantity is greater than y.
func (*Quantity) CmpInt64 ¶
CmpInt64 returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the quantity is greater than y.
func (Quantity) DeepCopy ¶
DeepCopy returns a deep-copy of the Quantity value. Note that the method receiver is a value, so we can mutate it in-place and return it.
func (Quantity) MarshalJSON ¶
MarshalJSON implements the json.Marshaller interface.
func (*Quantity) MilliValue ¶
MilliValue returns the value of ceil(q * 1000); this could overflow an int64; if that's a concern, call Value() first to verify the number is small enough.
func (*Quantity) ScaledValue ¶
ScaledValue returns the value of ceil(q / 10^scale). For example, NewQuantity(1, DecimalSI).ScaledValue(Milli) returns 1000. This could overflow an int64. To detect overflow, call Value() first and verify the expected magnitude.
func (*Quantity) String ¶
String formats the Quantity as a string, caching the result if not calculated. String is an expensive operation and caching this result significantly reduces the cost of normal parse / marshal operations on Quantity.
func (*Quantity) ToDec ¶
ToDec promotes the quantity in place to use an inf.Dec representation and returns itself.
func (Quantity) ToUnstructured ¶
func (q Quantity) ToUnstructured() interface{}
ToUnstructured implements the value.UnstructuredConverter interface.
func (*Quantity) UnmarshalJSON ¶
UnmarshalJSON implements the json.Unmarshaller interface. TODO: Remove support for leading/trailing whitespace