From 5c291a7ef69fe967cb878c8af557f659c1a010f4 Mon Sep 17 00:00:00 2001 From: Sergiusz Urbaniak Date: Wed, 6 Jul 2016 11:01:17 +0200 Subject: [PATCH 1/2] godep: update kubernetes (v1.3.0) --- Godeps/Godeps.json | 14 +- .../kubernetes/pkg/api/resource/amount.go | 298 +++++++++ .../{deep_copy_generated.go => deep_copy.go} | 35 +- .../pkg/api/resource/generated.pb.go | 325 --------- .../pkg/api/resource/generated.proto | 21 +- .../kubernetes/pkg/api/resource/math.go | 327 +++++++++ .../kubernetes/pkg/api/resource/quantity.go | 620 ++++++++++++------ .../pkg/api/resource/quantity_proto.go | 292 +++++++-- .../kubernetes/pkg/api/resource/suffix.go | 84 ++- .../pkg/conversion/deep_copy_generated.go | 185 ------ 10 files changed, 1388 insertions(+), 813 deletions(-) create mode 100644 vendor/k8s.io/kubernetes/pkg/api/resource/amount.go rename vendor/k8s.io/kubernetes/pkg/api/resource/{deep_copy_generated.go => deep_copy.go} (53%) create mode 100644 vendor/k8s.io/kubernetes/pkg/api/resource/math.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/conversion/deep_copy_generated.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 1513a3ae..251e61b1 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,7 +1,7 @@ { "ImportPath": "github.com/appc/spec", "GoVersion": "go1.6", - "GodepVersion": "v60", + "GodepVersion": "v64", "Packages": [ "./..." ], @@ -38,18 +38,18 @@ }, { "ImportPath": "k8s.io/kubernetes/pkg/api/resource", - "Comment": "v1.3.0-alpha.4", - "Rev": "9990f843cd62caa90445cf76b07d63ba7b5c86fd" + "Comment": "v1.3.0", + "Rev": "283137936a498aed572ee22af6774b6fb6e9fd94" }, { "ImportPath": "k8s.io/kubernetes/pkg/conversion", - "Comment": "v1.3.0-alpha.4", - "Rev": "9990f843cd62caa90445cf76b07d63ba7b5c86fd" + "Comment": "v1.3.0", + "Rev": "283137936a498aed572ee22af6774b6fb6e9fd94" }, { "ImportPath": "k8s.io/kubernetes/third_party/forked/reflect", - "Comment": "v1.3.0-alpha.4", - "Rev": "9990f843cd62caa90445cf76b07d63ba7b5c86fd" + "Comment": "v1.3.0", + "Rev": "283137936a498aed572ee22af6774b6fb6e9fd94" } ] } diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/amount.go b/vendor/k8s.io/kubernetes/pkg/api/resource/amount.go new file mode 100644 index 00000000..6ae823a0 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/amount.go @@ -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 arbitrary 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 +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/api/resource/deep_copy.go similarity index 53% rename from vendor/k8s.io/kubernetes/pkg/api/resource/deep_copy_generated.go rename to vendor/k8s.io/kubernetes/pkg/api/resource/deep_copy.go index 6a34e2d4..4efc0406 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/deep_copy.go @@ -1,5 +1,3 @@ -// +build !ignore_autogenerated - /* Copyright 2016 The Kubernetes Authors All rights reserved. @@ -16,40 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -// This file was autogenerated by deepcopy-gen. Do not edit it manually! - package resource import ( - inf_v0 "gopkg.in/inf.v0" + inf "gopkg.in/inf.v0" + conversion "k8s.io/kubernetes/pkg/conversion" ) func DeepCopy_resource_Quantity(in Quantity, out *Quantity, c *conversion.Cloner) error { - if in.Amount != nil { - in, out := in.Amount, &out.Amount - *out = new(inf_v0.Dec) - if newVal, err := c.DeepCopy(*in); err != nil { - return err - } else { - **out = newVal.(inf_v0.Dec) - } - } else { - out.Amount = nil - } - out.Format = in.Format - return nil -} - -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)) - copy(*out, in) - } else { - out.Bigint = nil + *out = in + if in.d.Dec != nil { + tmp := &inf.Dec{} + out.d.Dec = tmp.Set(in.d.Dec) } return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/generated.pb.go b/vendor/k8s.io/kubernetes/pkg/api/resource/generated.pb.go index 7484f927..cf9447a3 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/generated.pb.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/generated.pb.go @@ -26,7 +26,6 @@ limitations under the License. It has these top-level messages: Quantity - QuantityProto */ package resource @@ -34,8 +33,6 @@ import proto "github.com/gogo/protobuf/proto" import fmt "fmt" import math "math" -import io "io" - // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf @@ -44,328 +41,6 @@ var _ = math.Inf func (m *Quantity) Reset() { *m = Quantity{} } func (*Quantity) ProtoMessage() {} -func (m *QuantityProto) Reset() { *m = QuantityProto{} } -func (m *QuantityProto) String() string { return proto.CompactTextString(m) } -func (*QuantityProto) ProtoMessage() {} - func init() { 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") -) diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/generated.proto b/vendor/k8s.io/kubernetes/pkg/api/resource/generated.proto index 34ede458..e1c2a3d6 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/generated.proto +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/generated.proto @@ -83,27 +83,12 @@ option go_package = "resource"; // writing some sort of special handling code in the hopes that that will // cause implementors to also use a fixed point implementation. // +// +gencopy=false // +protobuf=true -// +protobuf.embed=QuantityProto +// +protobuf.embed=string // +protobuf.options.marshal=false // +protobuf.options.(gogoproto.goproto_stringer)=false message Quantity { - optional QuantityProto QuantityProto = 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; + optional string string = 1; } diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/math.go b/vendor/k8s.io/kubernetes/pkg/api/resource/math.go new file mode 100644 index 00000000..163aafa5 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/math.go @@ -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 +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/quantity.go b/vendor/k8s.io/kubernetes/pkg/api/resource/quantity.go index e61c8800..96877b4c 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/quantity.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/quantity.go @@ -17,10 +17,12 @@ limitations under the License. package resource import ( + "bytes" "errors" "fmt" "math/big" "regexp" + "strconv" "strings" flag "github.com/spf13/pflag" @@ -85,20 +87,36 @@ import ( // writing some sort of special handling code in the hopes that that will // cause implementors to also use a fixed point implementation. // +// +gencopy=false // +protobuf=true -// +protobuf.embed=QuantityProto +// +protobuf.embed=string // +protobuf.options.marshal=false // +protobuf.options.(gogoproto.goproto_stringer)=false type Quantity struct { - // Amount is public, so you can manipulate it if the accessor - // functions are not sufficient. - Amount *inf.Dec + // i is the quantity in int64 scaled form, if d.Dec == nil + i int64Amount + // 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 string // Change Format at will. See the comment for Canonicalize for // more details. 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. type Format string @@ -115,26 +133,9 @@ func MustParse(str string) Quantity { if err != nil { 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 ( // 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. @@ -149,47 +150,199 @@ var ( ErrFormatWrong = errors.New("quantities must match the regular expression '" + splitREString + "'") ErrNumeric = errors.New("unable to parse numeric part of quantity") ErrSuffix = errors.New("unable to parse quantity's suffix") - - // 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: + 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. -func ParseQuantity(str string) (*Quantity, error) { - parts := splitRE.FindStringSubmatch(strings.TrimSpace(str)) - // regexp returns are entire match, followed by an entry for each () section. - if len(parts) != 3 { - return nil, ErrFormatWrong +func ParseQuantity(str string) (Quantity, error) { + if len(str) == 0 { + return Quantity{}, ErrFormatWrong + } + if str == "0" { + return Quantity{Format: DecimalSI, s: str}, nil } - amount := new(inf.Dec) - if _, ok := amount.SetString(parts[1]); !ok { - return nil, ErrNumeric + positive, value, num, denom, suf, err := parseQuantityString(str) + if err != nil { + return Quantity{}, err } - base, exponent, format, ok := quantitySuffixer.interpret(suffix(parts[2])) + base, exponent, format, ok := quantitySuffixer.interpret(suffix(suf)) if !ok { - return nil, ErrSuffix + 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 + } + // if the number is in canonical form, reuse the string + switch format { + case BinarySI: + if exponent%10 == 0 && (value&0x07 != 0) { + return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format, s: str}, nil + } + default: + if scale%3 == 0 && !strings.HasSuffix(shifted, "000") && shifted[0] != '0' { + return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format, s: str}, nil + } + } + return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format}, nil + } + } + } + + amount := new(inf.Dec) + if _, ok := amount.SetString(value); !ok { + return Quantity{}, ErrNumeric } // So that no one but us has to think about suffixes, remove it. @@ -217,9 +370,11 @@ func ParseQuantity(str string) (*Quantity, error) { } // The max is just a simple cap. - if amount.Cmp(maxAllowed) > 0 { - amount.Set(maxAllowed) + // TODO: this prevents accumulating quantities greater than int64, for instance quota across a cluster + if format == BinarySI && amount.Cmp(maxAllowed.Dec) > 0 { + amount.Set(maxAllowed.Dec) } + if format == BinarySI && amount.Cmp(decOne) < 0 && amount.Cmp(decZero) > 0 { // This avoids rounding and hopefully confusion, too. format = DecimalSI @@ -228,55 +383,32 @@ func ParseQuantity(str string) (*Quantity, error) { 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). +// CanonicalizeBytes returns the canonical form of q and its suffix (see comment on Quantity). // // Note about BinarySI: // * If q.Format is set to BinarySI and q.Amount represents a non-zero value between // -1 and +1, it will be emitted as if q.Format were DecimalSI. // * Otherwise, if q.Format is set to BinarySI, frational parts of q.Amount will be // rounded up. (1.1i becomes 2i.) -func (q *Quantity) Canonicalize() (string, suffix) { - if q.Amount == nil { - return "0", "" - } - - // zero is zero always - if q.Amount.Cmp(&inf.Dec{}) == 0 { - return "0", "" +func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte) { + if q.IsZero() { + return zeroBytes, nil } + var rounded CanonicalValue format := q.Format switch format { case DecimalExponent, DecimalSI: 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. format = DecimalSI } else { - tmp := &inf.Dec{} - tmp.Round(q.Amount, 0, inf.RoundUp) - if tmp.Cmp(q.Amount) != 0 { + var exact bool + if rounded, exact = q.AsScale(0); !exact { // Don't lose precision-- show as DecimalSI format = DecimalSI } @@ -289,125 +421,223 @@ func (q *Quantity) Canonicalize() (string, suffix) { // one of the other formats. switch format { case DecimalExponent, DecimalSI: - mantissa := q.Amount.UnscaledBig() - exponent := int(-q.Amount.Scale()) - 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() + number, exponent := q.AsCanonicalBytes(out) + suffix, _ := quantitySuffixer.constructBytes(10, exponent, format) return number, suffix - case BinarySI: - tmp := &inf.Dec{} - tmp.Round(q.Amount, 0, inf.RoundUp) - - amount, exponent := removeFactors(tmp.UnscaledBig(), big1024) - suffix, _ := quantitySuffixer.construct(2, exponent*10, format) - number := amount.String() + default: + // format must be BinarySI + number, exponent := rounded.AsCanonicalBase1024Bytes(out) + suffix, _ := quantitySuffixer.constructBytes(2, exponent*10, format) return number, suffix } - return "0", "" } -// String formats the Quantity as a string. -func (q *Quantity) String() string { - number, suffix := q.Canonicalize() - return number + string(suffix) +// 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() } -// 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() +// 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{} } - if y.Amount == nil { - return q.Amount.Sign() + 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 } - return q.Amount.Cmp(y.Amount) + q.d.Dec = q.i.AsDec() + q.i = int64Amount{} + return q.d.Dec } -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) +// 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 nil + return q.i.AsCanonicalBytes(out) } -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 { +// 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 { + q.s = "" + d, exact := q.d.AsScale(scale) + q.d = d + return exact + } + // avoid clearing the string value if we have already calculated it + if q.i.scale >= scale { + return true + } + q.s = "" + 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 = "" + if q.d.Dec == nil && y.d.Dec == nil { + if q.i.value == 0 { q.Format = y.Format } - q.Amount.Sub(q.Amount, y.Amount) + if q.i.Add(y.i) { + return + } + } else if q.IsZero() { + q.Format = y.Format } - return nil + q.ToDec().d.Dec.Add(q.d.Dec, y.AsDec()) } -// 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) +// 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 = "" + if q.IsZero() { q.Format = y.Format } - return nil + 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 = "" + if q.d.Dec == nil { + q.i.value = -q.i.value + return + } + q.d.Dec.Neg(q.d.Dec) +} + +// 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, caching the result if not calculated. +// String is an expensive operation and caching this result significantly reduces the cost of +// normal parse / marshal operations on Quantity. +func (q *Quantity) String() string { + if len(q.s) == 0 { + result := make([]byte, 0, int64QuantityExpectedBytes) + number, suffix := q.CanonicalizeBytes(result) + number = append(number, suffix...) + q.s = string(number) + } + return q.s } // MarshalJSON implements the json.Marshaller interface. func (q Quantity) MarshalJSON() ([]byte, error) { - return []byte(`"` + q.String() + `"`), nil + if len(q.s) > 0 { + 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. +// TODO: Remove support for leading/trailing whitespace func (q *Quantity) UnmarshalJSON(value []byte) error { - str := string(value) - parsed, err := ParseQuantity(strings.Trim(str, `"`)) + l := len(value) + if l == 4 && bytes.Equal(value, []byte("null")) { + q.d.Dec = nil + q.i = int64Amount{} + return nil + } + if l >= 2 && value[0] == '"' && value[l-1] == '"' { + value = value[1 : l-1] + } + + parsed, err := ParseQuantity(strings.TrimSpace(string(value))) if err != nil { return err } + // This copy is safe because parsed will not be referred to again. - *q = *parsed + *q = parsed return nil } @@ -415,7 +645,7 @@ func (q *Quantity) UnmarshalJSON(value []byte) error { // value in the given format. func NewQuantity(value int64, format Format) *Quantity { return &Quantity{ - Amount: inf.NewDec(value, 0), + i: int64Amount{value: value}, Format: format, } } @@ -426,7 +656,7 @@ func NewQuantity(value int64, format Format) *Quantity { // values x where (-1 < x < 1) && (x != 0). func NewMilliQuantity(value int64, format Format) *Quantity { return &Quantity{ - Amount: inf.NewDec(value, 3), + i: int64Amount{value: value, scale: -3}, Format: format, } } @@ -435,7 +665,7 @@ func NewMilliQuantity(value int64, format Format) *Quantity { // value * 10^scale in DecimalSI format. func NewScaledQuantity(value int64, scale Scale) *Quantity { return &Quantity{ - Amount: inf.NewDec(value, scale.infScale()), + i: int64Amount{value: value, scale: scale}, Format: DecimalSI, } } @@ -454,10 +684,12 @@ func (q *Quantity) MilliValue() 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. func (q *Quantity) ScaledValue(scale Scale) int64 { - if q.Amount == nil { - return 0 + if q.d.Dec == nil { + 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. @@ -472,22 +704,25 @@ func (q *Quantity) SetMilli(value int64) { // SetScaled sets q's value to be value * 10^scale func (q *Quantity) SetScaled(value int64, scale Scale) { - if q.Amount == nil { - q.Amount = &inf.Dec{} - } - q.Amount.SetUnscaled(value) - q.Amount.SetScale(scale.infScale()) + q.s = "" + q.d.Dec = nil + q.i = int64Amount{value: value, scale: scale} } // Copy is a convenience function that makes a deep copy for you. Non-deep // copies of quantities share pointers and you will regret that. func (q *Quantity) Copy() *Quantity { - if q.Amount == nil { - return NewQuantity(0, q.Format) + if q.d.Dec == nil { + return &Quantity{ + s: q.s, + i: q.i, + Format: q.Format, + } } tmp := &inf.Dec{} return &Quantity{ - Amount: tmp.Set(q.Amount), + s: q.s, + d: infDecAmount{tmp.Set(q.d.Dec)}, Format: q.Format, } } @@ -504,7 +739,7 @@ func (qf qFlag) Set(val string) error { return err } // This copy is OK because q will not be referenced again. - *qf.dest = *q + *qf.dest = q return nil } @@ -531,8 +766,3 @@ func QuantityFlag(flagName, defaultValue, description string) *Quantity { func NewQuantityFlagValue(q *Quantity) flag.Value { 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 -} diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/quantity_proto.go b/vendor/k8s.io/kubernetes/pkg/api/resource/quantity_proto.go index 01d5c299..24029468 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/quantity_proto.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/quantity_proto.go @@ -17,62 +17,268 @@ limitations under the License. package resource 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 -// protobuf marshalling/unmarshalling. It is generated into a serialization -// that matches Quantity. Do not use in Go structs. -// -// +protobuf=true -type QuantityProto struct { - // The format of the quantity - Format Format `protobuf:"bytes,1,opt,name=format,casttype=Format"` - // The scale dimension of the value - Scale int32 `protobuf:"varint,2,opt,name=scale"` - // Bigint is serialized as a raw bytes array - Bigint []byte `protobuf:"bytes,3,opt,name=bigint"` -} +var _ proto.Sizer = &Quantity{} -// ProtoTime returns the Time as a new ProtoTime value. -func (q *Quantity) QuantityProto() *QuantityProto { - if q == nil { - return &QuantityProto{} +func (m *Quantity) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - p := &QuantityProto{ - Format: q.Format, + return data[:n], nil +} + +// MarshalTo is a customized version of the generated Protobuf unmarshaler for a struct +// with a single string field. +func (m *Quantity) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + + data[i] = 0xa + i++ + // BEGIN CUSTOM MARSHAL + out := m.String() + i = encodeVarintGenerated(data, i, uint64(len(out))) + i += copy(data[i:], out) + // END CUSTOM MARSHAL + + return i, nil +} + +func encodeVarintGenerated(data []byte, offset int, v uint64) int { + for v >= 1<<7 { + data[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ } - if q.Amount != nil { - p.Scale = int32(q.Amount.Scale()) - p.Bigint = q.Amount.UnscaledBig().Bytes() + data[offset] = uint8(v) + return offset + 1 +} + +func (m *Quantity) Size() (n int) { + var l int + _ = l + + // BEGIN CUSTOM SIZE + l = len(m.String()) + // 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 p + return n } -// Size implements the protobuf marshalling interface. -func (q *Quantity) Size() (n int) { return q.QuantityProto().Size() } +// 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]) -// Reset implements the protobuf marshalling interface. -func (q *Quantity) Unmarshal(data []byte) error { - p := QuantityProto{} - if err := p.Unmarshal(data); err != nil { - return err + // BEGIN CUSTOM DECODE + p, err := ParseQuantity(s) + if err != nil { + return err + } + *m = p + // END CUSTOM DECODE + + 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 } - q.Format = p.Format - b := big.NewInt(0) - b.SetBytes(p.Bigint) - q.Amount = inf.NewDecBig(b, inf.Scale(p.Scale)) return nil } -// Marshal implements the protobuf marshalling interface. -func (q *Quantity) Marshal() (data []byte, err error) { - return q.QuantityProto().Marshal() +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") } -// MarshalTo implements the protobuf marshalling interface. -func (q *Quantity) MarshalTo(data []byte) (int, error) { - return q.QuantityProto().MarshalTo(data) -} +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/suffix.go b/vendor/k8s.io/kubernetes/pkg/api/resource/suffix.go index 52971236..0aa2ce2b 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/suffix.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/suffix.go @@ -24,8 +24,9 @@ type suffix string // suffixer can interpret and construct suffixes. type suffixer interface { - interpret(suffix) (base, exponent int, fmt Format, ok bool) - construct(base, exponent int, fmt Format) (s suffix, ok bool) + interpret(suffix) (base, exponent int32, fmt Format, 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 @@ -33,12 +34,13 @@ type suffixer interface { var quantitySuffixer = newSuffixer() type bePair struct { - base, exponent int + base, exponent int32 } type listSuffixer struct { - suffixToBE map[suffix]bePair - beToSuffix map[bePair]suffix + suffixToBE map[suffix]bePair + beToSuffix map[bePair]suffix + beToSuffixBytes map[bePair][]byte } func (ls *listSuffixer) addSuffix(s suffix, pair bePair) { @@ -48,11 +50,15 @@ func (ls *listSuffixer) addSuffix(s suffix, pair bePair) { if ls.beToSuffix == nil { ls.beToSuffix = map[bePair]suffix{} } + if ls.beToSuffixBytes == nil { + ls.beToSuffixBytes = map[bePair][]byte{} + } ls.suffixToBE[s] = pair 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] if !ok { 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 } -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}] return } +func (ls *listSuffixer) constructBytes(base, exponent int32) (s []byte, ok bool) { + s, ok = ls.beToSuffixBytes[bePair{base, exponent}] + return +} + type suffixHandler struct { decSuffixes 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 { sh := &suffixHandler{} + // IMPORTANT: if you change this section you must change fastLookup + sh.binSuffixes.addSuffix("Ki", bePair{2, 10}) sh.binSuffixes.addSuffix("Mi", bePair{2, 20}) sh.binSuffixes.addSuffix("Gi", bePair{2, 30}) @@ -94,10 +131,10 @@ func newSuffixer() suffixer { sh.decSuffixes.addSuffix("P", bePair{10, 15}) 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 { case DecimalSI: return sh.decSuffixes.construct(base, exponent) @@ -115,7 +152,32 @@ func (sh *suffixHandler) construct(base, exponent int, fmt Format) (s suffix, ok 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 if b, e, ok := sh.decSuffixes.lookup(suffix); ok { return b, e, DecimalSI, true @@ -129,7 +191,7 @@ func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int, fmt Forma if err != nil { return 0, 0, DecimalExponent, false } - return 10, int(parsed), DecimalExponent, true + return 10, int32(parsed), DecimalExponent, true } return 0, 0, DecimalExponent, false diff --git a/vendor/k8s.io/kubernetes/pkg/conversion/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/conversion/deep_copy_generated.go deleted file mode 100644 index 717feaf1..00000000 --- a/vendor/k8s.io/kubernetes/pkg/conversion/deep_copy_generated.go +++ /dev/null @@ -1,185 +0,0 @@ -// +build !ignore_autogenerated - -/* -Copyright 2016 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. -*/ - -// This file was autogenerated by deepcopy-gen. Do not edit it manually! - -package conversion - -import ( - forked_reflect "k8s.io/kubernetes/third_party/forked/reflect" - reflect "reflect" -) - -func DeepCopy_conversion_Cloner(in Cloner, out *Cloner, c *Cloner) error { - if in.deepCopyFuncs != nil { - in, out := in.deepCopyFuncs, &out.deepCopyFuncs - *out = make(map[reflect.Type]reflect.Value) - for range in { - // FIXME: Copying unassignable keys unsupported reflect.Type - } - } else { - out.deepCopyFuncs = nil - } - if in.generatedDeepCopyFuncs != nil { - in, out := in.generatedDeepCopyFuncs, &out.generatedDeepCopyFuncs - *out = make(map[reflect.Type]reflect.Value) - for range in { - // FIXME: Copying unassignable keys unsupported reflect.Type - } - } else { - out.generatedDeepCopyFuncs = nil - } - return nil -} - -func DeepCopy_conversion_ConversionFuncs(in ConversionFuncs, out *ConversionFuncs, c *Cloner) error { - if in.fns != nil { - in, out := in.fns, &out.fns - *out = make(map[typePair]reflect.Value) - for range in { - // FIXME: Copying unassignable keys unsupported typePair - } - } else { - out.fns = nil - } - return nil -} - -func DeepCopy_conversion_Converter(in Converter, out *Converter, c *Cloner) error { - if err := DeepCopy_conversion_ConversionFuncs(in.conversionFuncs, &out.conversionFuncs, c); err != nil { - return err - } - if err := DeepCopy_conversion_ConversionFuncs(in.generatedConversionFuncs, &out.generatedConversionFuncs, c); err != nil { - return err - } - if in.genericConversions != nil { - in, out := in.genericConversions, &out.genericConversions - *out = make([]GenericConversionFunc, len(in)) - for i := range in { - if newVal, err := c.DeepCopy(in[i]); err != nil { - return err - } else { - (*out)[i] = newVal.(GenericConversionFunc) - } - } - } else { - out.genericConversions = nil - } - if in.ignoredConversions != nil { - in, out := in.ignoredConversions, &out.ignoredConversions - *out = make(map[typePair]struct{}) - for range in { - // FIXME: Copying unassignable keys unsupported typePair - } - } else { - out.ignoredConversions = nil - } - if in.structFieldDests != nil { - in, out := in.structFieldDests, &out.structFieldDests - *out = make(map[typeNamePair][]typeNamePair) - for range in { - // FIXME: Copying unassignable keys unsupported typeNamePair - } - } else { - out.structFieldDests = nil - } - if in.structFieldSources != nil { - in, out := in.structFieldSources, &out.structFieldSources - *out = make(map[typeNamePair][]typeNamePair) - for range in { - // FIXME: Copying unassignable keys unsupported typeNamePair - } - } else { - out.structFieldSources = nil - } - if in.defaultingFuncs != nil { - in, out := in.defaultingFuncs, &out.defaultingFuncs - *out = make(map[reflect.Type]reflect.Value) - for range in { - // FIXME: Copying unassignable keys unsupported reflect.Type - } - } else { - out.defaultingFuncs = nil - } - if in.defaultingInterfaces != nil { - in, out := in.defaultingInterfaces, &out.defaultingInterfaces - *out = make(map[reflect.Type]interface{}) - for range in { - // FIXME: Copying unassignable keys unsupported reflect.Type - } - } else { - out.defaultingInterfaces = nil - } - if in.inputFieldMappingFuncs != nil { - in, out := in.inputFieldMappingFuncs, &out.inputFieldMappingFuncs - *out = make(map[reflect.Type]FieldMappingFunc) - for range in { - // FIXME: Copying unassignable keys unsupported reflect.Type - } - } else { - out.inputFieldMappingFuncs = nil - } - if in.inputDefaultFlags != nil { - in, out := in.inputDefaultFlags, &out.inputDefaultFlags - *out = make(map[reflect.Type]FieldMatchingFlags) - for range in { - // FIXME: Copying unassignable keys unsupported reflect.Type - } - } else { - out.inputDefaultFlags = nil - } - if in.Debug == nil { - out.Debug = nil - } else if newVal, err := c.DeepCopy(in.Debug); err != nil { - return err - } else { - out.Debug = newVal.(DebugLogger) - } - if in.nameFunc == nil { - out.nameFunc = nil - } else if newVal, err := c.DeepCopy(in.nameFunc); err != nil { - return err - } else { - out.nameFunc = newVal.(func(reflect.Type) string) - } - return nil -} - -func DeepCopy_conversion_Equalities(in Equalities, out *Equalities, c *Cloner) error { - if in.Equalities != nil { - in, out := in.Equalities, &out.Equalities - *out = make(forked_reflect.Equalities) - for range in { - // FIXME: Copying unassignable keys unsupported reflect.Type - } - } else { - out.Equalities = nil - } - return nil -} - -func DeepCopy_conversion_Meta(in Meta, out *Meta, c *Cloner) error { - if in.KeyNameMapping == nil { - out.KeyNameMapping = nil - } else if newVal, err := c.DeepCopy(in.KeyNameMapping); err != nil { - return err - } else { - out.KeyNameMapping = newVal.(FieldMappingFunc) - } - return nil -} From de6f4f252da48aee7e6b60842ba916eea527eef3 Mon Sep 17 00:00:00 2001 From: Sergiusz Urbaniak Date: Wed, 6 Jul 2016 11:01:39 +0200 Subject: [PATCH 2/2] types: fix changed Request/Limit return types Starting from v1.3.0 resource.ParseQuantity returns values instead of pointers. Previously it was the other way around. This fixes it by taking the address of the returned values of Request/Limit. --- schema/types/isolator_resources.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/schema/types/isolator_resources.go b/schema/types/isolator_resources.go index 2b77e304..771c73fd 100644 --- a/schema/types/isolator_resources.go +++ b/schema/types/isolator_resources.go @@ -164,8 +164,8 @@ func NewResourceCPUIsolator(request, limit string) (*ResourceCPU, error) { res := &ResourceCPU{ ResourceBase{ resourceValue{ - Request: req, - Limit: lim, + Request: &req, + Limit: &lim, }, }, } @@ -218,8 +218,8 @@ func NewResourceMemoryIsolator(request, limit string) (*ResourceMemory, error) { res := &ResourceMemory{ ResourceBase{ resourceValue{ - Request: req, - Limit: lim, + Request: &req, + Limit: &lim, }, }, }