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") // The maximum value we can represent milli-units for. // Compare with the return value of Quantity.Value() to // see if it's safe to use Quantity.MilliValue(). MaxMilliValue = int64(((1 << 63) - 1) / 1000) )
NewQuantityFlagValue returns an object that can be used to back a flag, pointing at the given Quantity variable.
Format lists the three possible formattings of a quantity.
memorySize := resource.NewQuantity(5*1024*1024*1024, resource.BinarySI) fmt.Printf("memorySize = %v\n", memorySize) diskSize := resource.NewQuantity(5*1000*1000*1000, resource.DecimalSI) fmt.Printf("diskSize = %v\n", diskSize) cores := resource.NewMilliQuantity(5300, resource.DecimalSI) fmt.Printf("cores = %v\n", cores)
memorySize = 5Gi diskSize = 5G cores = 5300m
Quantity is a fixed-point representation of a number. It provides convenient marshaling/unmarshaling in JSON and YAML, in addition to String() and Int64() 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.
1.5 will be serialized as "1500m" 1.5Gi will be serialized as "1536Mi"
NOTE: We reserve the right to amend this canonical format, perhaps to
allow 1.5 to be canonical.
TODO: Remove above disclaimer after all bikeshedding about format is over,
or after March 2015.
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.
MustParse turns the given string into a quantity or panics; for tests or others cases where you know the string is valid.
memorySize := resource.MustParse("5Gi") fmt.Printf("memorySize = %v (%v)\n", memorySize.Value(), memorySize.Format) diskSize := resource.MustParse("5G") fmt.Printf("diskSize = %v (%v)\n", diskSize.Value(), diskSize.Format) cores := resource.MustParse("5300m") fmt.Printf("milliCores = %v (%v)\n", cores.MilliValue(), cores.Format) cores2 := resource.MustParse("5.4") fmt.Printf("milliCores = %v (%v)\n", cores2.MilliValue(), cores2.Format)
memorySize = 5368709120 (BinarySI) diskSize = 5000000000 (DecimalSI) milliCores = 5300 (DecimalSI) milliCores = 5400 (DecimalSI)
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).
NewQuantity returns a new Quantity representing the given value in the given format.
ParseQuantity turns str into a Quantity, or returns an error.
QuantityFlag is a helper that makes a quantity flag (using standard flag package). Will panic if defaultValue is not a valid quantity.
Canonicalize 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, frational parts of q.Amount will be
rounded up. (1.1i becomes 2i.)
Copy is a convenience function that makes a deep copy for you. Non-deep copies of quantities share pointers and you will regret that.
MarshalJSON implements the json.Marshaller interface.
MilliValue returns the value of q * 1000; this could overflow an int64; if that's a concern, call Value() first to verify the number is small enough.
Set sets q's value to be value.
SetMilli sets q's value to be value * 1/1000.
String formats the Quantity as a string.
UnmarshalJSON implements the json.Unmarshaller interface.
Value returns the value of q; any fractional part will be lost.