mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +00:00
Merge pull request #25243 from smarterclayton/explore_quantity
Provide an int64 version of Quantity that is much faster
This commit is contained in:
commit
5448400b1c
@ -927,10 +927,10 @@ func parseResourceList(m utilconfig.ConfigurationMap) (api.ResourceList, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if q.Amount.Sign() == -1 {
|
if q.Sign() == -1 {
|
||||||
return nil, fmt.Errorf("resource quantity for %q cannot be negative: %v", k, v)
|
return nil, fmt.Errorf("resource quantity for %q cannot be negative: %v", k, v)
|
||||||
}
|
}
|
||||||
rl[api.ResourceName(k)] = *q
|
rl[api.ResourceName(k)] = q
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("cannot reserve %q resource", k)
|
return nil, fmt.Errorf("cannot reserve %q resource", k)
|
||||||
}
|
}
|
||||||
|
@ -85,14 +85,8 @@ func podResources(pod *api.Pod, resourceName api.ResourceName, def, min resource
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add up the request and limit sum for all containers
|
// add up the request and limit sum for all containers
|
||||||
err = requestSum.Add(request)
|
requestSum.Add(request)
|
||||||
if err != nil {
|
limitSum.Add(limit)
|
||||||
return
|
|
||||||
}
|
|
||||||
err = limitSum.Add(limit)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// optionally write request and limit back
|
// optionally write request and limit back
|
||||||
if write {
|
if write {
|
||||||
|
@ -25,11 +25,10 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg4_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg1_api "k8s.io/kubernetes/pkg/api"
|
pkg1_api "k8s.io/kubernetes/pkg/api"
|
||||||
pkg3_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg3_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg2_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg2_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg5_types "k8s.io/kubernetes/pkg/types"
|
pkg4_types "k8s.io/kubernetes/pkg/types"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -65,13 +64,12 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg4_inf_v0.Dec
|
var v0 pkg1_api.ConditionStatus
|
||||||
var v1 pkg1_api.ConditionStatus
|
var v1 pkg3_resource.Quantity
|
||||||
var v2 pkg3_resource.Quantity
|
var v2 pkg2_unversioned.Time
|
||||||
var v3 pkg2_unversioned.Time
|
var v3 pkg4_types.UID
|
||||||
var v4 pkg5_types.UID
|
var v4 time.Time
|
||||||
var v5 time.Time
|
_, _, _, _, _ = v0, v1, v2, v3, v4
|
||||||
_, _, _, _, _, _ = v0, v1, v2, v3, v4, v5
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,11 +25,10 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg4_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg3_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg3_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg2_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg2_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg1_v1 "k8s.io/kubernetes/pkg/api/v1"
|
pkg1_v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||||
pkg5_types "k8s.io/kubernetes/pkg/types"
|
pkg4_types "k8s.io/kubernetes/pkg/types"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -65,13 +64,12 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg4_inf_v0.Dec
|
var v0 pkg3_resource.Quantity
|
||||||
var v1 pkg3_resource.Quantity
|
var v1 pkg2_unversioned.Time
|
||||||
var v2 pkg2_unversioned.Time
|
var v2 pkg1_v1.ConditionStatus
|
||||||
var v3 pkg1_v1.ConditionStatus
|
var v3 pkg4_types.UID
|
||||||
var v4 pkg5_types.UID
|
var v4 time.Time
|
||||||
var v5 time.Time
|
_, _, _, _, _ = v0, v1, v2, v3, v4
|
||||||
_, _, _, _, _, _ = v0, v1, v2, v3, v4, v5
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ else
|
|||||||
linux/amd64
|
linux/amd64
|
||||||
linux/arm
|
linux/arm
|
||||||
linux/arm64
|
linux/arm64
|
||||||
linux/ppc64le
|
#linux/ppc64le # temporarily disabled due to a linking error
|
||||||
)
|
)
|
||||||
|
|
||||||
# If we update this we should also update the set of golang compilers we build
|
# If we update this we should also update the set of golang compilers we build
|
||||||
@ -78,7 +78,7 @@ else
|
|||||||
linux/386
|
linux/386
|
||||||
linux/arm
|
linux/arm
|
||||||
linux/arm64
|
linux/arm64
|
||||||
linux/ppc64le
|
#linux/ppc64le # temporarily disabled due to a linking error
|
||||||
darwin/amd64
|
darwin/amd64
|
||||||
darwin/386
|
darwin/386
|
||||||
windows/amd64
|
windows/amd64
|
||||||
|
@ -58,16 +58,7 @@ var Semantic = conversion.EqualitiesOrDie(
|
|||||||
// TODO: if we decide it's important, it should be safe to start comparing the format.
|
// TODO: if we decide it's important, it should be safe to start comparing the format.
|
||||||
//
|
//
|
||||||
// Uninitialized quantities are equivalent to 0 quantities.
|
// Uninitialized quantities are equivalent to 0 quantities.
|
||||||
if a.Amount == nil && b.MilliValue() == 0 {
|
return a.Cmp(b) == 0
|
||||||
return true
|
|
||||||
}
|
|
||||||
if b.Amount == nil && a.MilliValue() == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if a.Amount == nil || b.Amount == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return a.Amount.Cmp(b.Amount) == 0
|
|
||||||
},
|
},
|
||||||
func(a, b unversioned.Time) bool {
|
func(a, b unversioned.Time) bool {
|
||||||
return a.UTC() == b.UTC()
|
return a.UTC() == b.UTC()
|
||||||
|
@ -23,8 +23,6 @@ import (
|
|||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
|
|
||||||
inf "gopkg.in/inf.v0"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestConversionError(t *testing.T) {
|
func TestConversionError(t *testing.T) {
|
||||||
@ -56,8 +54,8 @@ func TestSemantic(t *testing.T) {
|
|||||||
{resource.Quantity{}, resource.MustParse("0"), true},
|
{resource.Quantity{}, resource.MustParse("0"), true},
|
||||||
{resource.Quantity{}, resource.MustParse("1m"), false},
|
{resource.Quantity{}, resource.MustParse("1m"), false},
|
||||||
{
|
{
|
||||||
resource.Quantity{Amount: inf.NewDec(5, 0), Format: resource.BinarySI},
|
resource.NewQuantity(5, resource.BinarySI),
|
||||||
resource.Quantity{Amount: inf.NewDec(5, 0), Format: resource.DecimalSI},
|
resource.NewQuantity(5, resource.DecimalSI),
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{resource.MustParse("2m"), resource.MustParse("1m"), false},
|
{resource.MustParse("2m"), resource.MustParse("1m"), false},
|
||||||
|
298
pkg/api/resource/amount.go
Normal file
298
pkg/api/resource/amount.go
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
inf "gopkg.in/inf.v0"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Scale is used for getting and setting the base-10 scaled value.
|
||||||
|
// Base-2 scales are omitted for mathematical simplicity.
|
||||||
|
// See Quantity.ScaledValue for more details.
|
||||||
|
type Scale int32
|
||||||
|
|
||||||
|
// infScale adapts a Scale value to an inf.Scale value.
|
||||||
|
func (s Scale) infScale() inf.Scale {
|
||||||
|
return inf.Scale(-s) // inf.Scale is upside-down
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
Nano Scale = -9
|
||||||
|
Micro Scale = -6
|
||||||
|
Milli Scale = -3
|
||||||
|
Kilo Scale = 3
|
||||||
|
Mega Scale = 6
|
||||||
|
Giga Scale = 9
|
||||||
|
Tera Scale = 12
|
||||||
|
Peta Scale = 15
|
||||||
|
Exa Scale = 18
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Zero = int64Amount{}
|
||||||
|
|
||||||
|
// Used by quantity strings - treat as read only
|
||||||
|
zeroBytes = []byte("0")
|
||||||
|
)
|
||||||
|
|
||||||
|
// int64Amount represents a fixed precision numerator and arbitary scale exponent. It is faster
|
||||||
|
// than operations on inf.Dec for values that can be represented as int64.
|
||||||
|
type int64Amount struct {
|
||||||
|
value int64
|
||||||
|
scale Scale
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign returns 0 if the value is zero, -1 if it is less than 0, or 1 if it is greater than 0.
|
||||||
|
func (a int64Amount) Sign() int {
|
||||||
|
switch {
|
||||||
|
case a.value == 0:
|
||||||
|
return 0
|
||||||
|
case a.value > 0:
|
||||||
|
return 1
|
||||||
|
default:
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsInt64 returns the current amount as an int64 at scale 0, or false if the value cannot be
|
||||||
|
// represented in an int64 OR would result in a loss of precision. This method is intended as
|
||||||
|
// an optimization to avoid calling AsDec.
|
||||||
|
func (a int64Amount) AsInt64() (int64, bool) {
|
||||||
|
if a.scale == 0 {
|
||||||
|
return a.value, true
|
||||||
|
}
|
||||||
|
if a.scale < 0 {
|
||||||
|
// TODO: attempt to reduce factors, although it is assumed that factors are reduced prior
|
||||||
|
// to the int64Amount being created.
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return positiveScaleInt64(a.value, a.scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsScaledInt64 returns an int64 representing the value of this amount at the specified scale,
|
||||||
|
// rounding up, or false if that would result in overflow. (1e20).AsScaledInt64(1) would result
|
||||||
|
// in overflow because 1e19 is not representable as an int64. Note that setting a scale larger
|
||||||
|
// than the current value may result in loss of precision - i.e. (1e-6).AsScaledInt64(0) would
|
||||||
|
// return 1, because 0.000001 is rounded up to 1.
|
||||||
|
func (a int64Amount) AsScaledInt64(scale Scale) (result int64, ok bool) {
|
||||||
|
if a.scale < scale {
|
||||||
|
result, _ = negativeScaleInt64(a.value, scale-a.scale)
|
||||||
|
return result, true
|
||||||
|
}
|
||||||
|
return positiveScaleInt64(a.value, a.scale-scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsDec returns an inf.Dec representation of this value.
|
||||||
|
func (a int64Amount) AsDec() *inf.Dec {
|
||||||
|
var base inf.Dec
|
||||||
|
base.SetUnscaled(a.value)
|
||||||
|
base.SetScale(inf.Scale(-a.scale))
|
||||||
|
return &base
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cmp returns 0 if a and b are equal, 1 if a is greater than b, or -1 if a is less than b.
|
||||||
|
func (a int64Amount) Cmp(b int64Amount) int {
|
||||||
|
switch {
|
||||||
|
case a.scale == b.scale:
|
||||||
|
// compare only the unscaled portion
|
||||||
|
case a.scale > b.scale:
|
||||||
|
result, remainder, exact := divideByScaleInt64(b.value, a.scale-b.scale)
|
||||||
|
if !exact {
|
||||||
|
return a.AsDec().Cmp(b.AsDec())
|
||||||
|
}
|
||||||
|
if result == a.value {
|
||||||
|
switch {
|
||||||
|
case remainder == 0:
|
||||||
|
return 0
|
||||||
|
case remainder > 0:
|
||||||
|
return -1
|
||||||
|
default:
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.value = result
|
||||||
|
default:
|
||||||
|
result, remainder, exact := divideByScaleInt64(a.value, b.scale-a.scale)
|
||||||
|
if !exact {
|
||||||
|
return a.AsDec().Cmp(b.AsDec())
|
||||||
|
}
|
||||||
|
if result == b.value {
|
||||||
|
switch {
|
||||||
|
case remainder == 0:
|
||||||
|
return 0
|
||||||
|
case remainder > 0:
|
||||||
|
return 1
|
||||||
|
default:
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a.value = result
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case a.value == b.value:
|
||||||
|
return 0
|
||||||
|
case a.value < b.value:
|
||||||
|
return -1
|
||||||
|
default:
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds two int64Amounts together, matching scales. It will return false and not mutate
|
||||||
|
// a if overflow or underflow would result.
|
||||||
|
func (a *int64Amount) Add(b int64Amount) bool {
|
||||||
|
switch {
|
||||||
|
case b.value == 0:
|
||||||
|
return true
|
||||||
|
case a.value == 0:
|
||||||
|
a.value = b.value
|
||||||
|
a.scale = b.scale
|
||||||
|
return true
|
||||||
|
case a.scale == b.scale:
|
||||||
|
c, ok := int64Add(a.value, b.value)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
a.value = c
|
||||||
|
case a.scale > b.scale:
|
||||||
|
c, ok := positiveScaleInt64(a.value, a.scale-b.scale)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c, ok = int64Add(c, b.value)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
a.scale = b.scale
|
||||||
|
a.value = c
|
||||||
|
default:
|
||||||
|
c, ok := positiveScaleInt64(b.value, b.scale-a.scale)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c, ok = int64Add(a.value, c)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
a.value = c
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub removes the value of b from the current amount, or returns false if underflow would result.
|
||||||
|
func (a *int64Amount) Sub(b int64Amount) bool {
|
||||||
|
return a.Add(int64Amount{value: -b.value, scale: b.scale})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision
|
||||||
|
// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6.
|
||||||
|
func (a int64Amount) AsScale(scale Scale) (int64Amount, bool) {
|
||||||
|
if a.scale >= scale {
|
||||||
|
return a, true
|
||||||
|
}
|
||||||
|
result, exact := negativeScaleInt64(a.value, scale-a.scale)
|
||||||
|
return int64Amount{value: result, scale: scale}, exact
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsCanonicalBytes accepts a buffer to write the base-10 string value of this field to, and returns
|
||||||
|
// either that buffer or a larger buffer and the current exponent of the value. The value is adjusted
|
||||||
|
// until the exponent is a multiple of 3 - i.e. 1.1e5 would return "110", 3.
|
||||||
|
func (a int64Amount) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
|
||||||
|
mantissa := a.value
|
||||||
|
exponent = int32(a.scale)
|
||||||
|
|
||||||
|
amount, times := removeInt64Factors(mantissa, 10)
|
||||||
|
exponent += int32(times)
|
||||||
|
|
||||||
|
// make sure exponent is a multiple of 3
|
||||||
|
var ok bool
|
||||||
|
switch exponent % 3 {
|
||||||
|
case 1, -2:
|
||||||
|
amount, ok = int64MultiplyScale10(amount)
|
||||||
|
if !ok {
|
||||||
|
return infDecAmount{a.AsDec()}.AsCanonicalBytes(out)
|
||||||
|
}
|
||||||
|
exponent = exponent - 1
|
||||||
|
case 2, -1:
|
||||||
|
amount, ok = int64MultiplyScale100(amount)
|
||||||
|
if !ok {
|
||||||
|
return infDecAmount{a.AsDec()}.AsCanonicalBytes(out)
|
||||||
|
}
|
||||||
|
exponent = exponent - 2
|
||||||
|
}
|
||||||
|
return strconv.AppendInt(out, amount, 10), exponent
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsCanonicalBase1024Bytes accepts a buffer to write the base-1024 string value of this field to, and returns
|
||||||
|
// either that buffer or a larger buffer and the current exponent of the value. 2048 is 2 * 1024 ^ 1 and would
|
||||||
|
// return []byte("2048"), 1.
|
||||||
|
func (a int64Amount) AsCanonicalBase1024Bytes(out []byte) (result []byte, exponent int32) {
|
||||||
|
value, ok := a.AsScaledInt64(0)
|
||||||
|
if !ok {
|
||||||
|
return infDecAmount{a.AsDec()}.AsCanonicalBase1024Bytes(out)
|
||||||
|
}
|
||||||
|
amount, exponent := removeInt64Factors(value, 1024)
|
||||||
|
return strconv.AppendInt(out, amount, 10), exponent
|
||||||
|
}
|
||||||
|
|
||||||
|
// infDecAmount implements common operations over an inf.Dec that are specific to the quantity
|
||||||
|
// representation.
|
||||||
|
type infDecAmount struct {
|
||||||
|
*inf.Dec
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision
|
||||||
|
// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6.
|
||||||
|
func (a infDecAmount) AsScale(scale Scale) (infDecAmount, bool) {
|
||||||
|
tmp := &inf.Dec{}
|
||||||
|
tmp.Round(a.Dec, scale.infScale(), inf.RoundUp)
|
||||||
|
return infDecAmount{tmp}, tmp.Cmp(a.Dec) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsCanonicalBytes accepts a buffer to write the base-10 string value of this field to, and returns
|
||||||
|
// either that buffer or a larger buffer and the current exponent of the value. The value is adjusted
|
||||||
|
// until the exponent is a multiple of 3 - i.e. 1.1e5 would return "110", 3.
|
||||||
|
func (a infDecAmount) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
|
||||||
|
mantissa := a.Dec.UnscaledBig()
|
||||||
|
exponent = int32(-a.Dec.Scale())
|
||||||
|
amount := big.NewInt(0).Set(mantissa)
|
||||||
|
// move all factors of 10 into the exponent for easy reasoning
|
||||||
|
amount, times := removeBigIntFactors(amount, bigTen)
|
||||||
|
exponent += times
|
||||||
|
|
||||||
|
// make sure exponent is a multiple of 3
|
||||||
|
for exponent%3 != 0 {
|
||||||
|
amount.Mul(amount, bigTen)
|
||||||
|
exponent--
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(out, amount.String()...), exponent
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsCanonicalBase1024Bytes accepts a buffer to write the base-1024 string value of this field to, and returns
|
||||||
|
// either that buffer or a larger buffer and the current exponent of the value. 2048 is 2 * 1024 ^ 1 and would
|
||||||
|
// return []byte("2048"), 1.
|
||||||
|
func (a infDecAmount) AsCanonicalBase1024Bytes(out []byte) (result []byte, exponent int32) {
|
||||||
|
tmp := &inf.Dec{}
|
||||||
|
tmp.Round(a.Dec, 0, inf.RoundUp)
|
||||||
|
amount, exponent := removeBigIntFactors(tmp.UnscaledBig(), big1024)
|
||||||
|
return append(out, amount.String()...), exponent
|
||||||
|
}
|
111
pkg/api/resource/amount_test.go
Normal file
111
pkg/api/resource/amount_test.go
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInt64AmountAsInt64(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
value int64
|
||||||
|
scale Scale
|
||||||
|
result int64
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{100, 0, 100, true},
|
||||||
|
{100, 1, 1000, true},
|
||||||
|
{100, -5, 0, false},
|
||||||
|
{100, 100, 0, false},
|
||||||
|
} {
|
||||||
|
r, ok := int64Amount{value: test.value, scale: test.scale}.AsInt64()
|
||||||
|
if r != test.result {
|
||||||
|
t.Errorf("%v: unexpected result: %d", test, r)
|
||||||
|
}
|
||||||
|
if ok != test.ok {
|
||||||
|
t.Errorf("%v: unexpected ok: %t", test, ok)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInt64AmountAdd(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
a, b, c int64Amount
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{int64Amount{value: 100, scale: 1}, int64Amount{value: 10, scale: 2}, int64Amount{value: 200, scale: 1}, true},
|
||||||
|
{int64Amount{value: 100, scale: 1}, int64Amount{value: 1, scale: 2}, int64Amount{value: 110, scale: 1}, true},
|
||||||
|
{int64Amount{value: 100, scale: 1}, int64Amount{value: 1, scale: 100}, int64Amount{value: 1, scale: 100}, false},
|
||||||
|
{int64Amount{value: -5, scale: 2}, int64Amount{value: 50, scale: 1}, int64Amount{value: 0, scale: 1}, true},
|
||||||
|
{int64Amount{value: -5, scale: 2}, int64Amount{value: 5, scale: 2}, int64Amount{value: 0, scale: 2}, true},
|
||||||
|
|
||||||
|
{int64Amount{value: mostPositive, scale: -1}, int64Amount{value: 1, scale: -1}, int64Amount{value: 0, scale: -1}, false},
|
||||||
|
{int64Amount{value: mostPositive, scale: -1}, int64Amount{value: 0, scale: -1}, int64Amount{value: mostPositive, scale: -1}, true},
|
||||||
|
{int64Amount{value: mostPositive / 10, scale: 1}, int64Amount{value: 10, scale: 0}, int64Amount{value: mostPositive, scale: -1}, false},
|
||||||
|
} {
|
||||||
|
c := test.a
|
||||||
|
ok := c.Add(test.b)
|
||||||
|
if ok != test.ok {
|
||||||
|
t.Errorf("%v: unexpected ok: %t", test, ok)
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
if c != test.c {
|
||||||
|
t.Errorf("%v: unexpected result: %d", test, c)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if c != test.a {
|
||||||
|
t.Errorf("%v: overflow addition mutated source: %d", test, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// addition is commutative
|
||||||
|
c = test.b
|
||||||
|
if ok := c.Add(test.a); ok != test.ok {
|
||||||
|
t.Errorf("%v: unexpected ok: %t", test, ok)
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
if c != test.c {
|
||||||
|
t.Errorf("%v: unexpected result: %d", test, c)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if c != test.b {
|
||||||
|
t.Errorf("%v: overflow addition mutated source: %d", test, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func TestInt64AsCanonicalString(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
value int64
|
||||||
|
scale Scale
|
||||||
|
result string
|
||||||
|
exponent int32
|
||||||
|
}{
|
||||||
|
{100, 0, "100", 0},
|
||||||
|
{100, 1, "1", 3},
|
||||||
|
{100, -1, "10", 0},
|
||||||
|
{10800, -10, "1080", -9},
|
||||||
|
} {
|
||||||
|
r, exp := int64Amount{value: test.value, scale: test.scale}.AsCanonicalBytes(nil)
|
||||||
|
if string(r) != test.result {
|
||||||
|
t.Errorf("%v: unexpected result: %s", test, r)
|
||||||
|
}
|
||||||
|
if exp != test.exponent {
|
||||||
|
t.Errorf("%v: unexpected exponent: %d", test, exp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,35 +21,27 @@ limitations under the License.
|
|||||||
package resource
|
package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
inf_v0 "gopkg.in/inf.v0"
|
|
||||||
conversion "k8s.io/kubernetes/pkg/conversion"
|
conversion "k8s.io/kubernetes/pkg/conversion"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DeepCopy_resource_Quantity(in Quantity, out *Quantity, c *conversion.Cloner) error {
|
func DeepCopy_resource_Quantity(in Quantity, out *Quantity, c *conversion.Cloner) error {
|
||||||
if in.Amount != nil {
|
if newVal, err := c.DeepCopy(in.i); err != nil {
|
||||||
in, out := in.Amount, &out.Amount
|
|
||||||
*out = new(inf_v0.Dec)
|
|
||||||
if newVal, err := c.DeepCopy(*in); err != nil {
|
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
**out = newVal.(inf_v0.Dec)
|
out.i = newVal.(int64Amount)
|
||||||
}
|
}
|
||||||
|
if newVal, err := c.DeepCopy(in.d); err != nil {
|
||||||
|
return err
|
||||||
} else {
|
} else {
|
||||||
out.Amount = nil
|
out.d = newVal.(infDecAmount)
|
||||||
}
|
}
|
||||||
out.Format = in.Format
|
if in.s != nil {
|
||||||
return nil
|
in, out := in.s, &out.s
|
||||||
}
|
|
||||||
|
|
||||||
func DeepCopy_resource_QuantityProto(in QuantityProto, out *QuantityProto, c *conversion.Cloner) error {
|
|
||||||
out.Format = in.Format
|
|
||||||
out.Scale = in.Scale
|
|
||||||
if in.Bigint != nil {
|
|
||||||
in, out := in.Bigint, &out.Bigint
|
|
||||||
*out = make([]byte, len(in))
|
*out = make([]byte, len(in))
|
||||||
copy(*out, in)
|
copy(*out, in)
|
||||||
} else {
|
} else {
|
||||||
out.Bigint = nil
|
out.s = nil
|
||||||
}
|
}
|
||||||
|
out.Format = in.Format
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ limitations under the License.
|
|||||||
|
|
||||||
It has these top-level messages:
|
It has these top-level messages:
|
||||||
Quantity
|
Quantity
|
||||||
QuantityProto
|
|
||||||
*/
|
*/
|
||||||
package resource
|
package resource
|
||||||
|
|
||||||
@ -34,8 +33,6 @@ import proto "github.com/gogo/protobuf/proto"
|
|||||||
import fmt "fmt"
|
import fmt "fmt"
|
||||||
import math "math"
|
import math "math"
|
||||||
|
|
||||||
import io "io"
|
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
var _ = proto.Marshal
|
var _ = proto.Marshal
|
||||||
var _ = fmt.Errorf
|
var _ = fmt.Errorf
|
||||||
@ -44,328 +41,6 @@ var _ = math.Inf
|
|||||||
func (m *Quantity) Reset() { *m = Quantity{} }
|
func (m *Quantity) Reset() { *m = Quantity{} }
|
||||||
func (*Quantity) ProtoMessage() {}
|
func (*Quantity) ProtoMessage() {}
|
||||||
|
|
||||||
func (m *QuantityProto) Reset() { *m = QuantityProto{} }
|
|
||||||
func (m *QuantityProto) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*QuantityProto) ProtoMessage() {}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
proto.RegisterType((*Quantity)(nil), "k8s.io.kubernetes.pkg.api.resource.Quantity")
|
proto.RegisterType((*Quantity)(nil), "k8s.io.kubernetes.pkg.api.resource.Quantity")
|
||||||
proto.RegisterType((*QuantityProto)(nil), "k8s.io.kubernetes.pkg.api.resource.QuantityProto")
|
|
||||||
}
|
}
|
||||||
func (m *QuantityProto) Marshal() (data []byte, err error) {
|
|
||||||
size := m.Size()
|
|
||||||
data = make([]byte, size)
|
|
||||||
n, err := m.MarshalTo(data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return data[:n], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *QuantityProto) MarshalTo(data []byte) (int, error) {
|
|
||||||
var i int
|
|
||||||
_ = i
|
|
||||||
var l int
|
|
||||||
_ = l
|
|
||||||
data[i] = 0xa
|
|
||||||
i++
|
|
||||||
i = encodeVarintGenerated(data, i, uint64(len(m.Format)))
|
|
||||||
i += copy(data[i:], m.Format)
|
|
||||||
data[i] = 0x10
|
|
||||||
i++
|
|
||||||
i = encodeVarintGenerated(data, i, uint64(m.Scale))
|
|
||||||
if m.Bigint != nil {
|
|
||||||
data[i] = 0x1a
|
|
||||||
i++
|
|
||||||
i = encodeVarintGenerated(data, i, uint64(len(m.Bigint)))
|
|
||||||
i += copy(data[i:], m.Bigint)
|
|
||||||
}
|
|
||||||
return i, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeFixed64Generated(data []byte, offset int, v uint64) int {
|
|
||||||
data[offset] = uint8(v)
|
|
||||||
data[offset+1] = uint8(v >> 8)
|
|
||||||
data[offset+2] = uint8(v >> 16)
|
|
||||||
data[offset+3] = uint8(v >> 24)
|
|
||||||
data[offset+4] = uint8(v >> 32)
|
|
||||||
data[offset+5] = uint8(v >> 40)
|
|
||||||
data[offset+6] = uint8(v >> 48)
|
|
||||||
data[offset+7] = uint8(v >> 56)
|
|
||||||
return offset + 8
|
|
||||||
}
|
|
||||||
func encodeFixed32Generated(data []byte, offset int, v uint32) int {
|
|
||||||
data[offset] = uint8(v)
|
|
||||||
data[offset+1] = uint8(v >> 8)
|
|
||||||
data[offset+2] = uint8(v >> 16)
|
|
||||||
data[offset+3] = uint8(v >> 24)
|
|
||||||
return offset + 4
|
|
||||||
}
|
|
||||||
func encodeVarintGenerated(data []byte, offset int, v uint64) int {
|
|
||||||
for v >= 1<<7 {
|
|
||||||
data[offset] = uint8(v&0x7f | 0x80)
|
|
||||||
v >>= 7
|
|
||||||
offset++
|
|
||||||
}
|
|
||||||
data[offset] = uint8(v)
|
|
||||||
return offset + 1
|
|
||||||
}
|
|
||||||
func (m *QuantityProto) Size() (n int) {
|
|
||||||
var l int
|
|
||||||
_ = l
|
|
||||||
l = len(m.Format)
|
|
||||||
n += 1 + l + sovGenerated(uint64(l))
|
|
||||||
n += 1 + sovGenerated(uint64(m.Scale))
|
|
||||||
if m.Bigint != nil {
|
|
||||||
l = len(m.Bigint)
|
|
||||||
n += 1 + l + sovGenerated(uint64(l))
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func sovGenerated(x uint64) (n int) {
|
|
||||||
for {
|
|
||||||
n++
|
|
||||||
x >>= 7
|
|
||||||
if x == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
func sozGenerated(x uint64) (n int) {
|
|
||||||
return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
|
||||||
}
|
|
||||||
func (m *QuantityProto) Unmarshal(data []byte) error {
|
|
||||||
l := len(data)
|
|
||||||
iNdEx := 0
|
|
||||||
for iNdEx < l {
|
|
||||||
preIndex := iNdEx
|
|
||||||
var wire uint64
|
|
||||||
for shift := uint(0); ; shift += 7 {
|
|
||||||
if shift >= 64 {
|
|
||||||
return ErrIntOverflowGenerated
|
|
||||||
}
|
|
||||||
if iNdEx >= l {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
b := data[iNdEx]
|
|
||||||
iNdEx++
|
|
||||||
wire |= (uint64(b) & 0x7F) << shift
|
|
||||||
if b < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fieldNum := int32(wire >> 3)
|
|
||||||
wireType := int(wire & 0x7)
|
|
||||||
if wireType == 4 {
|
|
||||||
return fmt.Errorf("proto: QuantityProto: wiretype end group for non-group")
|
|
||||||
}
|
|
||||||
if fieldNum <= 0 {
|
|
||||||
return fmt.Errorf("proto: QuantityProto: illegal tag %d (wire type %d)", fieldNum, wire)
|
|
||||||
}
|
|
||||||
switch fieldNum {
|
|
||||||
case 1:
|
|
||||||
if wireType != 2 {
|
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Format", wireType)
|
|
||||||
}
|
|
||||||
var stringLen uint64
|
|
||||||
for shift := uint(0); ; shift += 7 {
|
|
||||||
if shift >= 64 {
|
|
||||||
return ErrIntOverflowGenerated
|
|
||||||
}
|
|
||||||
if iNdEx >= l {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
b := data[iNdEx]
|
|
||||||
iNdEx++
|
|
||||||
stringLen |= (uint64(b) & 0x7F) << shift
|
|
||||||
if b < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
intStringLen := int(stringLen)
|
|
||||||
if intStringLen < 0 {
|
|
||||||
return ErrInvalidLengthGenerated
|
|
||||||
}
|
|
||||||
postIndex := iNdEx + intStringLen
|
|
||||||
if postIndex > l {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
m.Format = Format(data[iNdEx:postIndex])
|
|
||||||
iNdEx = postIndex
|
|
||||||
case 2:
|
|
||||||
if wireType != 0 {
|
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Scale", wireType)
|
|
||||||
}
|
|
||||||
m.Scale = 0
|
|
||||||
for shift := uint(0); ; shift += 7 {
|
|
||||||
if shift >= 64 {
|
|
||||||
return ErrIntOverflowGenerated
|
|
||||||
}
|
|
||||||
if iNdEx >= l {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
b := data[iNdEx]
|
|
||||||
iNdEx++
|
|
||||||
m.Scale |= (int32(b) & 0x7F) << shift
|
|
||||||
if b < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
if wireType != 2 {
|
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Bigint", wireType)
|
|
||||||
}
|
|
||||||
var byteLen int
|
|
||||||
for shift := uint(0); ; shift += 7 {
|
|
||||||
if shift >= 64 {
|
|
||||||
return ErrIntOverflowGenerated
|
|
||||||
}
|
|
||||||
if iNdEx >= l {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
b := data[iNdEx]
|
|
||||||
iNdEx++
|
|
||||||
byteLen |= (int(b) & 0x7F) << shift
|
|
||||||
if b < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if byteLen < 0 {
|
|
||||||
return ErrInvalidLengthGenerated
|
|
||||||
}
|
|
||||||
postIndex := iNdEx + byteLen
|
|
||||||
if postIndex > l {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
m.Bigint = append(m.Bigint[:0], data[iNdEx:postIndex]...)
|
|
||||||
if m.Bigint == nil {
|
|
||||||
m.Bigint = []byte{}
|
|
||||||
}
|
|
||||||
iNdEx = postIndex
|
|
||||||
default:
|
|
||||||
iNdEx = preIndex
|
|
||||||
skippy, err := skipGenerated(data[iNdEx:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if skippy < 0 {
|
|
||||||
return ErrInvalidLengthGenerated
|
|
||||||
}
|
|
||||||
if (iNdEx + skippy) > l {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
iNdEx += skippy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if iNdEx > l {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func skipGenerated(data []byte) (n int, err error) {
|
|
||||||
l := len(data)
|
|
||||||
iNdEx := 0
|
|
||||||
for iNdEx < l {
|
|
||||||
var wire uint64
|
|
||||||
for shift := uint(0); ; shift += 7 {
|
|
||||||
if shift >= 64 {
|
|
||||||
return 0, ErrIntOverflowGenerated
|
|
||||||
}
|
|
||||||
if iNdEx >= l {
|
|
||||||
return 0, io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
b := data[iNdEx]
|
|
||||||
iNdEx++
|
|
||||||
wire |= (uint64(b) & 0x7F) << shift
|
|
||||||
if b < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wireType := int(wire & 0x7)
|
|
||||||
switch wireType {
|
|
||||||
case 0:
|
|
||||||
for shift := uint(0); ; shift += 7 {
|
|
||||||
if shift >= 64 {
|
|
||||||
return 0, ErrIntOverflowGenerated
|
|
||||||
}
|
|
||||||
if iNdEx >= l {
|
|
||||||
return 0, io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
iNdEx++
|
|
||||||
if data[iNdEx-1] < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return iNdEx, nil
|
|
||||||
case 1:
|
|
||||||
iNdEx += 8
|
|
||||||
return iNdEx, nil
|
|
||||||
case 2:
|
|
||||||
var length int
|
|
||||||
for shift := uint(0); ; shift += 7 {
|
|
||||||
if shift >= 64 {
|
|
||||||
return 0, ErrIntOverflowGenerated
|
|
||||||
}
|
|
||||||
if iNdEx >= l {
|
|
||||||
return 0, io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
b := data[iNdEx]
|
|
||||||
iNdEx++
|
|
||||||
length |= (int(b) & 0x7F) << shift
|
|
||||||
if b < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iNdEx += length
|
|
||||||
if length < 0 {
|
|
||||||
return 0, ErrInvalidLengthGenerated
|
|
||||||
}
|
|
||||||
return iNdEx, nil
|
|
||||||
case 3:
|
|
||||||
for {
|
|
||||||
var innerWire uint64
|
|
||||||
var start int = iNdEx
|
|
||||||
for shift := uint(0); ; shift += 7 {
|
|
||||||
if shift >= 64 {
|
|
||||||
return 0, ErrIntOverflowGenerated
|
|
||||||
}
|
|
||||||
if iNdEx >= l {
|
|
||||||
return 0, io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
b := data[iNdEx]
|
|
||||||
iNdEx++
|
|
||||||
innerWire |= (uint64(b) & 0x7F) << shift
|
|
||||||
if b < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
innerWireType := int(innerWire & 0x7)
|
|
||||||
if innerWireType == 4 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
next, err := skipGenerated(data[start:])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
iNdEx = start + next
|
|
||||||
}
|
|
||||||
return iNdEx, nil
|
|
||||||
case 4:
|
|
||||||
return iNdEx, nil
|
|
||||||
case 5:
|
|
||||||
iNdEx += 4
|
|
||||||
return iNdEx, nil
|
|
||||||
default:
|
|
||||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
|
|
||||||
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
|
|
||||||
)
|
|
||||||
|
@ -84,26 +84,10 @@ option go_package = "resource";
|
|||||||
// cause implementors to also use a fixed point implementation.
|
// cause implementors to also use a fixed point implementation.
|
||||||
//
|
//
|
||||||
// +protobuf=true
|
// +protobuf=true
|
||||||
// +protobuf.embed=QuantityProto
|
// +protobuf.embed=string
|
||||||
// +protobuf.options.marshal=false
|
// +protobuf.options.marshal=false
|
||||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||||
message Quantity {
|
message Quantity {
|
||||||
optional QuantityProto QuantityProto = 1;
|
optional string string = 1;
|
||||||
}
|
|
||||||
|
|
||||||
// QuantityProto is a struct that is equivalent to Quantity, but intended for
|
|
||||||
// protobuf marshalling/unmarshalling. It is generated into a serialization
|
|
||||||
// that matches Quantity. Do not use in Go structs.
|
|
||||||
//
|
|
||||||
// +protobuf=true
|
|
||||||
message QuantityProto {
|
|
||||||
// The format of the quantity
|
|
||||||
optional string format = 1;
|
|
||||||
|
|
||||||
// The scale dimension of the value
|
|
||||||
optional int32 scale = 2;
|
|
||||||
|
|
||||||
// Bigint is serialized as a raw bytes array
|
|
||||||
optional bytes bigint = 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
327
pkg/api/resource/math.go
Normal file
327
pkg/api/resource/math.go
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
inf "gopkg.in/inf.v0"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// maxInt64Factors is the highest value that will be checked when removing factors of 10 from an int64.
|
||||||
|
// It is also the maximum decimal digits that can be represented with an int64.
|
||||||
|
maxInt64Factors = 18
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Commonly needed big.Int values-- treat as read only!
|
||||||
|
bigTen = big.NewInt(10)
|
||||||
|
bigZero = big.NewInt(0)
|
||||||
|
bigOne = big.NewInt(1)
|
||||||
|
bigThousand = big.NewInt(1000)
|
||||||
|
big1024 = big.NewInt(1024)
|
||||||
|
|
||||||
|
// Commonly needed inf.Dec values-- treat as read only!
|
||||||
|
decZero = inf.NewDec(0, 0)
|
||||||
|
decOne = inf.NewDec(1, 0)
|
||||||
|
decMinusOne = inf.NewDec(-1, 0)
|
||||||
|
decThousand = inf.NewDec(1000, 0)
|
||||||
|
dec1024 = inf.NewDec(1024, 0)
|
||||||
|
decMinus1024 = inf.NewDec(-1024, 0)
|
||||||
|
|
||||||
|
// Largest (in magnitude) number allowed.
|
||||||
|
maxAllowed = infDecAmount{inf.NewDec((1<<63)-1, 0)} // == max int64
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
)
|
||||||
|
|
||||||
|
const mostNegative = -(mostPositive + 1)
|
||||||
|
const mostPositive = 1<<63 - 1
|
||||||
|
|
||||||
|
// int64Add returns a+b, or false if that would overflow int64.
|
||||||
|
func int64Add(a, b int64) (int64, bool) {
|
||||||
|
c := a + b
|
||||||
|
switch {
|
||||||
|
case a > 0 && b > 0:
|
||||||
|
if c < 0 {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
case a < 0 && b < 0:
|
||||||
|
if c > 0 {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
if a == mostNegative && b == mostNegative {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// int64Multiply returns a*b, or false if that would overflow or underflow int64.
|
||||||
|
func int64Multiply(a, b int64) (int64, bool) {
|
||||||
|
if a == 0 || b == 0 || a == 1 || b == 1 {
|
||||||
|
return a * b, true
|
||||||
|
}
|
||||||
|
if a == mostNegative || b == mostNegative {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
c := a * b
|
||||||
|
return c, c/b == a
|
||||||
|
}
|
||||||
|
|
||||||
|
// int64MultiplyScale returns a*b, assuming b is greater than one, or false if that would overflow or underflow int64.
|
||||||
|
// Use when b is known to be greater than one.
|
||||||
|
func int64MultiplyScale(a int64, b int64) (int64, bool) {
|
||||||
|
if a == 0 || a == 1 {
|
||||||
|
return a * b, true
|
||||||
|
}
|
||||||
|
if a == mostNegative && b != 1 {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
c := a * b
|
||||||
|
return c, c/b == a
|
||||||
|
}
|
||||||
|
|
||||||
|
// int64MultiplyScale10 multiplies a by 10, or returns false if that would overflow. This method is faster than
|
||||||
|
// int64Multiply(a, 10) because the compiler can optimize constant factor multiplication.
|
||||||
|
func int64MultiplyScale10(a int64) (int64, bool) {
|
||||||
|
if a == 0 || a == 1 {
|
||||||
|
return a * 10, true
|
||||||
|
}
|
||||||
|
if a == mostNegative {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
c := a * 10
|
||||||
|
return c, c/10 == a
|
||||||
|
}
|
||||||
|
|
||||||
|
// int64MultiplyScale100 multiplies a by 100, or returns false if that would overflow. This method is faster than
|
||||||
|
// int64Multiply(a, 100) because the compiler can optimize constant factor multiplication.
|
||||||
|
func int64MultiplyScale100(a int64) (int64, bool) {
|
||||||
|
if a == 0 || a == 1 {
|
||||||
|
return a * 100, true
|
||||||
|
}
|
||||||
|
if a == mostNegative {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
c := a * 100
|
||||||
|
return c, c/100 == a
|
||||||
|
}
|
||||||
|
|
||||||
|
// int64MultiplyScale1000 multiplies a by 1000, or returns false if that would overflow. This method is faster than
|
||||||
|
// int64Multiply(a, 1000) because the compiler can optimize constant factor multiplication.
|
||||||
|
func int64MultiplyScale1000(a int64) (int64, bool) {
|
||||||
|
if a == 0 || a == 1 {
|
||||||
|
return a * 1000, true
|
||||||
|
}
|
||||||
|
if a == mostNegative {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
c := a * 1000
|
||||||
|
return c, c/1000 == a
|
||||||
|
}
|
||||||
|
|
||||||
|
// positiveScaleInt64 multiplies base by 10^scale, returning false if the
|
||||||
|
// value overflows. Passing a negative scale is undefined.
|
||||||
|
func positiveScaleInt64(base int64, scale Scale) (int64, bool) {
|
||||||
|
switch scale {
|
||||||
|
case 0:
|
||||||
|
return base, true
|
||||||
|
case 1:
|
||||||
|
return int64MultiplyScale10(base)
|
||||||
|
case 2:
|
||||||
|
return int64MultiplyScale100(base)
|
||||||
|
case 3:
|
||||||
|
return int64MultiplyScale1000(base)
|
||||||
|
case 6:
|
||||||
|
return int64MultiplyScale(base, 1000000)
|
||||||
|
case 9:
|
||||||
|
return int64MultiplyScale(base, 1000000000)
|
||||||
|
default:
|
||||||
|
value := base
|
||||||
|
var ok bool
|
||||||
|
for i := Scale(0); i < scale; i++ {
|
||||||
|
if value, ok = int64MultiplyScale(value, 10); !ok {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// negativeScaleInt64 reduces base by the provided scale, rounding up, until the
|
||||||
|
// value is zero or the scale is reached. Passing a negative scale is undefined.
|
||||||
|
// The value returned, if not exact, is rounded away from zero.
|
||||||
|
func negativeScaleInt64(base int64, scale Scale) (result int64, exact bool) {
|
||||||
|
if scale == 0 {
|
||||||
|
return base, true
|
||||||
|
}
|
||||||
|
|
||||||
|
value := base
|
||||||
|
var fraction bool
|
||||||
|
for i := Scale(0); i < scale; i++ {
|
||||||
|
if !fraction && value%10 != 0 {
|
||||||
|
fraction = true
|
||||||
|
}
|
||||||
|
value = value / 10
|
||||||
|
if value == 0 {
|
||||||
|
if fraction {
|
||||||
|
if base > 0 {
|
||||||
|
return 1, false
|
||||||
|
}
|
||||||
|
return -1, false
|
||||||
|
}
|
||||||
|
return 0, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if fraction {
|
||||||
|
if base > 0 {
|
||||||
|
value += 1
|
||||||
|
} else {
|
||||||
|
value += -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value, !fraction
|
||||||
|
}
|
||||||
|
|
||||||
|
func pow10Int64(b int64) int64 {
|
||||||
|
switch b {
|
||||||
|
case 0:
|
||||||
|
return 1
|
||||||
|
case 1:
|
||||||
|
return 10
|
||||||
|
case 2:
|
||||||
|
return 100
|
||||||
|
case 3:
|
||||||
|
return 1000
|
||||||
|
case 4:
|
||||||
|
return 10000
|
||||||
|
case 5:
|
||||||
|
return 100000
|
||||||
|
case 6:
|
||||||
|
return 1000000
|
||||||
|
case 7:
|
||||||
|
return 10000000
|
||||||
|
case 8:
|
||||||
|
return 100000000
|
||||||
|
case 9:
|
||||||
|
return 1000000000
|
||||||
|
case 10:
|
||||||
|
return 10000000000
|
||||||
|
case 11:
|
||||||
|
return 100000000000
|
||||||
|
case 12:
|
||||||
|
return 1000000000000
|
||||||
|
case 13:
|
||||||
|
return 10000000000000
|
||||||
|
case 14:
|
||||||
|
return 100000000000000
|
||||||
|
case 15:
|
||||||
|
return 1000000000000000
|
||||||
|
case 16:
|
||||||
|
return 10000000000000000
|
||||||
|
case 17:
|
||||||
|
return 100000000000000000
|
||||||
|
case 18:
|
||||||
|
return 1000000000000000000
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// powInt64 raises a to the bth power. Is not overflow aware.
|
||||||
|
func powInt64(a, b int64) int64 {
|
||||||
|
p := int64(1)
|
||||||
|
for b > 0 {
|
||||||
|
if b&1 != 0 {
|
||||||
|
p *= a
|
||||||
|
}
|
||||||
|
b >>= 1
|
||||||
|
a *= a
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// negativeScaleInt64 returns the result of dividing base by scale * 10 and the remainder, or
|
||||||
|
// false if no such division is possible. Dividing by negative scales is undefined.
|
||||||
|
func divideByScaleInt64(base int64, scale Scale) (result, remainder int64, exact bool) {
|
||||||
|
if scale == 0 {
|
||||||
|
return base, 0, true
|
||||||
|
}
|
||||||
|
// the max scale representable in base 10 in an int64 is 18 decimal places
|
||||||
|
if scale >= 18 {
|
||||||
|
return 0, base, false
|
||||||
|
}
|
||||||
|
divisor := pow10Int64(int64(scale))
|
||||||
|
return base / divisor, base % divisor, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeInt64Factors divides in a loop; the return values have the property that
|
||||||
|
// value == result * base ^ scale
|
||||||
|
func removeInt64Factors(value int64, base int64) (result int64, times int32) {
|
||||||
|
times = 0
|
||||||
|
result = value
|
||||||
|
negative := result < 0
|
||||||
|
if negative {
|
||||||
|
result = -result
|
||||||
|
}
|
||||||
|
switch base {
|
||||||
|
// allow the compiler to optimize the common cases
|
||||||
|
case 10:
|
||||||
|
for result >= 10 && result%10 == 0 {
|
||||||
|
times++
|
||||||
|
result = result / 10
|
||||||
|
}
|
||||||
|
// allow the compiler to optimize the common cases
|
||||||
|
case 1024:
|
||||||
|
for result >= 1024 && result%1024 == 0 {
|
||||||
|
times++
|
||||||
|
result = result / 1024
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
for result >= base && result%base == 0 {
|
||||||
|
times++
|
||||||
|
result = result / base
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if negative {
|
||||||
|
result = -result
|
||||||
|
}
|
||||||
|
return result, times
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeBigIntFactors divides in a loop; the return values have the property that
|
||||||
|
// d == result * factor ^ times
|
||||||
|
// d may be modified in place.
|
||||||
|
// If d == 0, then the return values will be (0, 0)
|
||||||
|
func removeBigIntFactors(d, factor *big.Int) (result *big.Int, times int32) {
|
||||||
|
q := big.NewInt(0)
|
||||||
|
m := big.NewInt(0)
|
||||||
|
for d.Cmp(bigZero) != 0 {
|
||||||
|
q.DivMod(d, factor, m)
|
||||||
|
if m.Cmp(bigZero) != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
times++
|
||||||
|
d, q = q, d
|
||||||
|
}
|
||||||
|
return d, times
|
||||||
|
}
|
211
pkg/api/resource/math_test.go
Normal file
211
pkg/api/resource/math_test.go
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDetectOverflowAdd(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
a, b int64
|
||||||
|
c int64
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{0, 0, 0, true},
|
||||||
|
{-1, 1, 0, true},
|
||||||
|
{0, 1, 1, true},
|
||||||
|
{2, 2, 4, true},
|
||||||
|
{2, -2, 0, true},
|
||||||
|
{-2, -2, -4, true},
|
||||||
|
|
||||||
|
{mostNegative, -1, 0, false},
|
||||||
|
{mostNegative, 1, mostNegative + 1, true},
|
||||||
|
{mostPositive, -1, mostPositive - 1, true},
|
||||||
|
{mostPositive, 1, 0, false},
|
||||||
|
|
||||||
|
{mostNegative, mostPositive, -1, true},
|
||||||
|
{mostPositive, mostNegative, -1, true},
|
||||||
|
{mostPositive, mostPositive, 0, false},
|
||||||
|
{mostNegative, mostNegative, 0, false},
|
||||||
|
|
||||||
|
{-mostPositive, mostNegative, 0, false},
|
||||||
|
{mostNegative, -mostPositive, 0, false},
|
||||||
|
{-mostPositive, -mostPositive, 0, false},
|
||||||
|
} {
|
||||||
|
c, ok := int64Add(test.a, test.b)
|
||||||
|
if c != test.c {
|
||||||
|
t.Errorf("%v: unexpected result: %d", test, c)
|
||||||
|
}
|
||||||
|
if ok != test.ok {
|
||||||
|
t.Errorf("%v: unexpected overflow: %t", test, ok)
|
||||||
|
}
|
||||||
|
// addition is commutative
|
||||||
|
d, ok2 := int64Add(test.b, test.a)
|
||||||
|
if c != d || ok != ok2 {
|
||||||
|
t.Errorf("%v: not commutative: %d %t", test, d, ok2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDetectOverflowMultiply(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
a, b int64
|
||||||
|
c int64
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{0, 0, 0, true},
|
||||||
|
{-1, 1, -1, true},
|
||||||
|
{-1, -1, 1, true},
|
||||||
|
{1, 1, 1, true},
|
||||||
|
{0, 1, 0, true},
|
||||||
|
{1, 0, 0, true},
|
||||||
|
{2, 2, 4, true},
|
||||||
|
{2, -2, -4, true},
|
||||||
|
{-2, -2, 4, true},
|
||||||
|
|
||||||
|
{mostNegative, -1, 0, false},
|
||||||
|
{mostNegative, 1, mostNegative, true},
|
||||||
|
{mostPositive, -1, -mostPositive, true},
|
||||||
|
{mostPositive, 1, mostPositive, true},
|
||||||
|
|
||||||
|
{mostNegative, mostPositive, 0, false},
|
||||||
|
{mostPositive, mostNegative, 0, false},
|
||||||
|
{mostPositive, mostPositive, 1, false},
|
||||||
|
{mostNegative, mostNegative, 0, false},
|
||||||
|
|
||||||
|
{-mostPositive, mostNegative, 0, false},
|
||||||
|
{mostNegative, -mostPositive, 0, false},
|
||||||
|
{-mostPositive, -mostPositive, 1, false},
|
||||||
|
} {
|
||||||
|
c, ok := int64Multiply(test.a, test.b)
|
||||||
|
if c != test.c {
|
||||||
|
t.Errorf("%v: unexpected result: %d", test, c)
|
||||||
|
}
|
||||||
|
if ok != test.ok {
|
||||||
|
t.Errorf("%v: unexpected overflow: %t", test, ok)
|
||||||
|
}
|
||||||
|
// multiplication is commutative
|
||||||
|
d, ok2 := int64Multiply(test.b, test.a)
|
||||||
|
if c != d || ok != ok2 {
|
||||||
|
t.Errorf("%v: not commutative: %d %t", test, d, ok2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDetectOverflowScale(t *testing.T) {
|
||||||
|
for _, a := range []int64{0, -1, 1, 10, -10, mostPositive, mostNegative, -mostPositive} {
|
||||||
|
for _, b := range []int64{1, 2, 10, 100, 1000, mostPositive} {
|
||||||
|
expect, expectOk := int64Multiply(a, b)
|
||||||
|
|
||||||
|
c, ok := int64MultiplyScale(a, b)
|
||||||
|
if c != expect {
|
||||||
|
t.Errorf("%d*%d: unexpected result: %d", a, b, c)
|
||||||
|
}
|
||||||
|
if ok != expectOk {
|
||||||
|
t.Errorf("%d*%d: unexpected overflow: %t", a, b, ok)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, test := range []struct {
|
||||||
|
base int64
|
||||||
|
fn func(a int64) (int64, bool)
|
||||||
|
}{
|
||||||
|
{10, int64MultiplyScale10},
|
||||||
|
{100, int64MultiplyScale100},
|
||||||
|
{1000, int64MultiplyScale1000},
|
||||||
|
} {
|
||||||
|
expect, expectOk := int64Multiply(a, test.base)
|
||||||
|
c, ok := test.fn(a)
|
||||||
|
if c != expect {
|
||||||
|
t.Errorf("%d*%d: unexpected result: %d", a, test.base, c)
|
||||||
|
}
|
||||||
|
if ok != expectOk {
|
||||||
|
t.Errorf("%d*%d: unexpected overflow: %t", a, test.base, ok)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoveInt64Factors(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
value int64
|
||||||
|
max int64
|
||||||
|
result int64
|
||||||
|
scale int32
|
||||||
|
}{
|
||||||
|
{100, 10, 1, 2},
|
||||||
|
{100, 10, 1, 2},
|
||||||
|
{100, 100, 1, 1},
|
||||||
|
{1, 10, 1, 0},
|
||||||
|
} {
|
||||||
|
r, s := removeInt64Factors(test.value, test.max)
|
||||||
|
if r != test.result {
|
||||||
|
t.Errorf("%v: unexpected result: %d", test, r)
|
||||||
|
}
|
||||||
|
if s != test.scale {
|
||||||
|
t.Errorf("%v: unexpected scale: %d", test, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNegativeScaleInt64(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
base int64
|
||||||
|
scale Scale
|
||||||
|
result int64
|
||||||
|
exact bool
|
||||||
|
}{
|
||||||
|
{1234567, 0, 1234567, true},
|
||||||
|
{1234567, 1, 123457, false},
|
||||||
|
{1234567, 2, 12346, false},
|
||||||
|
{1234567, 3, 1235, false},
|
||||||
|
{1234567, 4, 124, false},
|
||||||
|
|
||||||
|
{-1234567, 0, -1234567, true},
|
||||||
|
{-1234567, 1, -123457, false},
|
||||||
|
{-1234567, 2, -12346, false},
|
||||||
|
{-1234567, 3, -1235, false},
|
||||||
|
{-1234567, 4, -124, false},
|
||||||
|
|
||||||
|
{1000, 0, 1000, true},
|
||||||
|
{1000, 1, 100, true},
|
||||||
|
{1000, 2, 10, true},
|
||||||
|
{1000, 3, 1, true},
|
||||||
|
{1000, 4, 1, false},
|
||||||
|
|
||||||
|
{-1000, 0, -1000, true},
|
||||||
|
{-1000, 1, -100, true},
|
||||||
|
{-1000, 2, -10, true},
|
||||||
|
{-1000, 3, -1, true},
|
||||||
|
{-1000, 4, -1, false},
|
||||||
|
|
||||||
|
{0, 0, 0, true},
|
||||||
|
{0, 1, 0, true},
|
||||||
|
{0, 2, 0, true},
|
||||||
|
|
||||||
|
// negative scale is undefined behavior
|
||||||
|
{1000, -1, 1000, true},
|
||||||
|
} {
|
||||||
|
result, exact := negativeScaleInt64(test.base, test.scale)
|
||||||
|
if result != test.result {
|
||||||
|
t.Errorf("%v: unexpected result: %d", test, result)
|
||||||
|
}
|
||||||
|
if exact != test.exact {
|
||||||
|
t.Errorf("%v: unexpected exact: %t", test, exact)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,10 +17,12 @@ limitations under the License.
|
|||||||
package resource
|
package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
flag "github.com/spf13/pflag"
|
flag "github.com/spf13/pflag"
|
||||||
@ -86,19 +88,34 @@ import (
|
|||||||
// cause implementors to also use a fixed point implementation.
|
// cause implementors to also use a fixed point implementation.
|
||||||
//
|
//
|
||||||
// +protobuf=true
|
// +protobuf=true
|
||||||
// +protobuf.embed=QuantityProto
|
// +protobuf.embed=string
|
||||||
// +protobuf.options.marshal=false
|
// +protobuf.options.marshal=false
|
||||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||||
type Quantity struct {
|
type Quantity struct {
|
||||||
// Amount is public, so you can manipulate it if the accessor
|
// i is the quantity in int64 scaled form, if d.Dec == nil
|
||||||
// functions are not sufficient.
|
i int64Amount
|
||||||
Amount *inf.Dec
|
// d is the quantity in inf.Dec form if d.Dec != nil
|
||||||
|
d infDecAmount
|
||||||
|
// s is the generated value of this quantity to avoid recalculation
|
||||||
|
s []byte
|
||||||
|
|
||||||
// Change Format at will. See the comment for Canonicalize for
|
// Change Format at will. See the comment for Canonicalize for
|
||||||
// more details.
|
// more details.
|
||||||
Format
|
Format
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CanonicalValue allows a quantity amount to be converted to a string.
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
// Format lists the three possible formattings of a quantity.
|
// Format lists the three possible formattings of a quantity.
|
||||||
type Format string
|
type Format string
|
||||||
|
|
||||||
@ -115,26 +132,9 @@ func MustParse(str string) Quantity {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot parse '%v': %v", str, err))
|
panic(fmt.Errorf("cannot parse '%v': %v", str, err))
|
||||||
}
|
}
|
||||||
return *q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scale is used for getting and setting the base-10 scaled value.
|
|
||||||
// Base-2 scales are omitted for mathematical simplicity.
|
|
||||||
// See Quantity.ScaledValue for more details.
|
|
||||||
type Scale int
|
|
||||||
|
|
||||||
const (
|
|
||||||
Nano Scale = -9
|
|
||||||
Micro Scale = -6
|
|
||||||
Milli Scale = -3
|
|
||||||
Kilo Scale = 3
|
|
||||||
Mega Scale = 6
|
|
||||||
Giga Scale = 9
|
|
||||||
Tera Scale = 12
|
|
||||||
Peta Scale = 15
|
|
||||||
Exa Scale = 18
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// splitREString is used to separate a number from its suffix; as such,
|
// splitREString is used to separate a number from its suffix; as such,
|
||||||
// this is overly permissive, but that's OK-- it will be checked later.
|
// this is overly permissive, but that's OK-- it will be checked later.
|
||||||
@ -149,47 +149,189 @@ var (
|
|||||||
ErrFormatWrong = errors.New("quantities must match the regular expression '" + splitREString + "'")
|
ErrFormatWrong = errors.New("quantities must match the regular expression '" + splitREString + "'")
|
||||||
ErrNumeric = errors.New("unable to parse numeric part of quantity")
|
ErrNumeric = errors.New("unable to parse numeric part of quantity")
|
||||||
ErrSuffix = errors.New("unable to parse quantity's suffix")
|
ErrSuffix = errors.New("unable to parse quantity's suffix")
|
||||||
|
|
||||||
// Commonly needed big.Int values-- treat as read only!
|
|
||||||
bigTen = big.NewInt(10)
|
|
||||||
bigZero = big.NewInt(0)
|
|
||||||
bigOne = big.NewInt(1)
|
|
||||||
bigThousand = big.NewInt(1000)
|
|
||||||
big1024 = big.NewInt(1024)
|
|
||||||
|
|
||||||
// Commonly needed inf.Dec values-- treat as read only!
|
|
||||||
decZero = inf.NewDec(0, 0)
|
|
||||||
decOne = inf.NewDec(1, 0)
|
|
||||||
decMinusOne = inf.NewDec(-1, 0)
|
|
||||||
decThousand = inf.NewDec(1000, 0)
|
|
||||||
dec1024 = inf.NewDec(1024, 0)
|
|
||||||
decMinus1024 = inf.NewDec(-1024, 0)
|
|
||||||
|
|
||||||
// Largest (in magnitude) number allowed.
|
|
||||||
maxAllowed = inf.NewDec((1<<63)-1, 0) // == max int64
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// parseQuantityString is a fast scanner for quantity values.
|
||||||
|
func parseQuantityString(str string) (positive bool, value, num, denom, suffix string, err error) {
|
||||||
|
positive = true
|
||||||
|
pos := 0
|
||||||
|
end := len(str)
|
||||||
|
|
||||||
|
// handle leading sign
|
||||||
|
if pos < end {
|
||||||
|
switch str[0] {
|
||||||
|
case '-':
|
||||||
|
positive = false
|
||||||
|
pos++
|
||||||
|
case '+':
|
||||||
|
pos++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip leading zeros
|
||||||
|
Zeroes:
|
||||||
|
for i := pos; ; i++ {
|
||||||
|
if i >= end {
|
||||||
|
num = "0"
|
||||||
|
value = num
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch str[i] {
|
||||||
|
case '0':
|
||||||
|
pos++
|
||||||
|
default:
|
||||||
|
break Zeroes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract the numerator
|
||||||
|
Num:
|
||||||
|
for i := pos; ; i++ {
|
||||||
|
if i >= end {
|
||||||
|
num = str[pos:end]
|
||||||
|
value = str[0:end]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch str[i] {
|
||||||
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
default:
|
||||||
|
num = str[pos:i]
|
||||||
|
pos = i
|
||||||
|
break Num
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we stripped all numerator positions, always return 0
|
||||||
|
if len(num) == 0 {
|
||||||
|
num = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle a denominator
|
||||||
|
if pos < end && str[pos] == '.' {
|
||||||
|
pos++
|
||||||
|
Denom:
|
||||||
|
for i := pos; ; i++ {
|
||||||
|
if i >= end {
|
||||||
|
denom = str[pos:end]
|
||||||
|
value = str[0:end]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch str[i] {
|
||||||
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
default:
|
||||||
|
denom = str[pos:i]
|
||||||
|
pos = i
|
||||||
|
break Denom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: we currently allow 1.G, but we may not want to in the future.
|
||||||
|
// if len(denom) == 0 {
|
||||||
|
// err = ErrFormatWrong
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
value = str[0:pos]
|
||||||
|
|
||||||
|
// grab the elements of the suffix
|
||||||
|
suffixStart := pos
|
||||||
|
for i := pos; ; i++ {
|
||||||
|
if i >= end {
|
||||||
|
suffix = str[suffixStart:end]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !strings.ContainsAny(str[i:i+1], "eEinumkKMGTP") {
|
||||||
|
pos = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pos < end {
|
||||||
|
switch str[pos] {
|
||||||
|
case '-', '+':
|
||||||
|
pos++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Suffix:
|
||||||
|
for i := pos; ; i++ {
|
||||||
|
if i >= end {
|
||||||
|
suffix = str[suffixStart:end]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch str[i] {
|
||||||
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
default:
|
||||||
|
pos = i
|
||||||
|
break Suffix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we encountered a non decimal in the Suffix loop, but the last character
|
||||||
|
// was not a valid exponent
|
||||||
|
err = ErrFormatWrong
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ParseQuantity turns str into a Quantity, or returns an error.
|
// ParseQuantity turns str into a Quantity, or returns an error.
|
||||||
func ParseQuantity(str string) (*Quantity, error) {
|
func ParseQuantity(str string) (Quantity, error) {
|
||||||
parts := splitRE.FindStringSubmatch(strings.TrimSpace(str))
|
if len(str) == 0 {
|
||||||
// regexp returns are entire match, followed by an entry for each () section.
|
return Quantity{}, ErrFormatWrong
|
||||||
if len(parts) != 3 {
|
}
|
||||||
return nil, ErrFormatWrong
|
if str == "0" {
|
||||||
|
return Quantity{Format: DecimalSI}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
positive, value, num, denom, suf, err := parseQuantityString(str)
|
||||||
|
if err != nil {
|
||||||
|
return Quantity{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
base, exponent, format, ok := quantitySuffixer.interpret(suffix(suf))
|
||||||
|
if !ok {
|
||||||
|
return Quantity{}, ErrSuffix
|
||||||
|
}
|
||||||
|
|
||||||
|
precision := int32(0)
|
||||||
|
scale := int32(0)
|
||||||
|
mantissa := int64(1)
|
||||||
|
switch format {
|
||||||
|
case DecimalExponent, DecimalSI:
|
||||||
|
scale = exponent
|
||||||
|
precision = maxInt64Factors - int32(len(num)+len(denom))
|
||||||
|
case BinarySI:
|
||||||
|
scale = 0
|
||||||
|
switch {
|
||||||
|
case exponent >= 0 && len(denom) == 0:
|
||||||
|
// only handle positive binary numbers with the fast path
|
||||||
|
mantissa = int64(int64(mantissa) << uint64(exponent))
|
||||||
|
// 1Mi (2^20) has ~6 digits of decimal precision, so exponent*3/10 -1 is roughly the precision
|
||||||
|
precision = 15 - int32(len(num)) - int32(float32(exponent)*3/10) - 1
|
||||||
|
default:
|
||||||
|
precision = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if precision >= 0 {
|
||||||
|
// if we have a denominator, shift the entire value to the left by the number of places in the
|
||||||
|
// denominator
|
||||||
|
scale -= int32(len(denom))
|
||||||
|
if scale >= int32(Nano) {
|
||||||
|
shifted := num + denom
|
||||||
|
|
||||||
|
var value int64
|
||||||
|
value, err := strconv.ParseInt(shifted, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return Quantity{}, ErrNumeric
|
||||||
|
}
|
||||||
|
if result, ok := int64Multiply(value, int64(mantissa)); ok {
|
||||||
|
if !positive {
|
||||||
|
result = -result
|
||||||
|
}
|
||||||
|
return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
amount := new(inf.Dec)
|
amount := new(inf.Dec)
|
||||||
if _, ok := amount.SetString(parts[1]); !ok {
|
if _, ok := amount.SetString(value); !ok {
|
||||||
return nil, ErrNumeric
|
return Quantity{}, ErrNumeric
|
||||||
}
|
|
||||||
|
|
||||||
base, exponent, format, ok := quantitySuffixer.interpret(suffix(parts[2]))
|
|
||||||
if !ok {
|
|
||||||
return nil, ErrSuffix
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// So that no one but us has to think about suffixes, remove it.
|
// So that no one but us has to think about suffixes, remove it.
|
||||||
@ -217,9 +359,11 @@ func ParseQuantity(str string) (*Quantity, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The max is just a simple cap.
|
// The max is just a simple cap.
|
||||||
if amount.Cmp(maxAllowed) > 0 {
|
// TODO: this prevents accumulating quantities greater than int64, for instance quota across a cluster
|
||||||
amount.Set(maxAllowed)
|
if format == BinarySI && amount.Cmp(maxAllowed.Dec) > 0 {
|
||||||
|
amount.Set(maxAllowed.Dec)
|
||||||
}
|
}
|
||||||
|
|
||||||
if format == BinarySI && amount.Cmp(decOne) < 0 && amount.Cmp(decZero) > 0 {
|
if format == BinarySI && amount.Cmp(decOne) < 0 && amount.Cmp(decZero) > 0 {
|
||||||
// This avoids rounding and hopefully confusion, too.
|
// This avoids rounding and hopefully confusion, too.
|
||||||
format = DecimalSI
|
format = DecimalSI
|
||||||
@ -228,25 +372,7 @@ func ParseQuantity(str string) (*Quantity, error) {
|
|||||||
amount.Neg(amount)
|
amount.Neg(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Quantity{amount, format}, nil
|
return Quantity{d: infDecAmount{amount}, Format: format}, nil
|
||||||
}
|
|
||||||
|
|
||||||
// removeFactors divides in a loop; the return values have the property that
|
|
||||||
// d == result * factor ^ times
|
|
||||||
// d may be modified in place.
|
|
||||||
// If d == 0, then the return values will be (0, 0)
|
|
||||||
func removeFactors(d, factor *big.Int) (result *big.Int, times int) {
|
|
||||||
q := big.NewInt(0)
|
|
||||||
m := big.NewInt(0)
|
|
||||||
for d.Cmp(bigZero) != 0 {
|
|
||||||
q.DivMod(d, factor, m)
|
|
||||||
if m.Cmp(bigZero) != 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
times++
|
|
||||||
d, q = q, d
|
|
||||||
}
|
|
||||||
return d, times
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Canonicalize returns the canonical form of q and its suffix (see comment on Quantity).
|
// Canonicalize returns the canonical form of q and its suffix (see comment on Quantity).
|
||||||
@ -256,27 +382,22 @@ func removeFactors(d, factor *big.Int) (result *big.Int, times int) {
|
|||||||
// -1 and +1, it will be emitted as if q.Format were DecimalSI.
|
// -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
|
// * Otherwise, if q.Format is set to BinarySI, frational parts of q.Amount will be
|
||||||
// rounded up. (1.1i becomes 2i.)
|
// rounded up. (1.1i becomes 2i.)
|
||||||
func (q *Quantity) Canonicalize() (string, suffix) {
|
func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte) {
|
||||||
if q.Amount == nil {
|
if q.IsZero() {
|
||||||
return "0", ""
|
return zeroBytes, nil
|
||||||
}
|
|
||||||
|
|
||||||
// zero is zero always
|
|
||||||
if q.Amount.Cmp(&inf.Dec{}) == 0 {
|
|
||||||
return "0", ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var rounded CanonicalValue
|
||||||
format := q.Format
|
format := q.Format
|
||||||
switch format {
|
switch format {
|
||||||
case DecimalExponent, DecimalSI:
|
case DecimalExponent, DecimalSI:
|
||||||
case BinarySI:
|
case BinarySI:
|
||||||
if q.Amount.Cmp(decMinus1024) > 0 && q.Amount.Cmp(dec1024) < 0 {
|
if q.CmpInt64(-1024) > 0 && q.CmpInt64(1024) < 0 {
|
||||||
// This avoids rounding and hopefully confusion, too.
|
// This avoids rounding and hopefully confusion, too.
|
||||||
format = DecimalSI
|
format = DecimalSI
|
||||||
} else {
|
} else {
|
||||||
tmp := &inf.Dec{}
|
var exact bool
|
||||||
tmp.Round(q.Amount, 0, inf.RoundUp)
|
if rounded, exact = q.AsScale(0); !exact {
|
||||||
if tmp.Cmp(q.Amount) != 0 {
|
|
||||||
// Don't lose precision-- show as DecimalSI
|
// Don't lose precision-- show as DecimalSI
|
||||||
format = DecimalSI
|
format = DecimalSI
|
||||||
}
|
}
|
||||||
@ -289,125 +410,223 @@ func (q *Quantity) Canonicalize() (string, suffix) {
|
|||||||
// one of the other formats.
|
// one of the other formats.
|
||||||
switch format {
|
switch format {
|
||||||
case DecimalExponent, DecimalSI:
|
case DecimalExponent, DecimalSI:
|
||||||
mantissa := q.Amount.UnscaledBig()
|
number, exponent := q.AsCanonicalBytes(out)
|
||||||
exponent := int(-q.Amount.Scale())
|
suffix, _ := quantitySuffixer.constructBytes(10, exponent, format)
|
||||||
amount := big.NewInt(0).Set(mantissa)
|
|
||||||
// move all factors of 10 into the exponent for easy reasoning
|
|
||||||
amount, times := removeFactors(amount, bigTen)
|
|
||||||
exponent += times
|
|
||||||
|
|
||||||
// make sure exponent is a multiple of 3
|
|
||||||
for exponent%3 != 0 {
|
|
||||||
amount.Mul(amount, bigTen)
|
|
||||||
exponent--
|
|
||||||
}
|
|
||||||
|
|
||||||
suffix, _ := quantitySuffixer.construct(10, exponent, format)
|
|
||||||
number := amount.String()
|
|
||||||
return number, suffix
|
return number, suffix
|
||||||
case BinarySI:
|
default:
|
||||||
tmp := &inf.Dec{}
|
// format must be BinarySI
|
||||||
tmp.Round(q.Amount, 0, inf.RoundUp)
|
number, exponent := rounded.AsCanonicalBase1024Bytes(out)
|
||||||
|
suffix, _ := quantitySuffixer.constructBytes(2, exponent*10, format)
|
||||||
amount, exponent := removeFactors(tmp.UnscaledBig(), big1024)
|
|
||||||
suffix, _ := quantitySuffixer.construct(2, exponent*10, format)
|
|
||||||
number := amount.String()
|
|
||||||
return number, suffix
|
return number, suffix
|
||||||
}
|
}
|
||||||
return "0", ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 (q *Quantity) AsInt64() (int64, bool) {
|
||||||
|
if q.d.Dec != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return q.i.AsInt64()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDec promotes the quantity in place to use an inf.Dec representation and returns itself.
|
||||||
|
func (q *Quantity) ToDec() *Quantity {
|
||||||
|
if q.d.Dec == nil {
|
||||||
|
q.d.Dec = q.i.AsDec()
|
||||||
|
q.i = int64Amount{}
|
||||||
|
}
|
||||||
|
return q
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsDec returns the quantity as represented by a scaled inf.Dec.
|
||||||
|
func (q *Quantity) AsDec() *inf.Dec {
|
||||||
|
if q.d.Dec != nil {
|
||||||
|
return q.d.Dec
|
||||||
|
}
|
||||||
|
q.d.Dec = q.i.AsDec()
|
||||||
|
q.i = int64Amount{}
|
||||||
|
return q.d.Dec
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 (q *Quantity) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
|
||||||
|
if q.d.Dec != nil {
|
||||||
|
return q.d.AsCanonicalBytes(out)
|
||||||
|
}
|
||||||
|
return q.i.AsCanonicalBytes(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsZero returns true if the quantity is equal to zero.
|
||||||
|
func (q *Quantity) IsZero() bool {
|
||||||
|
if q.d.Dec != nil {
|
||||||
|
return q.d.Dec.Sign() == 0
|
||||||
|
}
|
||||||
|
return q.i.value == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign returns 0 if the quantity is zero, -1 if the quantity is less than zero, or 1 if the
|
||||||
|
// quantity is greater than zero.
|
||||||
|
func (q *Quantity) Sign() int {
|
||||||
|
if q.d.Dec != nil {
|
||||||
|
return q.d.Dec.Sign()
|
||||||
|
}
|
||||||
|
return q.i.Sign()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsScaled returns the current value, rounded up to the provided scale, and returns
|
||||||
|
// false if the scale resulted in a loss of precision.
|
||||||
|
func (q *Quantity) AsScale(scale Scale) (CanonicalValue, bool) {
|
||||||
|
if q.d.Dec != nil {
|
||||||
|
return q.d.AsScale(scale)
|
||||||
|
}
|
||||||
|
return q.i.AsScale(scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundUp updates the quantity to the provided scale, ensuring that the value is at
|
||||||
|
// least 1. False is returned if the rounding operation resulted in a loss of precision.
|
||||||
|
// Negative numbers are rounded away from zero (-9 scale 1 rounds to -10).
|
||||||
|
func (q *Quantity) RoundUp(scale Scale) bool {
|
||||||
|
if q.d.Dec != nil {
|
||||||
|
d, exact := q.d.AsScale(scale)
|
||||||
|
q.d = d
|
||||||
|
return exact
|
||||||
|
}
|
||||||
|
i, exact := q.i.AsScale(scale)
|
||||||
|
q.i = i
|
||||||
|
return exact
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds the provide y quantity to the current value. If the current value is zero,
|
||||||
|
// the format of the quantity will be updated to the format of y.
|
||||||
|
func (q *Quantity) Add(y Quantity) {
|
||||||
|
q.s = nil
|
||||||
|
if q.d.Dec == nil && y.d.Dec == nil {
|
||||||
|
if q.i.value == 0 {
|
||||||
|
q.Format = y.Format
|
||||||
|
}
|
||||||
|
if q.i.Add(y.i) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if q.IsZero() {
|
||||||
|
q.Format = y.Format
|
||||||
|
}
|
||||||
|
q.ToDec().d.Dec.Add(q.d.Dec, y.AsDec())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub subtracts the provided quantity from the current value in place. If the current
|
||||||
|
// value is zero, the format of the quantity will be updated to the format of y.
|
||||||
|
func (q *Quantity) Sub(y Quantity) {
|
||||||
|
q.s = nil
|
||||||
|
if q.IsZero() {
|
||||||
|
q.Format = y.Format
|
||||||
|
}
|
||||||
|
if q.d.Dec == nil && y.d.Dec == nil && q.i.Sub(y.i) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
q.ToDec().d.Dec.Sub(q.d.Dec, y.AsDec())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 (q *Quantity) Cmp(y Quantity) int {
|
||||||
|
if q.d.Dec == nil && y.d.Dec == nil {
|
||||||
|
return q.i.Cmp(y.i)
|
||||||
|
}
|
||||||
|
return q.AsDec().Cmp(y.AsDec())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 (q *Quantity) CmpInt64(y int64) int {
|
||||||
|
if q.d.Dec != nil {
|
||||||
|
return q.d.Dec.Cmp(inf.NewDec(y, inf.Scale(0)))
|
||||||
|
}
|
||||||
|
return q.i.Cmp(int64Amount{value: y})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Neg sets quantity to be the negative value of itself.
|
||||||
|
func (q *Quantity) Neg() {
|
||||||
|
q.s = nil
|
||||||
|
if q.d.Dec == nil {
|
||||||
|
q.i.value = -q.i.value
|
||||||
|
return
|
||||||
|
}
|
||||||
|
q.d.Dec.Neg(q.d.Dec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// toBytes ensures q.s is set to a byte slice representing the canonical string form of this
|
||||||
|
// quantity and then returns the value. CanonicalizeBytes is an expensive operation, and caching
|
||||||
|
// this result significantly reduces the cost of normal parse / marshal operations on Quantity.
|
||||||
|
func (q *Quantity) toBytes() []byte {
|
||||||
|
if q.s == nil {
|
||||||
|
result := make([]byte, 0, int64QuantityExpectedBytes)
|
||||||
|
number, suffix := q.CanonicalizeBytes(result)
|
||||||
|
number = append(number, suffix...)
|
||||||
|
q.s = number
|
||||||
|
}
|
||||||
|
return q.s
|
||||||
|
}
|
||||||
|
|
||||||
|
// int64QuantityExpectedBytes is the expected width in bytes of the canonical string representation
|
||||||
|
// of most Quantity values.
|
||||||
|
const int64QuantityExpectedBytes = 18
|
||||||
|
|
||||||
// String formats the Quantity as a string.
|
// String formats the Quantity as a string.
|
||||||
func (q *Quantity) String() string {
|
func (q *Quantity) String() string {
|
||||||
number, suffix := q.Canonicalize()
|
return string(q.toBytes())
|
||||||
return number + string(suffix)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cmp compares q and y and returns:
|
|
||||||
//
|
|
||||||
// -1 if q < y
|
|
||||||
// 0 if q == y
|
|
||||||
// +1 if q > y
|
|
||||||
//
|
|
||||||
func (q *Quantity) Cmp(y Quantity) int {
|
|
||||||
if q.Amount == nil {
|
|
||||||
if y.Amount == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return -y.Amount.Sign()
|
|
||||||
}
|
|
||||||
if y.Amount == nil {
|
|
||||||
return q.Amount.Sign()
|
|
||||||
}
|
|
||||||
return q.Amount.Cmp(y.Amount)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Quantity) Add(y Quantity) error {
|
|
||||||
switch {
|
|
||||||
case y.Amount == nil:
|
|
||||||
// Adding 0: do nothing.
|
|
||||||
case q.Amount == nil:
|
|
||||||
q.Amount = &inf.Dec{}
|
|
||||||
return q.Add(y)
|
|
||||||
default:
|
|
||||||
// we want to preserve the format of the non-zero value
|
|
||||||
zero := &inf.Dec{}
|
|
||||||
if q.Amount.Cmp(zero) == 0 && y.Amount.Cmp(zero) != 0 {
|
|
||||||
q.Format = y.Format
|
|
||||||
}
|
|
||||||
q.Amount.Add(q.Amount, y.Amount)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Quantity) Sub(y Quantity) error {
|
|
||||||
switch {
|
|
||||||
case y.Amount == nil:
|
|
||||||
// Subtracting 0: do nothing.
|
|
||||||
case q.Amount == nil:
|
|
||||||
q.Amount = &inf.Dec{}
|
|
||||||
return q.Sub(y)
|
|
||||||
default:
|
|
||||||
// we want to preserve the format of the non-zero value
|
|
||||||
zero := &inf.Dec{}
|
|
||||||
if q.Amount.Cmp(zero) == 0 && y.Amount.Cmp(zero) != 0 {
|
|
||||||
q.Format = y.Format
|
|
||||||
}
|
|
||||||
q.Amount.Sub(q.Amount, y.Amount)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Neg sets q to the negative value of y.
|
|
||||||
// It updates the format of q to match y.
|
|
||||||
func (q *Quantity) Neg(y Quantity) error {
|
|
||||||
switch {
|
|
||||||
case y.Amount == nil:
|
|
||||||
*q = y
|
|
||||||
case q.Amount == nil:
|
|
||||||
q.Amount = &inf.Dec{}
|
|
||||||
fallthrough
|
|
||||||
default:
|
|
||||||
q.Amount.Neg(y.Amount)
|
|
||||||
q.Format = y.Format
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements the json.Marshaller interface.
|
// MarshalJSON implements the json.Marshaller interface.
|
||||||
func (q Quantity) MarshalJSON() ([]byte, error) {
|
func (q Quantity) MarshalJSON() ([]byte, error) {
|
||||||
return []byte(`"` + q.String() + `"`), nil
|
if q.s != nil {
|
||||||
|
out := make([]byte, len(q.s)+2)
|
||||||
|
out[0], out[len(out)-1] = '"', '"'
|
||||||
|
copy(out[1:], q.s)
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
result := make([]byte, int64QuantityExpectedBytes, int64QuantityExpectedBytes)
|
||||||
|
result[0] = '"'
|
||||||
|
number, suffix := q.CanonicalizeBytes(result[1:1])
|
||||||
|
// if the same slice was returned to us that we passed in, avoid another allocation by copying number into
|
||||||
|
// the source slice and returning that
|
||||||
|
if len(number) > 0 && &number[0] == &result[1] && (len(number)+len(suffix)+2) <= int64QuantityExpectedBytes {
|
||||||
|
number = append(number, suffix...)
|
||||||
|
number = append(number, '"')
|
||||||
|
return result[:1+len(number)], nil
|
||||||
|
}
|
||||||
|
// if CanonicalizeBytes needed more space than our slice provided, we may need to allocate again so use
|
||||||
|
// append
|
||||||
|
result = result[:1]
|
||||||
|
result = append(result, number...)
|
||||||
|
result = append(result, suffix...)
|
||||||
|
result = append(result, '"')
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||||
func (q *Quantity) UnmarshalJSON(value []byte) error {
|
func (q *Quantity) UnmarshalJSON(value []byte) error {
|
||||||
str := string(value)
|
l := len(value)
|
||||||
parsed, err := ParseQuantity(strings.Trim(str, `"`))
|
if l == 4 && bytes.Equal(value, []byte("null")) {
|
||||||
|
q.d.Dec = nil
|
||||||
|
q.i = int64Amount{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if l < 2 {
|
||||||
|
return ErrFormatWrong
|
||||||
|
}
|
||||||
|
if value[0] == '"' && value[l-1] == '"' {
|
||||||
|
value = value[1 : l-1]
|
||||||
|
}
|
||||||
|
parsed, err := ParseQuantity(string(value))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
parsed.s = value
|
||||||
// This copy is safe because parsed will not be referred to again.
|
// This copy is safe because parsed will not be referred to again.
|
||||||
*q = *parsed
|
*q = parsed
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,7 +634,7 @@ func (q *Quantity) UnmarshalJSON(value []byte) error {
|
|||||||
// value in the given format.
|
// value in the given format.
|
||||||
func NewQuantity(value int64, format Format) *Quantity {
|
func NewQuantity(value int64, format Format) *Quantity {
|
||||||
return &Quantity{
|
return &Quantity{
|
||||||
Amount: inf.NewDec(value, 0),
|
i: int64Amount{value: value},
|
||||||
Format: format,
|
Format: format,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -426,7 +645,7 @@ func NewQuantity(value int64, format Format) *Quantity {
|
|||||||
// values x where (-1 < x < 1) && (x != 0).
|
// values x where (-1 < x < 1) && (x != 0).
|
||||||
func NewMilliQuantity(value int64, format Format) *Quantity {
|
func NewMilliQuantity(value int64, format Format) *Quantity {
|
||||||
return &Quantity{
|
return &Quantity{
|
||||||
Amount: inf.NewDec(value, 3),
|
i: int64Amount{value: value, scale: -3},
|
||||||
Format: format,
|
Format: format,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,7 +654,7 @@ func NewMilliQuantity(value int64, format Format) *Quantity {
|
|||||||
// value * 10^scale in DecimalSI format.
|
// value * 10^scale in DecimalSI format.
|
||||||
func NewScaledQuantity(value int64, scale Scale) *Quantity {
|
func NewScaledQuantity(value int64, scale Scale) *Quantity {
|
||||||
return &Quantity{
|
return &Quantity{
|
||||||
Amount: inf.NewDec(value, scale.infScale()),
|
i: int64Amount{value: value, scale: scale},
|
||||||
Format: DecimalSI,
|
Format: DecimalSI,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -454,10 +673,12 @@ func (q *Quantity) MilliValue() int64 {
|
|||||||
// ScaledValue returns the value of ceil(q * 10^scale); this could overflow an int64.
|
// ScaledValue returns the value of ceil(q * 10^scale); this could overflow an int64.
|
||||||
// To detect overflow, call Value() first and verify the expected magnitude.
|
// To detect overflow, call Value() first and verify the expected magnitude.
|
||||||
func (q *Quantity) ScaledValue(scale Scale) int64 {
|
func (q *Quantity) ScaledValue(scale Scale) int64 {
|
||||||
if q.Amount == nil {
|
if q.d.Dec == nil {
|
||||||
return 0
|
i, _ := q.i.AsScaledInt64(scale)
|
||||||
|
return i
|
||||||
}
|
}
|
||||||
return scaledValue(q.Amount.UnscaledBig(), int(q.Amount.Scale()), int(scale.infScale()))
|
dec := q.d.Dec
|
||||||
|
return scaledValue(dec.UnscaledBig(), int(dec.Scale()), int(scale.infScale()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set sets q's value to be value.
|
// Set sets q's value to be value.
|
||||||
@ -472,22 +693,25 @@ func (q *Quantity) SetMilli(value int64) {
|
|||||||
|
|
||||||
// SetScaled sets q's value to be value * 10^scale
|
// SetScaled sets q's value to be value * 10^scale
|
||||||
func (q *Quantity) SetScaled(value int64, scale Scale) {
|
func (q *Quantity) SetScaled(value int64, scale Scale) {
|
||||||
if q.Amount == nil {
|
q.s = nil
|
||||||
q.Amount = &inf.Dec{}
|
q.d.Dec = nil
|
||||||
}
|
q.i = int64Amount{value: value, scale: scale}
|
||||||
q.Amount.SetUnscaled(value)
|
|
||||||
q.Amount.SetScale(scale.infScale())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy is a convenience function that makes a deep copy for you. Non-deep
|
// Copy is a convenience function that makes a deep copy for you. Non-deep
|
||||||
// copies of quantities share pointers and you will regret that.
|
// copies of quantities share pointers and you will regret that.
|
||||||
func (q *Quantity) Copy() *Quantity {
|
func (q *Quantity) Copy() *Quantity {
|
||||||
if q.Amount == nil {
|
if q.d.Dec == nil {
|
||||||
return NewQuantity(0, q.Format)
|
return &Quantity{
|
||||||
|
s: q.s,
|
||||||
|
i: q.i,
|
||||||
|
Format: q.Format,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tmp := &inf.Dec{}
|
tmp := &inf.Dec{}
|
||||||
return &Quantity{
|
return &Quantity{
|
||||||
Amount: tmp.Set(q.Amount),
|
s: q.s,
|
||||||
|
d: infDecAmount{tmp.Set(q.d.Dec)},
|
||||||
Format: q.Format,
|
Format: q.Format,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,7 +728,7 @@ func (qf qFlag) Set(val string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// This copy is OK because q will not be referenced again.
|
// This copy is OK because q will not be referenced again.
|
||||||
*qf.dest = *q
|
*qf.dest = q
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,8 +755,3 @@ func QuantityFlag(flagName, defaultValue, description string) *Quantity {
|
|||||||
func NewQuantityFlagValue(q *Quantity) flag.Value {
|
func NewQuantityFlagValue(q *Quantity) flag.Value {
|
||||||
return qFlag{q}
|
return qFlag{q}
|
||||||
}
|
}
|
||||||
|
|
||||||
// infScale adapts a Scale value to an inf.Scale value.
|
|
||||||
func (s Scale) infScale() inf.Scale {
|
|
||||||
return inf.Scale(-s) // inf.Scale is upside-down
|
|
||||||
}
|
|
||||||
|
@ -17,62 +17,268 @@ limitations under the License.
|
|||||||
package resource
|
package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
inf "gopkg.in/inf.v0"
|
"github.com/gogo/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// QuantityProto is a struct that is equivalent to Quantity, but intended for
|
var _ proto.Sizer = &Quantity{}
|
||||||
// protobuf marshalling/unmarshalling. It is generated into a serialization
|
|
||||||
// that matches Quantity. Do not use in Go structs.
|
func (m *Quantity) Marshal() (data []byte, err error) {
|
||||||
//
|
size := m.Size()
|
||||||
// +protobuf=true
|
data = make([]byte, size)
|
||||||
type QuantityProto struct {
|
n, err := m.MarshalTo(data)
|
||||||
// The format of the quantity
|
if err != nil {
|
||||||
Format Format `protobuf:"bytes,1,opt,name=format,casttype=Format"`
|
return nil, err
|
||||||
// The scale dimension of the value
|
}
|
||||||
Scale int32 `protobuf:"varint,2,opt,name=scale"`
|
return data[:n], nil
|
||||||
// Bigint is serialized as a raw bytes array
|
|
||||||
Bigint []byte `protobuf:"bytes,3,opt,name=bigint"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProtoTime returns the Time as a new ProtoTime value.
|
// MarshalTo is a customized version of the generated Protobuf unmarshaler for a struct
|
||||||
func (q *Quantity) QuantityProto() *QuantityProto {
|
// with a single string field.
|
||||||
if q == nil {
|
func (m *Quantity) MarshalTo(data []byte) (int, error) {
|
||||||
return &QuantityProto{}
|
var i int
|
||||||
}
|
_ = i
|
||||||
p := &QuantityProto{
|
var l int
|
||||||
Format: q.Format,
|
_ = l
|
||||||
}
|
|
||||||
if q.Amount != nil {
|
data[i] = 0xa
|
||||||
p.Scale = int32(q.Amount.Scale())
|
i++
|
||||||
p.Bigint = q.Amount.UnscaledBig().Bytes()
|
// BEGIN CUSTOM MARSHAL
|
||||||
}
|
out := m.toBytes()
|
||||||
return p
|
i = encodeVarintGenerated(data, i, uint64(len(out)))
|
||||||
|
i += copy(data[i:], out)
|
||||||
|
// END CUSTOM MARSHAL
|
||||||
|
|
||||||
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size implements the protobuf marshalling interface.
|
func encodeVarintGenerated(data []byte, offset int, v uint64) int {
|
||||||
func (q *Quantity) Size() (n int) { return q.QuantityProto().Size() }
|
for v >= 1<<7 {
|
||||||
|
data[offset] = uint8(v&0x7f | 0x80)
|
||||||
|
v >>= 7
|
||||||
|
offset++
|
||||||
|
}
|
||||||
|
data[offset] = uint8(v)
|
||||||
|
return offset + 1
|
||||||
|
}
|
||||||
|
|
||||||
// Reset implements the protobuf marshalling interface.
|
func (m *Quantity) Size() (n int) {
|
||||||
func (q *Quantity) Unmarshal(data []byte) error {
|
var l int
|
||||||
p := QuantityProto{}
|
_ = l
|
||||||
if err := p.Unmarshal(data); err != nil {
|
|
||||||
|
// BEGIN CUSTOM SIZE
|
||||||
|
l = len(m.toBytes())
|
||||||
|
// END CUSTOM SIZE
|
||||||
|
|
||||||
|
n += 1 + l + sovGenerated(uint64(l))
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func sovGenerated(x uint64) (n int) {
|
||||||
|
for {
|
||||||
|
n++
|
||||||
|
x >>= 7
|
||||||
|
if x == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal is a customized version of the generated Protobuf unmarshaler for a struct
|
||||||
|
// with a single string field.
|
||||||
|
func (m *Quantity) Unmarshal(data []byte) error {
|
||||||
|
l := len(data)
|
||||||
|
iNdEx := 0
|
||||||
|
for iNdEx < l {
|
||||||
|
preIndex := iNdEx
|
||||||
|
var wire uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowGenerated
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
wire |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldNum := int32(wire >> 3)
|
||||||
|
wireType := int(wire & 0x7)
|
||||||
|
if wireType == 4 {
|
||||||
|
return fmt.Errorf("proto: Quantity: wiretype end group for non-group")
|
||||||
|
}
|
||||||
|
if fieldNum <= 0 {
|
||||||
|
return fmt.Errorf("proto: Quantity: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||||
|
}
|
||||||
|
switch fieldNum {
|
||||||
|
case 1:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field String_", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowGenerated
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthGenerated
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
s := string(data[iNdEx:postIndex])
|
||||||
|
|
||||||
|
// BEGIN CUSTOM DECODE
|
||||||
|
p, err := ParseQuantity(s)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
q.Format = p.Format
|
*m = p
|
||||||
b := big.NewInt(0)
|
// END CUSTOM DECODE
|
||||||
b.SetBytes(p.Bigint)
|
|
||||||
q.Amount = inf.NewDecBig(b, inf.Scale(p.Scale))
|
iNdEx = postIndex
|
||||||
|
default:
|
||||||
|
iNdEx = preIndex
|
||||||
|
skippy, err := skipGenerated(data[iNdEx:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if skippy < 0 {
|
||||||
|
return ErrInvalidLengthGenerated
|
||||||
|
}
|
||||||
|
if (iNdEx + skippy) > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
iNdEx += skippy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if iNdEx > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshal implements the protobuf marshalling interface.
|
func skipGenerated(data []byte) (n int, err error) {
|
||||||
func (q *Quantity) Marshal() (data []byte, err error) {
|
l := len(data)
|
||||||
return q.QuantityProto().Marshal()
|
iNdEx := 0
|
||||||
|
for iNdEx < l {
|
||||||
|
var wire uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return 0, ErrIntOverflowGenerated
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
wire |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wireType := int(wire & 0x7)
|
||||||
|
switch wireType {
|
||||||
|
case 0:
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return 0, ErrIntOverflowGenerated
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
iNdEx++
|
||||||
|
if data[iNdEx-1] < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iNdEx, nil
|
||||||
|
case 1:
|
||||||
|
iNdEx += 8
|
||||||
|
return iNdEx, nil
|
||||||
|
case 2:
|
||||||
|
var length int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return 0, ErrIntOverflowGenerated
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
length |= (int(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iNdEx += length
|
||||||
|
if length < 0 {
|
||||||
|
return 0, ErrInvalidLengthGenerated
|
||||||
|
}
|
||||||
|
return iNdEx, nil
|
||||||
|
case 3:
|
||||||
|
for {
|
||||||
|
var innerWire uint64
|
||||||
|
var start int = iNdEx
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return 0, ErrIntOverflowGenerated
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
innerWire |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
innerWireType := int(innerWire & 0x7)
|
||||||
|
if innerWireType == 4 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
next, err := skipGenerated(data[start:])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
iNdEx = start + next
|
||||||
|
}
|
||||||
|
return iNdEx, nil
|
||||||
|
case 4:
|
||||||
|
return iNdEx, nil
|
||||||
|
case 5:
|
||||||
|
iNdEx += 4
|
||||||
|
return iNdEx, nil
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalTo implements the protobuf marshalling interface.
|
var (
|
||||||
func (q *Quantity) MarshalTo(data []byte) (int, error) {
|
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||||
return q.QuantityProto().MarshalTo(data)
|
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
|
||||||
}
|
)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -24,8 +24,9 @@ type suffix string
|
|||||||
|
|
||||||
// suffixer can interpret and construct suffixes.
|
// suffixer can interpret and construct suffixes.
|
||||||
type suffixer interface {
|
type suffixer interface {
|
||||||
interpret(suffix) (base, exponent int, fmt Format, ok bool)
|
interpret(suffix) (base, exponent int32, fmt Format, ok bool)
|
||||||
construct(base, exponent int, fmt Format) (s suffix, ok bool)
|
construct(base, exponent int32, fmt Format) (s suffix, ok bool)
|
||||||
|
constructBytes(base, exponent int32, fmt Format) (s []byte, ok bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// quantitySuffixer handles suffixes for all three formats that quantity
|
// quantitySuffixer handles suffixes for all three formats that quantity
|
||||||
@ -33,12 +34,13 @@ type suffixer interface {
|
|||||||
var quantitySuffixer = newSuffixer()
|
var quantitySuffixer = newSuffixer()
|
||||||
|
|
||||||
type bePair struct {
|
type bePair struct {
|
||||||
base, exponent int
|
base, exponent int32
|
||||||
}
|
}
|
||||||
|
|
||||||
type listSuffixer struct {
|
type listSuffixer struct {
|
||||||
suffixToBE map[suffix]bePair
|
suffixToBE map[suffix]bePair
|
||||||
beToSuffix map[bePair]suffix
|
beToSuffix map[bePair]suffix
|
||||||
|
beToSuffixBytes map[bePair][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ls *listSuffixer) addSuffix(s suffix, pair bePair) {
|
func (ls *listSuffixer) addSuffix(s suffix, pair bePair) {
|
||||||
@ -48,11 +50,15 @@ func (ls *listSuffixer) addSuffix(s suffix, pair bePair) {
|
|||||||
if ls.beToSuffix == nil {
|
if ls.beToSuffix == nil {
|
||||||
ls.beToSuffix = map[bePair]suffix{}
|
ls.beToSuffix = map[bePair]suffix{}
|
||||||
}
|
}
|
||||||
|
if ls.beToSuffixBytes == nil {
|
||||||
|
ls.beToSuffixBytes = map[bePair][]byte{}
|
||||||
|
}
|
||||||
ls.suffixToBE[s] = pair
|
ls.suffixToBE[s] = pair
|
||||||
ls.beToSuffix[pair] = s
|
ls.beToSuffix[pair] = s
|
||||||
|
ls.beToSuffixBytes[pair] = []byte(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ls *listSuffixer) lookup(s suffix) (base, exponent int, ok bool) {
|
func (ls *listSuffixer) lookup(s suffix) (base, exponent int32, ok bool) {
|
||||||
pair, ok := ls.suffixToBE[s]
|
pair, ok := ls.suffixToBE[s]
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, 0, false
|
return 0, 0, false
|
||||||
@ -60,19 +66,50 @@ func (ls *listSuffixer) lookup(s suffix) (base, exponent int, ok bool) {
|
|||||||
return pair.base, pair.exponent, true
|
return pair.base, pair.exponent, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ls *listSuffixer) construct(base, exponent int) (s suffix, ok bool) {
|
func (ls *listSuffixer) construct(base, exponent int32) (s suffix, ok bool) {
|
||||||
s, ok = ls.beToSuffix[bePair{base, exponent}]
|
s, ok = ls.beToSuffix[bePair{base, exponent}]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ls *listSuffixer) constructBytes(base, exponent int32) (s []byte, ok bool) {
|
||||||
|
s, ok = ls.beToSuffixBytes[bePair{base, exponent}]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type suffixHandler struct {
|
type suffixHandler struct {
|
||||||
decSuffixes listSuffixer
|
decSuffixes listSuffixer
|
||||||
binSuffixes listSuffixer
|
binSuffixes listSuffixer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type fastLookup struct {
|
||||||
|
*suffixHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fastLookup) interpret(s suffix) (base, exponent int32, format Format, ok bool) {
|
||||||
|
switch s {
|
||||||
|
case "":
|
||||||
|
return 10, 0, DecimalSI, true
|
||||||
|
case "n":
|
||||||
|
return 10, -9, DecimalSI, true
|
||||||
|
case "u":
|
||||||
|
return 10, -6, DecimalSI, true
|
||||||
|
case "m":
|
||||||
|
return 10, -3, DecimalSI, true
|
||||||
|
case "k":
|
||||||
|
return 10, 3, DecimalSI, true
|
||||||
|
case "M":
|
||||||
|
return 10, 6, DecimalSI, true
|
||||||
|
case "G":
|
||||||
|
return 10, 9, DecimalSI, true
|
||||||
|
}
|
||||||
|
return l.suffixHandler.interpret(s)
|
||||||
|
}
|
||||||
|
|
||||||
func newSuffixer() suffixer {
|
func newSuffixer() suffixer {
|
||||||
sh := &suffixHandler{}
|
sh := &suffixHandler{}
|
||||||
|
|
||||||
|
// IMPORTANT: if you change this section you must change fastLookup
|
||||||
|
|
||||||
sh.binSuffixes.addSuffix("Ki", bePair{2, 10})
|
sh.binSuffixes.addSuffix("Ki", bePair{2, 10})
|
||||||
sh.binSuffixes.addSuffix("Mi", bePair{2, 20})
|
sh.binSuffixes.addSuffix("Mi", bePair{2, 20})
|
||||||
sh.binSuffixes.addSuffix("Gi", bePair{2, 30})
|
sh.binSuffixes.addSuffix("Gi", bePair{2, 30})
|
||||||
@ -94,10 +131,10 @@ func newSuffixer() suffixer {
|
|||||||
sh.decSuffixes.addSuffix("P", bePair{10, 15})
|
sh.decSuffixes.addSuffix("P", bePair{10, 15})
|
||||||
sh.decSuffixes.addSuffix("E", bePair{10, 18})
|
sh.decSuffixes.addSuffix("E", bePair{10, 18})
|
||||||
|
|
||||||
return sh
|
return fastLookup{sh}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sh *suffixHandler) construct(base, exponent int, fmt Format) (s suffix, ok bool) {
|
func (sh *suffixHandler) construct(base, exponent int32, fmt Format) (s suffix, ok bool) {
|
||||||
switch fmt {
|
switch fmt {
|
||||||
case DecimalSI:
|
case DecimalSI:
|
||||||
return sh.decSuffixes.construct(base, exponent)
|
return sh.decSuffixes.construct(base, exponent)
|
||||||
@ -115,7 +152,32 @@ func (sh *suffixHandler) construct(base, exponent int, fmt Format) (s suffix, ok
|
|||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int, fmt Format, ok bool) {
|
func (sh *suffixHandler) constructBytes(base, exponent int32, format Format) (s []byte, ok bool) {
|
||||||
|
switch format {
|
||||||
|
case DecimalSI:
|
||||||
|
return sh.decSuffixes.constructBytes(base, exponent)
|
||||||
|
case BinarySI:
|
||||||
|
return sh.binSuffixes.constructBytes(base, exponent)
|
||||||
|
case DecimalExponent:
|
||||||
|
if base != 10 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if exponent == 0 {
|
||||||
|
return nil, true
|
||||||
|
}
|
||||||
|
result := make([]byte, 8, 8)
|
||||||
|
result[0] = 'e'
|
||||||
|
number := strconv.AppendInt(result[1:1], int64(exponent), 10)
|
||||||
|
if &result[1] == &number[0] {
|
||||||
|
return result[:1+len(number)], true
|
||||||
|
}
|
||||||
|
result = append(result[:1], number...)
|
||||||
|
return result, true
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int32, fmt Format, ok bool) {
|
||||||
// Try lookup tables first
|
// Try lookup tables first
|
||||||
if b, e, ok := sh.decSuffixes.lookup(suffix); ok {
|
if b, e, ok := sh.decSuffixes.lookup(suffix); ok {
|
||||||
return b, e, DecimalSI, true
|
return b, e, DecimalSI, true
|
||||||
@ -129,7 +191,7 @@ func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int, fmt Forma
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, DecimalExponent, false
|
return 0, 0, DecimalExponent, false
|
||||||
}
|
}
|
||||||
return 10, int(parsed), DecimalExponent, true
|
return 10, int32(parsed), DecimalExponent, true
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, 0, DecimalExponent, false
|
return 0, 0, DecimalExponent, false
|
||||||
|
@ -151,15 +151,17 @@ func PodRequestsAndLimits(pod *Pod) (reqs map[ResourceName]resource.Quantity, li
|
|||||||
for name, quantity := range container.Resources.Requests {
|
for name, quantity := range container.Resources.Requests {
|
||||||
if value, ok := reqs[name]; !ok {
|
if value, ok := reqs[name]; !ok {
|
||||||
reqs[name] = *quantity.Copy()
|
reqs[name] = *quantity.Copy()
|
||||||
} else if err = value.Add(quantity); err != nil {
|
} else {
|
||||||
return nil, nil, err
|
value.Add(quantity)
|
||||||
|
reqs[name] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for name, quantity := range container.Resources.Limits {
|
for name, quantity := range container.Resources.Limits {
|
||||||
if value, ok := limits[name]; !ok {
|
if value, ok := limits[name]; !ok {
|
||||||
limits[name] = *quantity.Copy()
|
limits[name] = *quantity.Copy()
|
||||||
} else if err = value.Add(quantity); err != nil {
|
} else {
|
||||||
return nil, nil, err
|
value.Add(quantity)
|
||||||
|
limits[name] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,10 @@ func TestResourceHelpers(t *testing.T) {
|
|||||||
"kube.io/storage": memoryLimit,
|
"kube.io/storage": memoryLimit,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if res := resourceSpec.Limits.Cpu(); *res != cpuLimit {
|
if res := resourceSpec.Limits.Cpu(); res.Cmp(cpuLimit) != 0 {
|
||||||
t.Errorf("expected cpulimit %v, got %v", cpuLimit, res)
|
t.Errorf("expected cpulimit %v, got %v", cpuLimit, res)
|
||||||
}
|
}
|
||||||
if res := resourceSpec.Limits.Memory(); *res != memoryLimit {
|
if res := resourceSpec.Limits.Memory(); res.Cmp(memoryLimit) != 0 {
|
||||||
t.Errorf("expected memorylimit %v, got %v", memoryLimit, res)
|
t.Errorf("expected memorylimit %v, got %v", memoryLimit, res)
|
||||||
}
|
}
|
||||||
resourceSpec = ResourceRequirements{
|
resourceSpec = ResourceRequirements{
|
||||||
@ -47,7 +47,7 @@ func TestResourceHelpers(t *testing.T) {
|
|||||||
if res := resourceSpec.Limits.Cpu(); res.Value() != 0 {
|
if res := resourceSpec.Limits.Cpu(); res.Value() != 0 {
|
||||||
t.Errorf("expected cpulimit %v, got %v", 0, res)
|
t.Errorf("expected cpulimit %v, got %v", 0, res)
|
||||||
}
|
}
|
||||||
if res := resourceSpec.Limits.Memory(); *res != memoryLimit {
|
if res := resourceSpec.Limits.Memory(); res.Cmp(memoryLimit) != 0 {
|
||||||
t.Errorf("expected memorylimit %v, got %v", memoryLimit, res)
|
t.Errorf("expected memorylimit %v, got %v", memoryLimit, res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,13 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg4_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg3_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg3_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg2_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg2_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg7_fields "k8s.io/kubernetes/pkg/fields"
|
pkg6_fields "k8s.io/kubernetes/pkg/fields"
|
||||||
pkg6_labels "k8s.io/kubernetes/pkg/labels"
|
pkg5_labels "k8s.io/kubernetes/pkg/labels"
|
||||||
pkg8_runtime "k8s.io/kubernetes/pkg/runtime"
|
pkg7_runtime "k8s.io/kubernetes/pkg/runtime"
|
||||||
pkg1_types "k8s.io/kubernetes/pkg/types"
|
pkg1_types "k8s.io/kubernetes/pkg/types"
|
||||||
pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
pkg4_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -68,16 +67,15 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg4_inf_v0.Dec
|
var v0 pkg3_resource.Quantity
|
||||||
var v1 pkg3_resource.Quantity
|
var v1 pkg2_unversioned.Time
|
||||||
var v2 pkg2_unversioned.Time
|
var v2 pkg6_fields.Selector
|
||||||
var v3 pkg7_fields.Selector
|
var v3 pkg5_labels.Selector
|
||||||
var v4 pkg6_labels.Selector
|
var v4 pkg7_runtime.Object
|
||||||
var v5 pkg8_runtime.Object
|
var v5 pkg1_types.UID
|
||||||
var v6 pkg1_types.UID
|
var v6 pkg4_intstr.IntOrString
|
||||||
var v7 pkg5_intstr.IntOrString
|
var v7 time.Time
|
||||||
var v8 time.Time
|
_, _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6, v7
|
||||||
_, _, _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6, v7, v8
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16227,7 +16225,7 @@ func (x *HTTPGetAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
case "port":
|
case "port":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Port = pkg5_intstr.IntOrString{}
|
x.Port = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv5 := &x.Port
|
yyv5 := &x.Port
|
||||||
yym6 := z.DecBinary()
|
yym6 := z.DecBinary()
|
||||||
@ -16306,7 +16304,7 @@ func (x *HTTPGetAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Port = pkg5_intstr.IntOrString{}
|
x.Port = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv13 := &x.Port
|
yyv13 := &x.Port
|
||||||
yym14 := z.DecBinary()
|
yym14 := z.DecBinary()
|
||||||
@ -16542,7 +16540,7 @@ func (x *TCPSocketAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
switch yys3 {
|
switch yys3 {
|
||||||
case "port":
|
case "port":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Port = pkg5_intstr.IntOrString{}
|
x.Port = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv4 := &x.Port
|
yyv4 := &x.Port
|
||||||
yym5 := z.DecBinary()
|
yym5 := z.DecBinary()
|
||||||
@ -16581,7 +16579,7 @@ func (x *TCPSocketAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Port = pkg5_intstr.IntOrString{}
|
x.Port = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv7 := &x.Port
|
yyv7 := &x.Port
|
||||||
yym8 := z.DecBinary()
|
yym8 := z.DecBinary()
|
||||||
@ -31535,7 +31533,7 @@ func (x *ServicePort) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
case "targetPort":
|
case "targetPort":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.TargetPort = pkg5_intstr.IntOrString{}
|
x.TargetPort = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv7 := &x.TargetPort
|
yyv7 := &x.TargetPort
|
||||||
yym8 := z.DecBinary()
|
yym8 := z.DecBinary()
|
||||||
@ -31628,7 +31626,7 @@ func (x *ServicePort) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.TargetPort = pkg5_intstr.IntOrString{}
|
x.TargetPort = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv14 := &x.TargetPort
|
yyv14 := &x.TargetPort
|
||||||
yym15 := z.DecBinary()
|
yym15 := z.DecBinary()
|
||||||
@ -45477,7 +45475,7 @@ func (x *List) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
_ = yym9
|
_ = yym9
|
||||||
if false {
|
if false {
|
||||||
} else {
|
} else {
|
||||||
h.encSliceruntime_Object(([]pkg8_runtime.Object)(x.Items), e)
|
h.encSliceruntime_Object(([]pkg7_runtime.Object)(x.Items), e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -45491,7 +45489,7 @@ func (x *List) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
_ = yym10
|
_ = yym10
|
||||||
if false {
|
if false {
|
||||||
} else {
|
} else {
|
||||||
h.encSliceruntime_Object(([]pkg8_runtime.Object)(x.Items), e)
|
h.encSliceruntime_Object(([]pkg7_runtime.Object)(x.Items), e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45628,7 +45626,7 @@ func (x *List) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
_ = yym7
|
_ = yym7
|
||||||
if false {
|
if false {
|
||||||
} else {
|
} else {
|
||||||
h.decSliceruntime_Object((*[]pkg8_runtime.Object)(yyv6), d)
|
h.decSliceruntime_Object((*[]pkg7_runtime.Object)(yyv6), d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "kind":
|
case "kind":
|
||||||
@ -45699,7 +45697,7 @@ func (x *List) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
_ = yym14
|
_ = yym14
|
||||||
if false {
|
if false {
|
||||||
} else {
|
} else {
|
||||||
h.decSliceruntime_Object((*[]pkg8_runtime.Object)(yyv13), d)
|
h.decSliceruntime_Object((*[]pkg7_runtime.Object)(yyv13), d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
yyj10++
|
yyj10++
|
||||||
@ -56094,7 +56092,7 @@ func (x codecSelfer1234) decResourceList(v *ResourceList, d *codec1978.Decoder)
|
|||||||
yyl1 := r.ReadMapStart()
|
yyl1 := r.ReadMapStart()
|
||||||
yybh1 := z.DecBasicHandle()
|
yybh1 := z.DecBasicHandle()
|
||||||
if yyv1 == nil {
|
if yyv1 == nil {
|
||||||
yyrl1, _ := z.DecInferLen(yyl1, yybh1.MaxInitLen, 40)
|
yyrl1, _ := z.DecInferLen(yyl1, yybh1.MaxInitLen, 80)
|
||||||
yyv1 = make(map[ResourceName]pkg3_resource.Quantity, yyrl1)
|
yyv1 = make(map[ResourceName]pkg3_resource.Quantity, yyrl1)
|
||||||
*v = yyv1
|
*v = yyv1
|
||||||
}
|
}
|
||||||
@ -56643,7 +56641,7 @@ func (x codecSelfer1234) decSliceEvent(v *[]Event, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x codecSelfer1234) encSliceruntime_Object(v []pkg8_runtime.Object, e *codec1978.Encoder) {
|
func (x codecSelfer1234) encSliceruntime_Object(v []pkg7_runtime.Object, e *codec1978.Encoder) {
|
||||||
var h codecSelfer1234
|
var h codecSelfer1234
|
||||||
z, r := codec1978.GenHelperEncoder(e)
|
z, r := codec1978.GenHelperEncoder(e)
|
||||||
_, _, _ = h, z, r
|
_, _, _ = h, z, r
|
||||||
@ -56665,7 +56663,7 @@ func (x codecSelfer1234) encSliceruntime_Object(v []pkg8_runtime.Object, e *code
|
|||||||
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
|
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg8_runtime.Object, d *codec1978.Decoder) {
|
func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg7_runtime.Object, d *codec1978.Decoder) {
|
||||||
var h codecSelfer1234
|
var h codecSelfer1234
|
||||||
z, r := codec1978.GenHelperDecoder(d)
|
z, r := codec1978.GenHelperDecoder(d)
|
||||||
_, _, _ = h, z, r
|
_, _, _ = h, z, r
|
||||||
@ -56676,7 +56674,7 @@ func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg8_runtime.Object, d *cod
|
|||||||
_ = yyc1
|
_ = yyc1
|
||||||
if yyl1 == 0 {
|
if yyl1 == 0 {
|
||||||
if yyv1 == nil {
|
if yyv1 == nil {
|
||||||
yyv1 = []pkg8_runtime.Object{}
|
yyv1 = []pkg7_runtime.Object{}
|
||||||
yyc1 = true
|
yyc1 = true
|
||||||
} else if len(yyv1) != 0 {
|
} else if len(yyv1) != 0 {
|
||||||
yyv1 = yyv1[:0]
|
yyv1 = yyv1[:0]
|
||||||
@ -56696,10 +56694,10 @@ func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg8_runtime.Object, d *cod
|
|||||||
if yyrl1 <= cap(yyv1) {
|
if yyrl1 <= cap(yyv1) {
|
||||||
yyv1 = yyv1[:yyrl1]
|
yyv1 = yyv1[:yyrl1]
|
||||||
} else {
|
} else {
|
||||||
yyv1 = make([]pkg8_runtime.Object, yyrl1)
|
yyv1 = make([]pkg7_runtime.Object, yyrl1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
yyv1 = make([]pkg8_runtime.Object, yyrl1)
|
yyv1 = make([]pkg7_runtime.Object, yyrl1)
|
||||||
}
|
}
|
||||||
yyc1 = true
|
yyc1 = true
|
||||||
yyrr1 = len(yyv1)
|
yyrr1 = len(yyv1)
|
||||||
@ -56752,7 +56750,7 @@ func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg8_runtime.Object, d *cod
|
|||||||
for ; !r.CheckBreak(); yyj1++ {
|
for ; !r.CheckBreak(); yyj1++ {
|
||||||
|
|
||||||
if yyj1 >= len(yyv1) {
|
if yyj1 >= len(yyv1) {
|
||||||
yyv1 = append(yyv1, nil) // var yyz1 pkg8_runtime.Object
|
yyv1 = append(yyv1, nil) // var yyz1 pkg7_runtime.Object
|
||||||
yyc1 = true
|
yyc1 = true
|
||||||
}
|
}
|
||||||
yyh1.ElemContainerState(yyj1)
|
yyh1.ElemContainerState(yyj1)
|
||||||
@ -56779,7 +56777,7 @@ func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg8_runtime.Object, d *cod
|
|||||||
yyv1 = yyv1[:yyj1]
|
yyv1 = yyv1[:yyj1]
|
||||||
yyc1 = true
|
yyc1 = true
|
||||||
} else if yyj1 == 0 && yyv1 == nil {
|
} else if yyj1 == 0 && yyv1 == nil {
|
||||||
yyv1 = []pkg8_runtime.Object{}
|
yyv1 = []pkg7_runtime.Object{}
|
||||||
yyc1 = true
|
yyc1 = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
inf "gopkg.in/inf.v0"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/conversion"
|
"k8s.io/kubernetes/pkg/conversion"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@ -670,8 +668,8 @@ func Convert_v1_ResourceList_To_api_ResourceList(in *ResourceList, out *api.Reso
|
|||||||
|
|
||||||
// TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
|
// TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
|
||||||
// In the future, we should instead reject values that need rounding.
|
// In the future, we should instead reject values that need rounding.
|
||||||
const milliScale = 3
|
const milliScale = -3
|
||||||
value.Amount.Round(value.Amount, milliScale, inf.RoundUp)
|
value.RoundUp(milliScale)
|
||||||
|
|
||||||
converted[api.ResourceName(key)] = *value
|
converted[api.ResourceName(key)] = *value
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg4_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg3_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg3_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg2_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg2_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg6_runtime "k8s.io/kubernetes/pkg/runtime"
|
pkg5_runtime "k8s.io/kubernetes/pkg/runtime"
|
||||||
pkg1_types "k8s.io/kubernetes/pkg/types"
|
pkg1_types "k8s.io/kubernetes/pkg/types"
|
||||||
pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
pkg4_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -66,14 +65,13 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg4_inf_v0.Dec
|
var v0 pkg3_resource.Quantity
|
||||||
var v1 pkg3_resource.Quantity
|
var v1 pkg2_unversioned.Time
|
||||||
var v2 pkg2_unversioned.Time
|
var v2 pkg5_runtime.RawExtension
|
||||||
var v3 pkg6_runtime.RawExtension
|
var v3 pkg1_types.UID
|
||||||
var v4 pkg1_types.UID
|
var v4 pkg4_intstr.IntOrString
|
||||||
var v5 pkg5_intstr.IntOrString
|
var v5 time.Time
|
||||||
var v6 time.Time
|
_, _, _, _, _, _ = v0, v1, v2, v3, v4, v5
|
||||||
_, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15844,7 +15842,7 @@ func (x *HTTPGetAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
case "port":
|
case "port":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Port = pkg5_intstr.IntOrString{}
|
x.Port = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv5 := &x.Port
|
yyv5 := &x.Port
|
||||||
yym6 := z.DecBinary()
|
yym6 := z.DecBinary()
|
||||||
@ -15923,7 +15921,7 @@ func (x *HTTPGetAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Port = pkg5_intstr.IntOrString{}
|
x.Port = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv13 := &x.Port
|
yyv13 := &x.Port
|
||||||
yym14 := z.DecBinary()
|
yym14 := z.DecBinary()
|
||||||
@ -16152,7 +16150,7 @@ func (x *TCPSocketAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
switch yys3 {
|
switch yys3 {
|
||||||
case "port":
|
case "port":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Port = pkg5_intstr.IntOrString{}
|
x.Port = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv4 := &x.Port
|
yyv4 := &x.Port
|
||||||
yym5 := z.DecBinary()
|
yym5 := z.DecBinary()
|
||||||
@ -16191,7 +16189,7 @@ func (x *TCPSocketAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Port = pkg5_intstr.IntOrString{}
|
x.Port = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv7 := &x.Port
|
yyv7 := &x.Port
|
||||||
yym8 := z.DecBinary()
|
yym8 := z.DecBinary()
|
||||||
@ -31024,7 +31022,7 @@ func (x *ServicePort) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
case "targetPort":
|
case "targetPort":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.TargetPort = pkg5_intstr.IntOrString{}
|
x.TargetPort = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv7 := &x.TargetPort
|
yyv7 := &x.TargetPort
|
||||||
yym8 := z.DecBinary()
|
yym8 := z.DecBinary()
|
||||||
@ -31117,7 +31115,7 @@ func (x *ServicePort) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.TargetPort = pkg5_intstr.IntOrString{}
|
x.TargetPort = pkg4_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv14 := &x.TargetPort
|
yyv14 := &x.TargetPort
|
||||||
yym15 := z.DecBinary()
|
yym15 := z.DecBinary()
|
||||||
@ -45289,7 +45287,7 @@ func (x *List) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
_ = yym9
|
_ = yym9
|
||||||
if false {
|
if false {
|
||||||
} else {
|
} else {
|
||||||
h.encSliceruntime_RawExtension(([]pkg6_runtime.RawExtension)(x.Items), e)
|
h.encSliceruntime_RawExtension(([]pkg5_runtime.RawExtension)(x.Items), e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -45303,7 +45301,7 @@ func (x *List) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
_ = yym10
|
_ = yym10
|
||||||
if false {
|
if false {
|
||||||
} else {
|
} else {
|
||||||
h.encSliceruntime_RawExtension(([]pkg6_runtime.RawExtension)(x.Items), e)
|
h.encSliceruntime_RawExtension(([]pkg5_runtime.RawExtension)(x.Items), e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45440,7 +45438,7 @@ func (x *List) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
_ = yym7
|
_ = yym7
|
||||||
if false {
|
if false {
|
||||||
} else {
|
} else {
|
||||||
h.decSliceruntime_RawExtension((*[]pkg6_runtime.RawExtension)(yyv6), d)
|
h.decSliceruntime_RawExtension((*[]pkg5_runtime.RawExtension)(yyv6), d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "kind":
|
case "kind":
|
||||||
@ -45511,7 +45509,7 @@ func (x *List) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
_ = yym14
|
_ = yym14
|
||||||
if false {
|
if false {
|
||||||
} else {
|
} else {
|
||||||
h.decSliceruntime_RawExtension((*[]pkg6_runtime.RawExtension)(yyv13), d)
|
h.decSliceruntime_RawExtension((*[]pkg5_runtime.RawExtension)(yyv13), d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
yyj10++
|
yyj10++
|
||||||
@ -56147,7 +56145,7 @@ func (x codecSelfer1234) decResourceList(v *ResourceList, d *codec1978.Decoder)
|
|||||||
yyl1 := r.ReadMapStart()
|
yyl1 := r.ReadMapStart()
|
||||||
yybh1 := z.DecBasicHandle()
|
yybh1 := z.DecBasicHandle()
|
||||||
if yyv1 == nil {
|
if yyv1 == nil {
|
||||||
yyrl1, _ := z.DecInferLen(yyl1, yybh1.MaxInitLen, 40)
|
yyrl1, _ := z.DecInferLen(yyl1, yybh1.MaxInitLen, 80)
|
||||||
yyv1 = make(map[ResourceName]pkg3_resource.Quantity, yyrl1)
|
yyv1 = make(map[ResourceName]pkg3_resource.Quantity, yyrl1)
|
||||||
*v = yyv1
|
*v = yyv1
|
||||||
}
|
}
|
||||||
@ -56696,7 +56694,7 @@ func (x codecSelfer1234) decSliceEvent(v *[]Event, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x codecSelfer1234) encSliceruntime_RawExtension(v []pkg6_runtime.RawExtension, e *codec1978.Encoder) {
|
func (x codecSelfer1234) encSliceruntime_RawExtension(v []pkg5_runtime.RawExtension, e *codec1978.Encoder) {
|
||||||
var h codecSelfer1234
|
var h codecSelfer1234
|
||||||
z, r := codec1978.GenHelperEncoder(e)
|
z, r := codec1978.GenHelperEncoder(e)
|
||||||
_, _, _ = h, z, r
|
_, _, _ = h, z, r
|
||||||
@ -56717,7 +56715,7 @@ func (x codecSelfer1234) encSliceruntime_RawExtension(v []pkg6_runtime.RawExtens
|
|||||||
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
|
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExtension, d *codec1978.Decoder) {
|
func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg5_runtime.RawExtension, d *codec1978.Decoder) {
|
||||||
var h codecSelfer1234
|
var h codecSelfer1234
|
||||||
z, r := codec1978.GenHelperDecoder(d)
|
z, r := codec1978.GenHelperDecoder(d)
|
||||||
_, _, _ = h, z, r
|
_, _, _ = h, z, r
|
||||||
@ -56728,7 +56726,7 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten
|
|||||||
_ = yyc1
|
_ = yyc1
|
||||||
if yyl1 == 0 {
|
if yyl1 == 0 {
|
||||||
if yyv1 == nil {
|
if yyv1 == nil {
|
||||||
yyv1 = []pkg6_runtime.RawExtension{}
|
yyv1 = []pkg5_runtime.RawExtension{}
|
||||||
yyc1 = true
|
yyc1 = true
|
||||||
} else if len(yyv1) != 0 {
|
} else if len(yyv1) != 0 {
|
||||||
yyv1 = yyv1[:0]
|
yyv1 = yyv1[:0]
|
||||||
@ -56748,10 +56746,10 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten
|
|||||||
if yyrl1 <= cap(yyv1) {
|
if yyrl1 <= cap(yyv1) {
|
||||||
yyv1 = yyv1[:yyrl1]
|
yyv1 = yyv1[:yyrl1]
|
||||||
} else {
|
} else {
|
||||||
yyv1 = make([]pkg6_runtime.RawExtension, yyrl1)
|
yyv1 = make([]pkg5_runtime.RawExtension, yyrl1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
yyv1 = make([]pkg6_runtime.RawExtension, yyrl1)
|
yyv1 = make([]pkg5_runtime.RawExtension, yyrl1)
|
||||||
}
|
}
|
||||||
yyc1 = true
|
yyc1 = true
|
||||||
yyrr1 = len(yyv1)
|
yyrr1 = len(yyv1)
|
||||||
@ -56766,7 +56764,7 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten
|
|||||||
for ; yyj1 < yyrr1; yyj1++ {
|
for ; yyj1 < yyrr1; yyj1++ {
|
||||||
yyh1.ElemContainerState(yyj1)
|
yyh1.ElemContainerState(yyj1)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
yyv1[yyj1] = pkg6_runtime.RawExtension{}
|
yyv1[yyj1] = pkg5_runtime.RawExtension{}
|
||||||
} else {
|
} else {
|
||||||
yyv2 := &yyv1[yyj1]
|
yyv2 := &yyv1[yyj1]
|
||||||
yym3 := z.DecBinary()
|
yym3 := z.DecBinary()
|
||||||
@ -56783,10 +56781,10 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten
|
|||||||
}
|
}
|
||||||
if yyrt1 {
|
if yyrt1 {
|
||||||
for ; yyj1 < yyl1; yyj1++ {
|
for ; yyj1 < yyl1; yyj1++ {
|
||||||
yyv1 = append(yyv1, pkg6_runtime.RawExtension{})
|
yyv1 = append(yyv1, pkg5_runtime.RawExtension{})
|
||||||
yyh1.ElemContainerState(yyj1)
|
yyh1.ElemContainerState(yyj1)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
yyv1[yyj1] = pkg6_runtime.RawExtension{}
|
yyv1[yyj1] = pkg5_runtime.RawExtension{}
|
||||||
} else {
|
} else {
|
||||||
yyv4 := &yyv1[yyj1]
|
yyv4 := &yyv1[yyj1]
|
||||||
yym5 := z.DecBinary()
|
yym5 := z.DecBinary()
|
||||||
@ -56808,13 +56806,13 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten
|
|||||||
for ; !r.CheckBreak(); yyj1++ {
|
for ; !r.CheckBreak(); yyj1++ {
|
||||||
|
|
||||||
if yyj1 >= len(yyv1) {
|
if yyj1 >= len(yyv1) {
|
||||||
yyv1 = append(yyv1, pkg6_runtime.RawExtension{}) // var yyz1 pkg6_runtime.RawExtension
|
yyv1 = append(yyv1, pkg5_runtime.RawExtension{}) // var yyz1 pkg5_runtime.RawExtension
|
||||||
yyc1 = true
|
yyc1 = true
|
||||||
}
|
}
|
||||||
yyh1.ElemContainerState(yyj1)
|
yyh1.ElemContainerState(yyj1)
|
||||||
if yyj1 < len(yyv1) {
|
if yyj1 < len(yyv1) {
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
yyv1[yyj1] = pkg6_runtime.RawExtension{}
|
yyv1[yyj1] = pkg5_runtime.RawExtension{}
|
||||||
} else {
|
} else {
|
||||||
yyv6 := &yyv1[yyj1]
|
yyv6 := &yyv1[yyj1]
|
||||||
yym7 := z.DecBinary()
|
yym7 := z.DecBinary()
|
||||||
@ -56837,7 +56835,7 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten
|
|||||||
yyv1 = yyv1[:yyj1]
|
yyv1 = yyv1[:yyj1]
|
||||||
yyc1 = true
|
yyc1 = true
|
||||||
} else if yyj1 == 0 && yyv1 == nil {
|
} else if yyj1 == 0 && yyv1 == nil {
|
||||||
yyv1 = []pkg6_runtime.RawExtension{}
|
yyv1 = []pkg5_runtime.RawExtension{}
|
||||||
yyc1 = true
|
yyc1 = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg5_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg2_api "k8s.io/kubernetes/pkg/api"
|
pkg2_api "k8s.io/kubernetes/pkg/api"
|
||||||
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg3_types "k8s.io/kubernetes/pkg/types"
|
pkg3_types "k8s.io/kubernetes/pkg/types"
|
||||||
pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -66,14 +65,13 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg5_inf_v0.Dec
|
var v0 pkg2_api.ObjectMeta
|
||||||
var v1 pkg2_api.ObjectMeta
|
var v1 pkg4_resource.Quantity
|
||||||
var v2 pkg4_resource.Quantity
|
var v2 pkg1_unversioned.TypeMeta
|
||||||
var v3 pkg1_unversioned.TypeMeta
|
var v3 pkg3_types.UID
|
||||||
var v4 pkg3_types.UID
|
var v4 pkg5_intstr.IntOrString
|
||||||
var v5 pkg6_intstr.IntOrString
|
var v5 time.Time
|
||||||
var v6 time.Time
|
_, _, _, _, _, _ = v0, v1, v2, v3, v4, v5
|
||||||
_, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +25,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg5_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg2_v1 "k8s.io/kubernetes/pkg/api/v1"
|
pkg2_v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||||
pkg3_types "k8s.io/kubernetes/pkg/types"
|
pkg3_types "k8s.io/kubernetes/pkg/types"
|
||||||
pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -66,14 +65,13 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg5_inf_v0.Dec
|
var v0 pkg4_resource.Quantity
|
||||||
var v1 pkg4_resource.Quantity
|
var v1 pkg1_unversioned.TypeMeta
|
||||||
var v2 pkg1_unversioned.TypeMeta
|
var v2 pkg2_v1.ObjectMeta
|
||||||
var v3 pkg2_v1.ObjectMeta
|
var v3 pkg3_types.UID
|
||||||
var v4 pkg3_types.UID
|
var v4 pkg5_intstr.IntOrString
|
||||||
var v5 pkg6_intstr.IntOrString
|
var v5 time.Time
|
||||||
var v6 time.Time
|
_, _, _, _, _, _ = v0, v1, v2, v3, v4, v5
|
||||||
_, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +25,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg5_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg2_api "k8s.io/kubernetes/pkg/api"
|
pkg2_api "k8s.io/kubernetes/pkg/api"
|
||||||
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg3_types "k8s.io/kubernetes/pkg/types"
|
pkg3_types "k8s.io/kubernetes/pkg/types"
|
||||||
pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -66,14 +65,13 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg5_inf_v0.Dec
|
var v0 pkg2_api.ObjectMeta
|
||||||
var v1 pkg2_api.ObjectMeta
|
var v1 pkg4_resource.Quantity
|
||||||
var v2 pkg4_resource.Quantity
|
var v2 pkg1_unversioned.TypeMeta
|
||||||
var v3 pkg1_unversioned.TypeMeta
|
var v3 pkg3_types.UID
|
||||||
var v4 pkg3_types.UID
|
var v4 pkg5_intstr.IntOrString
|
||||||
var v5 pkg6_intstr.IntOrString
|
var v5 time.Time
|
||||||
var v6 time.Time
|
_, _, _, _, _, _ = v0, v1, v2, v3, v4, v5
|
||||||
_, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +25,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg5_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg2_v1 "k8s.io/kubernetes/pkg/api/v1"
|
pkg2_v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||||
pkg3_types "k8s.io/kubernetes/pkg/types"
|
pkg3_types "k8s.io/kubernetes/pkg/types"
|
||||||
pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -66,14 +65,13 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg5_inf_v0.Dec
|
var v0 pkg4_resource.Quantity
|
||||||
var v1 pkg4_resource.Quantity
|
var v1 pkg1_unversioned.TypeMeta
|
||||||
var v2 pkg1_unversioned.TypeMeta
|
var v2 pkg2_v1.ObjectMeta
|
||||||
var v3 pkg2_v1.ObjectMeta
|
var v3 pkg3_types.UID
|
||||||
var v4 pkg3_types.UID
|
var v4 pkg5_intstr.IntOrString
|
||||||
var v5 pkg6_intstr.IntOrString
|
var v5 time.Time
|
||||||
var v6 time.Time
|
_, _, _, _, _, _ = v0, v1, v2, v3, v4, v5
|
||||||
_, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +25,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg5_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg2_v1 "k8s.io/kubernetes/pkg/api/v1"
|
pkg2_v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||||
pkg3_types "k8s.io/kubernetes/pkg/types"
|
pkg3_types "k8s.io/kubernetes/pkg/types"
|
||||||
pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -66,14 +65,13 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg5_inf_v0.Dec
|
var v0 pkg4_resource.Quantity
|
||||||
var v1 pkg4_resource.Quantity
|
var v1 pkg1_unversioned.TypeMeta
|
||||||
var v2 pkg1_unversioned.TypeMeta
|
var v2 pkg2_v1.ObjectMeta
|
||||||
var v3 pkg2_v1.ObjectMeta
|
var v3 pkg3_types.UID
|
||||||
var v4 pkg3_types.UID
|
var v4 pkg5_intstr.IntOrString
|
||||||
var v5 pkg6_intstr.IntOrString
|
var v5 time.Time
|
||||||
var v6 time.Time
|
_, _, _, _, _, _ = v0, v1, v2, v3, v4, v5
|
||||||
_, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +25,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg5_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg2_api "k8s.io/kubernetes/pkg/api"
|
pkg2_api "k8s.io/kubernetes/pkg/api"
|
||||||
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg3_types "k8s.io/kubernetes/pkg/types"
|
pkg3_types "k8s.io/kubernetes/pkg/types"
|
||||||
pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -66,14 +65,13 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg5_inf_v0.Dec
|
var v0 pkg2_api.ObjectMeta
|
||||||
var v1 pkg2_api.ObjectMeta
|
var v1 pkg4_resource.Quantity
|
||||||
var v2 pkg4_resource.Quantity
|
var v2 pkg1_unversioned.LabelSelector
|
||||||
var v3 pkg1_unversioned.LabelSelector
|
var v3 pkg3_types.UID
|
||||||
var v4 pkg3_types.UID
|
var v4 pkg5_intstr.IntOrString
|
||||||
var v5 pkg6_intstr.IntOrString
|
var v5 time.Time
|
||||||
var v6 time.Time
|
_, _, _, _, _, _ = v0, v1, v2, v3, v4, v5
|
||||||
_, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4916,7 +4914,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromMap(l int, d *codec1978.Dec
|
|||||||
switch yys3 {
|
switch yys3 {
|
||||||
case "maxUnavailable":
|
case "maxUnavailable":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.MaxUnavailable = pkg6_intstr.IntOrString{}
|
x.MaxUnavailable = pkg5_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv4 := &x.MaxUnavailable
|
yyv4 := &x.MaxUnavailable
|
||||||
yym5 := z.DecBinary()
|
yym5 := z.DecBinary()
|
||||||
@ -4931,7 +4929,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromMap(l int, d *codec1978.Dec
|
|||||||
}
|
}
|
||||||
case "maxSurge":
|
case "maxSurge":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.MaxSurge = pkg6_intstr.IntOrString{}
|
x.MaxSurge = pkg5_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv6 := &x.MaxSurge
|
yyv6 := &x.MaxSurge
|
||||||
yym7 := z.DecBinary()
|
yym7 := z.DecBinary()
|
||||||
@ -4970,7 +4968,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromArray(l int, d *codec1978.D
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.MaxUnavailable = pkg6_intstr.IntOrString{}
|
x.MaxUnavailable = pkg5_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv9 := &x.MaxUnavailable
|
yyv9 := &x.MaxUnavailable
|
||||||
yym10 := z.DecBinary()
|
yym10 := z.DecBinary()
|
||||||
@ -4995,7 +4993,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromArray(l int, d *codec1978.D
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.MaxSurge = pkg6_intstr.IntOrString{}
|
x.MaxSurge = pkg5_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv11 := &x.MaxSurge
|
yyv11 := &x.MaxSurge
|
||||||
yym12 := z.DecBinary()
|
yym12 := z.DecBinary()
|
||||||
@ -9593,7 +9591,7 @@ func (x *IngressBackend) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
case "servicePort":
|
case "servicePort":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.ServicePort = pkg6_intstr.IntOrString{}
|
x.ServicePort = pkg5_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv5 := &x.ServicePort
|
yyv5 := &x.ServicePort
|
||||||
yym6 := z.DecBinary()
|
yym6 := z.DecBinary()
|
||||||
@ -9648,7 +9646,7 @@ func (x *IngressBackend) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.ServicePort = pkg6_intstr.IntOrString{}
|
x.ServicePort = pkg5_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv9 := &x.ServicePort
|
yyv9 := &x.ServicePort
|
||||||
yym10 := z.DecBinary()
|
yym10 := z.DecBinary()
|
||||||
@ -13849,7 +13847,7 @@ func (x codecSelfer1234) decSliceCustomMetricTarget(v *[]CustomMetricTarget, d *
|
|||||||
|
|
||||||
yyrg1 := len(yyv1) > 0
|
yyrg1 := len(yyv1) > 0
|
||||||
yyv21 := yyv1
|
yyv21 := yyv1
|
||||||
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 40)
|
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 80)
|
||||||
if yyrt1 {
|
if yyrt1 {
|
||||||
if yyrl1 <= cap(yyv1) {
|
if yyrl1 <= cap(yyv1) {
|
||||||
yyv1 = yyv1[:yyrl1]
|
yyv1 = yyv1[:yyrl1]
|
||||||
@ -13968,7 +13966,7 @@ func (x codecSelfer1234) decSliceCustomMetricCurrentStatus(v *[]CustomMetricCurr
|
|||||||
|
|
||||||
yyrg1 := len(yyv1) > 0
|
yyrg1 := len(yyv1) > 0
|
||||||
yyv21 := yyv1
|
yyv21 := yyv1
|
||||||
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 40)
|
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 80)
|
||||||
if yyrt1 {
|
if yyrt1 {
|
||||||
if yyrl1 <= cap(yyv1) {
|
if yyrl1 <= cap(yyv1) {
|
||||||
yyv1 = yyv1[:yyrl1]
|
yyv1 = yyv1[:yyrl1]
|
||||||
|
@ -25,12 +25,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
codec1978 "github.com/ugorji/go/codec"
|
codec1978 "github.com/ugorji/go/codec"
|
||||||
pkg5_inf_v0 "gopkg.in/inf.v0"
|
|
||||||
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
pkg4_resource "k8s.io/kubernetes/pkg/api/resource"
|
||||||
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
pkg2_v1 "k8s.io/kubernetes/pkg/api/v1"
|
pkg2_v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||||
pkg3_types "k8s.io/kubernetes/pkg/types"
|
pkg3_types "k8s.io/kubernetes/pkg/types"
|
||||||
pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
time "time"
|
time "time"
|
||||||
@ -66,14 +65,13 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg5_inf_v0.Dec
|
var v0 pkg4_resource.Quantity
|
||||||
var v1 pkg4_resource.Quantity
|
var v1 pkg1_unversioned.TypeMeta
|
||||||
var v2 pkg1_unversioned.TypeMeta
|
var v2 pkg2_v1.ObjectMeta
|
||||||
var v3 pkg2_v1.ObjectMeta
|
var v3 pkg3_types.UID
|
||||||
var v4 pkg3_types.UID
|
var v4 pkg5_intstr.IntOrString
|
||||||
var v5 pkg6_intstr.IntOrString
|
var v5 time.Time
|
||||||
var v6 time.Time
|
_, _, _, _, _, _ = v0, v1, v2, v3, v4, v5
|
||||||
_, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6923,7 +6921,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromMap(l int, d *codec1978.Dec
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if x.MaxUnavailable == nil {
|
if x.MaxUnavailable == nil {
|
||||||
x.MaxUnavailable = new(pkg6_intstr.IntOrString)
|
x.MaxUnavailable = new(pkg5_intstr.IntOrString)
|
||||||
}
|
}
|
||||||
yym5 := z.DecBinary()
|
yym5 := z.DecBinary()
|
||||||
_ = yym5
|
_ = yym5
|
||||||
@ -6942,7 +6940,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromMap(l int, d *codec1978.Dec
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if x.MaxSurge == nil {
|
if x.MaxSurge == nil {
|
||||||
x.MaxSurge = new(pkg6_intstr.IntOrString)
|
x.MaxSurge = new(pkg5_intstr.IntOrString)
|
||||||
}
|
}
|
||||||
yym7 := z.DecBinary()
|
yym7 := z.DecBinary()
|
||||||
_ = yym7
|
_ = yym7
|
||||||
@ -6985,7 +6983,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromArray(l int, d *codec1978.D
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if x.MaxUnavailable == nil {
|
if x.MaxUnavailable == nil {
|
||||||
x.MaxUnavailable = new(pkg6_intstr.IntOrString)
|
x.MaxUnavailable = new(pkg5_intstr.IntOrString)
|
||||||
}
|
}
|
||||||
yym10 := z.DecBinary()
|
yym10 := z.DecBinary()
|
||||||
_ = yym10
|
_ = yym10
|
||||||
@ -7014,7 +7012,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromArray(l int, d *codec1978.D
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if x.MaxSurge == nil {
|
if x.MaxSurge == nil {
|
||||||
x.MaxSurge = new(pkg6_intstr.IntOrString)
|
x.MaxSurge = new(pkg5_intstr.IntOrString)
|
||||||
}
|
}
|
||||||
yym12 := z.DecBinary()
|
yym12 := z.DecBinary()
|
||||||
_ = yym12
|
_ = yym12
|
||||||
@ -13794,7 +13792,7 @@ func (x *IngressBackend) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
case "servicePort":
|
case "servicePort":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.ServicePort = pkg6_intstr.IntOrString{}
|
x.ServicePort = pkg5_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv5 := &x.ServicePort
|
yyv5 := &x.ServicePort
|
||||||
yym6 := z.DecBinary()
|
yym6 := z.DecBinary()
|
||||||
@ -13849,7 +13847,7 @@ func (x *IngressBackend) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.ServicePort = pkg6_intstr.IntOrString{}
|
x.ServicePort = pkg5_intstr.IntOrString{}
|
||||||
} else {
|
} else {
|
||||||
yyv9 := &x.ServicePort
|
yyv9 := &x.ServicePort
|
||||||
yym10 := z.DecBinary()
|
yym10 := z.DecBinary()
|
||||||
@ -19393,7 +19391,7 @@ func (x codecSelfer1234) decSliceCustomMetricTarget(v *[]CustomMetricTarget, d *
|
|||||||
|
|
||||||
yyrg1 := len(yyv1) > 0
|
yyrg1 := len(yyv1) > 0
|
||||||
yyv21 := yyv1
|
yyv21 := yyv1
|
||||||
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 40)
|
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 80)
|
||||||
if yyrt1 {
|
if yyrt1 {
|
||||||
if yyrl1 <= cap(yyv1) {
|
if yyrl1 <= cap(yyv1) {
|
||||||
yyv1 = yyv1[:yyrl1]
|
yyv1 = yyv1[:yyrl1]
|
||||||
@ -19512,7 +19510,7 @@ func (x codecSelfer1234) decSliceCustomMetricCurrentStatus(v *[]CustomMetricCurr
|
|||||||
|
|
||||||
yyrg1 := len(yyv1) > 0
|
yyrg1 := len(yyv1) > 0
|
||||||
yyv21 := yyv1
|
yyv21 := yyv1
|
||||||
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 40)
|
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 80)
|
||||||
if yyrt1 {
|
if yyrt1 {
|
||||||
if yyrl1 <= cap(yyv1) {
|
if yyrl1 <= cap(yyv1) {
|
||||||
yyv1 = yyv1[:yyrl1]
|
yyv1 = yyv1[:yyrl1]
|
||||||
|
@ -44,10 +44,7 @@ func newPVC(name string) api.PersistentVolumeClaim {
|
|||||||
Spec: api.PersistentVolumeClaimSpec{
|
Spec: api.PersistentVolumeClaimSpec{
|
||||||
Resources: api.ResourceRequirements{
|
Resources: api.ResourceRequirements{
|
||||||
Requests: api.ResourceList{
|
Requests: api.ResourceList{
|
||||||
api.ResourceStorage: resource.Quantity{
|
api.ResourceStorage: *resource.NewQuantity(1, resource.BinarySI),
|
||||||
Amount: dec(1, 0),
|
|
||||||
Format: resource.BinarySI,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -237,7 +237,7 @@ func (a *HorizontalController) computeReplicasForCustomMetrics(hpa *autoscaling.
|
|||||||
}
|
}
|
||||||
statusList.Items = append(statusList.Items, extensions.CustomMetricCurrentStatus{
|
statusList.Items = append(statusList.Items, extensions.CustomMetricCurrentStatus{
|
||||||
Name: customMetricTarget.Name,
|
Name: customMetricTarget.Name,
|
||||||
CurrentValue: *quantity,
|
CurrentValue: quantity,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
byteStatusList, err := json.Marshal(statusList)
|
byteStatusList, err := json.Marshal(statusList)
|
||||||
|
@ -129,8 +129,7 @@ func (h *HeapsterMetricsClient) GetCpuConsumptionAndRequestInMillis(namespace st
|
|||||||
|
|
||||||
podNames = append(podNames, pod.Name)
|
podNames = append(podNames, pod.Name)
|
||||||
for _, container := range pod.Spec.Containers {
|
for _, container := range pod.Spec.Containers {
|
||||||
containerRequest := container.Resources.Requests[api.ResourceCPU]
|
if containerRequest, ok := container.Resources.Requests[api.ResourceCPU]; ok {
|
||||||
if containerRequest.Amount != nil {
|
|
||||||
requestSum += containerRequest.MilliValue()
|
requestSum += containerRequest.MilliValue()
|
||||||
} else {
|
} else {
|
||||||
missing = true
|
missing = true
|
||||||
|
@ -1841,15 +1841,17 @@ func getPodsTotalRequestsAndLimits(podList *api.PodList) (reqs map[api.ResourceN
|
|||||||
for podReqName, podReqValue := range podReqs {
|
for podReqName, podReqValue := range podReqs {
|
||||||
if value, ok := reqs[podReqName]; !ok {
|
if value, ok := reqs[podReqName]; !ok {
|
||||||
reqs[podReqName] = *podReqValue.Copy()
|
reqs[podReqName] = *podReqValue.Copy()
|
||||||
} else if err = value.Add(podReqValue); err != nil {
|
} else {
|
||||||
return nil, nil, err
|
value.Add(podReqValue)
|
||||||
|
reqs[podReqName] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for podLimitName, podLimitValue := range podLimits {
|
for podLimitName, podLimitValue := range podLimits {
|
||||||
if value, ok := limits[podLimitName]; !ok {
|
if value, ok := limits[podLimitName]; !ok {
|
||||||
limits[podLimitName] = *podLimitValue.Copy()
|
limits[podLimitName] = *podLimitValue.Copy()
|
||||||
} else if err = value.Add(podLimitValue); err != nil {
|
} else {
|
||||||
return nil, nil, err
|
value.Add(podLimitValue)
|
||||||
|
limits[podLimitName] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -431,7 +431,7 @@ func TestGetPodsTotalRequests(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error %v", err)
|
t.Errorf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(reqs, testCase.expectedReqs) {
|
if !api.Semantic.DeepEqual(reqs, testCase.expectedReqs) {
|
||||||
t.Errorf("Expected %v, got %v", testCase.expectedReqs, reqs)
|
t.Errorf("Expected %v, got %v", testCase.expectedReqs, reqs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,7 +434,7 @@ func populateResourceList(spec string) (api.ResourceList, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result[resourceName] = *resourceQuantity
|
result[resourceName] = resourceQuantity
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
@ -458,7 +458,7 @@ func populateV1ResourceList(spec string) (v1.ResourceList, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result[resourceName] = *resourceQuantity
|
result[resourceName] = resourceQuantity
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
@ -378,10 +378,12 @@ func TestGenerate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
generator := BasicReplicationController{}
|
generator := BasicReplicationController{}
|
||||||
for _, test := range tests {
|
for i, test := range tests {
|
||||||
obj, err := generator.Generate(test.params)
|
obj, err := generator.Generate(test.params)
|
||||||
|
t.Logf("%d: %#v", i, obj)
|
||||||
if !test.expectErr && err != nil {
|
if !test.expectErr && err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if test.expectErr && err != nil {
|
if test.expectErr && err != nil {
|
||||||
continue
|
continue
|
||||||
|
@ -581,7 +581,7 @@ func (dm *DockerManager) runContainer(
|
|||||||
// If request is not specified, but limit is, we want request to default to limit.
|
// If request is not specified, but limit is, we want request to default to limit.
|
||||||
// API server does this for new containers, but we repeat this logic in Kubelet
|
// API server does this for new containers, but we repeat this logic in Kubelet
|
||||||
// for containers running on existing Kubernetes clusters.
|
// for containers running on existing Kubernetes clusters.
|
||||||
if cpuRequest.Amount == nil && cpuLimit.Amount != nil {
|
if cpuRequest.IsZero() && !cpuLimit.IsZero() {
|
||||||
cpuShares = milliCPUToShares(cpuLimit.MilliValue())
|
cpuShares = milliCPUToShares(cpuLimit.MilliValue())
|
||||||
} else {
|
} else {
|
||||||
// if cpuRequest.Amount is nil, then milliCPUToShares will return the minimal number
|
// if cpuRequest.Amount is nil, then milliCPUToShares will return the minimal number
|
||||||
|
@ -148,7 +148,7 @@ func parseThresholdStatement(statement string) (Threshold, error) {
|
|||||||
return Threshold{
|
return Threshold{
|
||||||
Signal: signal,
|
Signal: signal,
|
||||||
Operator: operator,
|
Operator: operator,
|
||||||
Value: *quantity,
|
Value: &quantity,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,14 +213,10 @@ func podUsage(podStats statsapi.PodStats) (api.ResourceList, error) {
|
|||||||
// disk usage (if known)
|
// disk usage (if known)
|
||||||
// TODO: need to handle volumes
|
// TODO: need to handle volumes
|
||||||
for _, fsStats := range []*statsapi.FsStats{container.Rootfs, container.Logs} {
|
for _, fsStats := range []*statsapi.FsStats{container.Rootfs, container.Logs} {
|
||||||
if err := disk.Add(*diskUsage(fsStats)); err != nil {
|
disk.Add(*diskUsage(fsStats))
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// memory usage (if known)
|
// memory usage (if known)
|
||||||
if err := memory.Add(*memoryUsage(container.Memory)); err != nil {
|
memory.Add(*memoryUsage(container.Memory))
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return api.ResourceList{
|
return api.ResourceList{
|
||||||
api.ResourceMemory: memory,
|
api.ResourceMemory: memory,
|
||||||
@ -430,7 +426,7 @@ func makeSignalObservations(summaryProvider stats.SummaryProvider) (signalObserv
|
|||||||
statsFunc := cachedStatsFunc(summary.Pods)
|
statsFunc := cachedStatsFunc(summary.Pods)
|
||||||
// build an evaluation context for current eviction signals
|
// build an evaluation context for current eviction signals
|
||||||
result := signalObservations{}
|
result := signalObservations{}
|
||||||
result[SignalMemoryAvailable] = *resource.NewQuantity(int64(*summary.Node.Memory.AvailableBytes), resource.BinarySI)
|
result[SignalMemoryAvailable] = resource.NewQuantity(int64(*summary.Node.Memory.AvailableBytes), resource.BinarySI)
|
||||||
return result, statsFunc, nil
|
return result, statsFunc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +442,7 @@ func thresholdsMet(thresholds []Threshold, observations signalObservations) []Th
|
|||||||
}
|
}
|
||||||
// determine if we have met the specified threshold
|
// determine if we have met the specified threshold
|
||||||
thresholdMet := false
|
thresholdMet := false
|
||||||
thresholdResult := threshold.Value.Cmp(observed)
|
thresholdResult := threshold.Value.Cmp(*observed)
|
||||||
switch threshold.Operator {
|
switch threshold.Operator {
|
||||||
case OpLessThan:
|
case OpLessThan:
|
||||||
thresholdMet = thresholdResult > 0
|
thresholdMet = thresholdResult > 0
|
||||||
@ -538,7 +534,7 @@ func hasNodeCondition(inputs []api.NodeConditionType, item api.NodeConditionType
|
|||||||
// hasThreshold returns true if the node condition is in the input list
|
// hasThreshold returns true if the node condition is in the input list
|
||||||
func hasThreshold(inputs []Threshold, item Threshold) bool {
|
func hasThreshold(inputs []Threshold, item Threshold) bool {
|
||||||
for _, input := range inputs {
|
for _, input := range inputs {
|
||||||
if input.GracePeriod == item.GracePeriod && input.Operator == item.Operator && input.Signal == item.Signal && input.Value.Cmp(item.Value) == 0 {
|
if input.GracePeriod == item.GracePeriod && input.Operator == item.Operator && input.Signal == item.Signal && input.Value.Cmp(*item.Value) == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,11 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/types"
|
"k8s.io/kubernetes/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func quantityMustParse(value string) *resource.Quantity {
|
||||||
|
q := resource.MustParse(value)
|
||||||
|
return &q
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseThresholdConfig(t *testing.T) {
|
func TestParseThresholdConfig(t *testing.T) {
|
||||||
gracePeriod, _ := time.ParseDuration("30s")
|
gracePeriod, _ := time.ParseDuration("30s")
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
@ -55,12 +60,12 @@ func TestParseThresholdConfig(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("150Mi"),
|
Value: quantityMustParse("150Mi"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("300Mi"),
|
Value: quantityMustParse("300Mi"),
|
||||||
GracePeriod: gracePeriod,
|
GracePeriod: gracePeriod,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -145,7 +150,7 @@ func thresholdEqual(a Threshold, b Threshold) bool {
|
|||||||
return a.GracePeriod == b.GracePeriod &&
|
return a.GracePeriod == b.GracePeriod &&
|
||||||
a.Operator == b.Operator &&
|
a.Operator == b.Operator &&
|
||||||
a.Signal == b.Signal &&
|
a.Signal == b.Signal &&
|
||||||
a.Value.Cmp(b.Value) == 0
|
a.Value.Cmp(*b.Value) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestOrderedByQoS ensures we order BestEffort < Burstable < Guaranteed
|
// TestOrderedByQoS ensures we order BestEffort < Burstable < Guaranteed
|
||||||
@ -348,7 +353,7 @@ func TestThresholdsMet(t *testing.T) {
|
|||||||
hardThreshold := Threshold{
|
hardThreshold := Threshold{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("1Gi"),
|
Value: quantityMustParse("1Gi"),
|
||||||
}
|
}
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
thresholds []Threshold
|
thresholds []Threshold
|
||||||
@ -363,14 +368,14 @@ func TestThresholdsMet(t *testing.T) {
|
|||||||
"threshold-met": {
|
"threshold-met": {
|
||||||
thresholds: []Threshold{hardThreshold},
|
thresholds: []Threshold{hardThreshold},
|
||||||
observations: signalObservations{
|
observations: signalObservations{
|
||||||
SignalMemoryAvailable: resource.MustParse("500Mi"),
|
SignalMemoryAvailable: quantityMustParse("500Mi"),
|
||||||
},
|
},
|
||||||
result: []Threshold{hardThreshold},
|
result: []Threshold{hardThreshold},
|
||||||
},
|
},
|
||||||
"threshold-not-met": {
|
"threshold-not-met": {
|
||||||
thresholds: []Threshold{hardThreshold},
|
thresholds: []Threshold{hardThreshold},
|
||||||
observations: signalObservations{
|
observations: signalObservations{
|
||||||
SignalMemoryAvailable: resource.MustParse("2Gi"),
|
SignalMemoryAvailable: quantityMustParse("2Gi"),
|
||||||
},
|
},
|
||||||
result: []Threshold{},
|
result: []Threshold{},
|
||||||
},
|
},
|
||||||
@ -387,7 +392,7 @@ func TestThresholdsFirstObservedAt(t *testing.T) {
|
|||||||
hardThreshold := Threshold{
|
hardThreshold := Threshold{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("1Gi"),
|
Value: quantityMustParse("1Gi"),
|
||||||
}
|
}
|
||||||
now := unversioned.Now()
|
now := unversioned.Now()
|
||||||
oldTime := unversioned.NewTime(now.Time.Add(-1 * time.Minute))
|
oldTime := unversioned.NewTime(now.Time.Add(-1 * time.Minute))
|
||||||
@ -435,12 +440,12 @@ func TestThresholdsMetGracePeriod(t *testing.T) {
|
|||||||
hardThreshold := Threshold{
|
hardThreshold := Threshold{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("1Gi"),
|
Value: quantityMustParse("1Gi"),
|
||||||
}
|
}
|
||||||
softThreshold := Threshold{
|
softThreshold := Threshold{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("2Gi"),
|
Value: quantityMustParse("2Gi"),
|
||||||
GracePeriod: 1 * time.Minute,
|
GracePeriod: 1 * time.Minute,
|
||||||
}
|
}
|
||||||
oldTime := unversioned.NewTime(now.Time.Add(-2 * time.Minute))
|
oldTime := unversioned.NewTime(now.Time.Add(-2 * time.Minute))
|
||||||
|
@ -103,7 +103,7 @@ func TestMemoryPressure(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("1Gi"),
|
Value: quantityMustParse("1Gi"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ type Threshold struct {
|
|||||||
// Operator represents a relationship of a signal to a value.
|
// Operator represents a relationship of a signal to a value.
|
||||||
Operator ThresholdOperator
|
Operator ThresholdOperator
|
||||||
// value is a quantity associated with the signal that is evaluated against the specified operator.
|
// value is a quantity associated with the signal that is evaluated against the specified operator.
|
||||||
Value resource.Quantity
|
Value *resource.Quantity
|
||||||
// GracePeriod represents the amount of time that a threshold must be met before eviction is triggered.
|
// GracePeriod represents the amount of time that a threshold must be met before eviction is triggered.
|
||||||
GracePeriod time.Duration
|
GracePeriod time.Duration
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ type statsFunc func(pod *api.Pod) (statsapi.PodStats, bool)
|
|||||||
type rankFunc func(pods []*api.Pod, stats statsFunc)
|
type rankFunc func(pods []*api.Pod, stats statsFunc)
|
||||||
|
|
||||||
// signalObservations maps a signal to an observed quantity
|
// signalObservations maps a signal to an observed quantity
|
||||||
type signalObservations map[Signal]resource.Quantity
|
type signalObservations map[Signal]*resource.Quantity
|
||||||
|
|
||||||
// thresholdsObservedAt maps a threshold to a time that it was observed
|
// thresholdsObservedAt maps a threshold to a time that it was observed
|
||||||
type thresholdsObservedAt map[Threshold]time.Time
|
type thresholdsObservedAt map[Threshold]time.Time
|
||||||
|
@ -3051,7 +3051,7 @@ func (kl *Kubelet) setNodeStatusMachineInfo(node *api.Node) {
|
|||||||
if kl.reservation.Kubernetes != nil {
|
if kl.reservation.Kubernetes != nil {
|
||||||
value.Sub(kl.reservation.Kubernetes[k])
|
value.Sub(kl.reservation.Kubernetes[k])
|
||||||
}
|
}
|
||||||
if value.Amount != nil && value.Amount.Sign() < 0 {
|
if value.Sign() < 0 {
|
||||||
// Negative Allocatable resources don't make sense.
|
// Negative Allocatable resources don't make sense.
|
||||||
value.Set(0)
|
value.Set(0)
|
||||||
}
|
}
|
||||||
|
@ -3853,16 +3853,16 @@ func TestExtractBandwidthResources(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: testPod("10M", ""),
|
pod: testPod("10M", ""),
|
||||||
expectedIngress: ten,
|
expectedIngress: &ten,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: testPod("", "10M"),
|
pod: testPod("", "10M"),
|
||||||
expectedEgress: ten,
|
expectedEgress: &ten,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: testPod("4M", "20M"),
|
pod: testPod("4M", "20M"),
|
||||||
expectedIngress: four,
|
expectedIngress: &four,
|
||||||
expectedEgress: twenty,
|
expectedEgress: &twenty,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: testPod("foo", ""),
|
pod: testPod("foo", ""),
|
||||||
|
@ -93,7 +93,7 @@ func Subtract(a api.ResourceList, b api.ResourceList) api.ResourceList {
|
|||||||
for key, value := range b {
|
for key, value := range b {
|
||||||
if _, found := result[key]; !found {
|
if _, found := result[key]; !found {
|
||||||
quantity := *value.Copy()
|
quantity := *value.Copy()
|
||||||
quantity.Neg(value)
|
quantity.Neg()
|
||||||
result[key] = quantity
|
result[key] = quantity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,18 +38,22 @@ func validateBandwidthIsReasonable(rsrc *resource.Quantity) error {
|
|||||||
func ExtractPodBandwidthResources(podAnnotations map[string]string) (ingress, egress *resource.Quantity, err error) {
|
func ExtractPodBandwidthResources(podAnnotations map[string]string) (ingress, egress *resource.Quantity, err error) {
|
||||||
str, found := podAnnotations["kubernetes.io/ingress-bandwidth"]
|
str, found := podAnnotations["kubernetes.io/ingress-bandwidth"]
|
||||||
if found {
|
if found {
|
||||||
if ingress, err = resource.ParseQuantity(str); err != nil {
|
ingressValue, err := resource.ParseQuantity(str)
|
||||||
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
ingress = &ingressValue
|
||||||
if err := validateBandwidthIsReasonable(ingress); err != nil {
|
if err := validateBandwidthIsReasonable(ingress); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
str, found = podAnnotations["kubernetes.io/egress-bandwidth"]
|
str, found = podAnnotations["kubernetes.io/egress-bandwidth"]
|
||||||
if found {
|
if found {
|
||||||
if egress, err = resource.ParseQuantity(str); err != nil {
|
egressValue, err := resource.ParseQuantity(str)
|
||||||
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
egress = &egressValue
|
||||||
if err := validateBandwidthIsReasonable(egress); err != nil {
|
if err := validateBandwidthIsReasonable(egress); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -383,5 +383,5 @@ func FindEmptyDirectoryUsageOnTmpfs() (*resource.Quantity, error) {
|
|||||||
return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err)
|
return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err)
|
||||||
}
|
}
|
||||||
used.Format = resource.BinarySI
|
used.Format = resource.BinarySI
|
||||||
return used, nil
|
return &used, nil
|
||||||
}
|
}
|
||||||
|
@ -43,5 +43,5 @@ func Du(path string) (*resource.Quantity, error) {
|
|||||||
return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err)
|
return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err)
|
||||||
}
|
}
|
||||||
used.Format = resource.BinarySI
|
used.Format = resource.BinarySI
|
||||||
return used, nil
|
return &used, nil
|
||||||
}
|
}
|
||||||
|
@ -57,5 +57,5 @@ func Du(path string) (*resource.Quantity, error) {
|
|||||||
return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err)
|
return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err)
|
||||||
}
|
}
|
||||||
used.Format = resource.BinarySI
|
used.Format = resource.BinarySI
|
||||||
return used, nil
|
return &used, nil
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ var _ = framework.KubeDescribe("LimitRange", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
func equalResourceRequirement(expected api.ResourceRequirements, actual api.ResourceRequirements) error {
|
func equalResourceRequirement(expected api.ResourceRequirements, actual api.ResourceRequirements) error {
|
||||||
framework.Logf("Verifying requests: expected %s with actual %s", expected.Requests, actual.Requests)
|
framework.Logf("Verifying requests: expected %v with actual %v", expected.Requests, actual.Requests)
|
||||||
err := equalResourceList(expected.Requests, actual.Requests)
|
err := equalResourceList(expected.Requests, actual.Requests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -314,10 +314,7 @@ func newPVC(name string) api.PersistentVolumeClaim {
|
|||||||
},
|
},
|
||||||
Resources: api.ResourceRequirements{
|
Resources: api.ResourceRequirements{
|
||||||
Requests: api.ResourceList{
|
Requests: api.ResourceList{
|
||||||
api.ResourceStorage: resource.Quantity{
|
api.ResourceStorage: *resource.NewQuantity(1, resource.BinarySI),
|
||||||
Amount: dec(1, 0),
|
|
||||||
Format: resource.BinarySI,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
8
vendor/github.com/appc/spec/schema/types/isolator_resources.go
generated
vendored
8
vendor/github.com/appc/spec/schema/types/isolator_resources.go
generated
vendored
@ -155,8 +155,8 @@ func NewResourceCPUIsolator(request, limit string) (*ResourceCPU, error) {
|
|||||||
res := &ResourceCPU{
|
res := &ResourceCPU{
|
||||||
ResourceBase{
|
ResourceBase{
|
||||||
resourceValue{
|
resourceValue{
|
||||||
Request: req,
|
Request: &req,
|
||||||
Limit: lim,
|
Limit: &lim,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -209,8 +209,8 @@ func NewResourceMemoryIsolator(request, limit string) (*ResourceMemory, error) {
|
|||||||
res := &ResourceMemory{
|
res := &ResourceMemory{
|
||||||
ResourceBase{
|
ResourceBase{
|
||||||
resourceValue{
|
resourceValue{
|
||||||
Request: req,
|
Request: &req,
|
||||||
Limit: lim,
|
Limit: &lim,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user