Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
18b89664
Commit
18b89664
authored
Jan 02, 2015
by
Daniel Smith
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Saturation + test, also test negative numbers
parent
394c9452
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
97 additions
and
29 deletions
+97
-29
quantity.go
pkg/api/resource/quantity.go
+36
-15
quantity_test.go
pkg/api/resource/quantity_test.go
+61
-14
No files found.
pkg/api/resource/quantity.go
View file @
18b89664
...
...
@@ -53,8 +53,8 @@ const (
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
//
// No matter which of the three exponent forms is used, no quantity may represent
// a number less than
.00
1m or greater than 2^63-1 in magnitude. Numbers that exceed
// a bound will be capped at that bound. (E.g.: 0.
0001m will be treated as 0.00
1m.)
// a number less than 1m or greater than 2^63-1 in magnitude. Numbers that exceed
// a bound will be capped at that bound. (E.g.: 0.
1m will be treated as
1m.)
// This may be extended in the future if we require larger or smaller quantities.
//
// Numbers with binary suffixes may not have any fractional part.
...
...
@@ -104,10 +104,22 @@ var (
// splitRE is used to get the various parts of a number.
splitRE
=
regexp
.
MustCompile
(
splitREString
)
// Errors that could happen while parsing a string.
ErrFormatWrong
=
errors
.
New
(
"quantities must match the regular expression '"
+
splitREString
+
"'"
)
ErrNumeric
=
errors
.
New
(
"unable to parse numeric part of quantity"
)
ErrSuffix
=
errors
.
New
(
"unable to parse quantity's suffix"
)
ErrFractionalBinary
=
errors
.
New
(
"numbers with binary-style SI suffixes can't have fractional parts"
)
// Commonly needed big.Ints-- treat as read only!
ten
=
big
.
NewInt
(
10
)
zero
=
big
.
NewInt
(
0
)
thousand
=
big
.
NewInt
(
1000
)
ten24
=
big
.
NewInt
(
1024
)
decZero
=
inf
.
NewDec
(
0
,
0
)
// Smallest and largest (in magnitude) numbers allowed.
minAllowed
=
inf
.
NewDec
(
1
,
3
)
// == 1/1000
maxAllowed
=
inf
.
NewDec
((
1
<<
63
)
-
1
,
0
)
// == max int64
)
// ParseQuantity turns str into a Quantity, or returns an error.
...
...
@@ -140,26 +152,35 @@ func ParseQuantity(str string) (*Quantity, error) {
return
nil
,
ErrFractionalBinary
}
// exponent will always be a multiple of 10.
dec1024
:=
inf
.
NewDec
(
1024
,
0
)
for
exponent
>
0
{
amount
.
Mul
(
amount
,
dec10
24
)
amount
.
UnscaledBig
()
.
Mul
(
amount
.
UnscaledBig
(),
ten
24
)
exponent
-=
10
}
}
return
&
Quantity
{
amount
,
format
},
nil
}
// Cap at min/max bounds.
sign
:=
amount
.
Sign
()
if
sign
==
-
1
{
amount
.
Neg
(
amount
)
}
// This rounds non-zero values up to the minimum representable
// value, under the theory that if you want some resources, you
// should get some resources, even if you asked for way too small
// of an amount.
// Arguably, this should be inf.RoundHalfUp (normal rounding), but
// that would have the side effect of rounding values < .5m to zero.
amount
.
Round
(
amount
,
3
,
inf
.
RoundUp
)
var
(
// Commonly needed big.Ints-- treat as read only!
ten
=
big
.
NewInt
(
10
)
zero
=
big
.
NewInt
(
0
)
thousand
=
big
.
NewInt
(
1000
)
ten24
=
big
.
NewInt
(
1024
)
// The max is just a simple cap.
if
amount
.
Cmp
(
maxAllowed
)
>
0
{
amount
.
Set
(
maxAllowed
)
}
if
sign
==
-
1
{
amount
.
Neg
(
amount
)
}
minAllowed
=
inf
.
NewDec
(
1
,
6
)
maxAllowed
=
inf
.
NewDec
(
999
,
-
18
)
)
return
&
Quantity
{
amount
,
format
},
nil
}
// removeFactors divides in a loop; the return values have the property that
// d == result * factor ^ times
...
...
pkg/api/resource/quantity_test.go
View file @
18b89664
...
...
@@ -97,21 +97,20 @@ func TestQuantityParse(t *testing.T) {
// Things that look like floating point
{
"0.001"
,
Quantity
{
dec
(
1
,
-
3
),
DecimalSI
}},
{
"0.0005
"
,
Quantity
{
dec
(
5
,
-
4
),
DecimalSI
}},
{
"0.0005
k"
,
Quantity
{
dec
(
5
,
-
1
),
DecimalSI
}},
{
"0.005"
,
Quantity
{
dec
(
5
,
-
3
),
DecimalSI
}},
{
"0.05"
,
Quantity
{
dec
(
5
,
-
2
),
DecimalSI
}},
{
"0.5"
,
Quantity
{
dec
(
5
,
-
1
),
DecimalSI
}},
{
"0.00050
"
,
Quantity
{
dec
(
5
,
-
4
),
DecimalSI
}},
{
"0.00050
k"
,
Quantity
{
dec
(
5
,
-
1
),
DecimalSI
}},
{
"0.00500"
,
Quantity
{
dec
(
5
,
-
3
),
DecimalSI
}},
{
"0.05000"
,
Quantity
{
dec
(
5
,
-
2
),
DecimalSI
}},
{
"0.50000"
,
Quantity
{
dec
(
5
,
-
1
),
DecimalSI
}},
{
"0.5e-3"
,
Quantity
{
dec
(
5
,
-
4
),
DecimalExponent
}},
{
"0.5e-2"
,
Quantity
{
dec
(
5
,
-
3
),
DecimalExponent
}},
{
"0.5e0"
,
Quantity
{
dec
(
5
,
-
1
),
DecimalExponent
}},
{
"0.5e-1"
,
Quantity
{
dec
(
5
,
-
2
),
DecimalExponent
}},
{
"0.5e-2"
,
Quantity
{
dec
(
5
,
-
3
),
DecimalExponent
}},
{
"0.5e0"
,
Quantity
{
dec
(
5
,
-
1
),
DecimalExponent
}},
{
"10.035M"
,
Quantity
{
dec
(
10035
,
3
),
DecimalSI
}},
{
"1.1E-3"
,
Quantity
{
dec
(
11
,
-
4
),
DecimalExponent
}},
{
"1.2e3"
,
Quantity
{
dec
(
12
,
2
),
DecimalExponent
}},
{
"1.3E6"
,
Quantity
{
dec
(
13
,
5
),
DecimalExponent
}},
{
"1.40e9"
,
Quantity
{
dec
(
14
,
8
),
DecimalExponent
}},
...
...
@@ -119,7 +118,6 @@ func TestQuantityParse(t *testing.T) {
{
"1.6e15"
,
Quantity
{
dec
(
16
,
14
),
DecimalExponent
}},
{
"1.7E18"
,
Quantity
{
dec
(
17
,
17
),
DecimalExponent
}},
{
"3.001m"
,
Quantity
{
dec
(
3001
,
-
6
),
DecimalSI
}},
{
"9.01"
,
Quantity
{
dec
(
901
,
-
2
),
DecimalSI
}},
{
"8.1k"
,
Quantity
{
dec
(
81
,
2
),
DecimalSI
}},
{
"7.123456M"
,
Quantity
{
dec
(
7123456
,
0
),
DecimalSI
}},
...
...
@@ -130,11 +128,19 @@ func TestQuantityParse(t *testing.T) {
{
"2.5P"
,
Quantity
{
dec
(
25
,
14
),
DecimalSI
}},
{
"1.01E"
,
Quantity
{
dec
(
101
,
16
),
DecimalSI
}},
// Things that saturate
//{"0.1m",
//{"9Ei",
//{"9223372036854775807Ki",
//{"12E",
// Things that saturate/round
{
"3.001m"
,
Quantity
{
dec
(
4
,
-
3
),
DecimalSI
}},
{
"1.1E-3"
,
Quantity
{
dec
(
2
,
-
3
),
DecimalExponent
}},
{
"0.0001"
,
Quantity
{
dec
(
1
,
-
3
),
DecimalSI
}},
{
"0.0005"
,
Quantity
{
dec
(
1
,
-
3
),
DecimalSI
}},
{
"0.00050"
,
Quantity
{
dec
(
1
,
-
3
),
DecimalSI
}},
{
"0.5e-3"
,
Quantity
{
dec
(
1
,
-
3
),
DecimalExponent
}},
{
"0.9m"
,
Quantity
{
dec
(
1
,
-
3
),
DecimalSI
}},
{
"0.12345"
,
Quantity
{
dec
(
124
,
-
3
),
DecimalSI
}},
{
"0.12354"
,
Quantity
{
dec
(
124
,
-
3
),
DecimalSI
}},
{
"9Ei"
,
Quantity
{
maxAllowed
,
BinarySI
}},
{
"9223372036854775807Ki"
,
Quantity
{
maxAllowed
,
BinarySI
}},
{
"12E"
,
Quantity
{
maxAllowed
,
DecimalSI
}},
}
for
_
,
item
:=
range
table
{
...
...
@@ -151,6 +157,38 @@ func TestQuantityParse(t *testing.T) {
}
}
// Try the negative version of everything
desired
:=
&
inf
.
Dec
{}
for
_
,
item
:=
range
table
{
got
,
err
:=
ParseQuantity
(
"-"
+
item
.
input
)
if
err
!=
nil
{
t
.
Errorf
(
"-%v: unexpected error: %v"
,
item
.
input
,
err
)
continue
}
desired
.
Neg
(
item
.
expect
.
Amount
)
if
e
,
a
:=
desired
,
got
.
Amount
;
e
.
Cmp
(
a
)
!=
0
{
t
.
Errorf
(
"%v: expected %v, got %v"
,
item
.
input
,
e
,
a
)
}
if
e
,
a
:=
item
.
expect
.
Format
,
got
.
Format
;
e
!=
a
{
t
.
Errorf
(
"%v: expected %#v, got %#v"
,
item
.
input
,
e
,
a
)
}
}
// Try everything with an explicit +
for
_
,
item
:=
range
table
{
got
,
err
:=
ParseQuantity
(
"+"
+
item
.
input
)
if
err
!=
nil
{
t
.
Errorf
(
"-%v: unexpected error: %v"
,
item
.
input
,
err
)
continue
}
if
e
,
a
:=
item
.
expect
.
Amount
,
got
.
Amount
;
e
.
Cmp
(
a
)
!=
0
{
t
.
Errorf
(
"%v: expected %v, got %v"
,
item
.
input
,
e
,
a
)
}
if
e
,
a
:=
item
.
expect
.
Format
,
got
.
Format
;
e
!=
a
{
t
.
Errorf
(
"%v: expected %#v, got %#v"
,
item
.
input
,
e
,
a
)
}
}
invalid
:=
[]
string
{
"1.1.M"
,
"1+1.0M"
,
...
...
@@ -208,9 +246,6 @@ func TestQuantityString(t *testing.T) {
{
Quantity
{
dec
(
3
,
3
),
DecimalExponent
},
"3e3"
},
{
Quantity
{
dec
(
3
,
3
),
DecimalSI
},
"3k"
},
{
Quantity
{
dec
(
0
,
0
),
DecimalExponent
},
"0"
},
{
Quantity
{
dec
(
-
1080
,
-
3
),
DecimalSI
},
"-1.080"
},
{
Quantity
{
dec
(
-
80
*
1024
,
0
),
BinarySI
},
"-80Ki"
},
}
for
_
,
item
:=
range
table
{
got
:=
item
.
in
.
String
()
...
...
@@ -218,4 +253,16 @@ func TestQuantityString(t *testing.T) {
t
.
Errorf
(
"%#v: expected %v, got %v"
,
item
.
in
,
e
,
a
)
}
}
desired
:=
&
inf
.
Dec
{}
// Avoid modifying the values in the table.
for
_
,
item
:=
range
table
{
if
item
.
in
.
Amount
.
Cmp
(
decZero
)
==
0
{
// Don't expect it to print "-0" ever
continue
}
q
:=
item
.
in
q
.
Amount
=
desired
.
Neg
(
q
.
Amount
)
if
e
,
a
:=
"-"
+
item
.
expect
,
q
.
String
();
e
!=
a
{
t
.
Errorf
(
"%#v: expected %v, got %v"
,
item
.
in
,
e
,
a
)
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment