forked from docker-archive/runc
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add internal/units, remove go-units dependency
We only use a single method, RAMInBytes, which can be easily implemented locally. Do that (based on docker/go-units#40, so the implementation is fully backward-compatible, except for the addition of treating -1), and remove docker/go-units dependency. This implementation relies on strings.Cut() which is only available since Go 1.18. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
- Loading branch information
Showing
14 changed files
with
165 additions
and
616 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package units | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
func RAMInBytes(val string) (int64, error) { | ||
if val == "-1" { | ||
return -1, nil | ||
} | ||
|
||
num, sfx, found := strings.Cut(val, " ") | ||
if !found { | ||
// No space between the number and the suffix. | ||
sep := strings.LastIndexAny(val, "01234567890.") | ||
if sep == -1 { | ||
// There should be at least a digit. | ||
return -1, fmt.Errorf("invalid value: %q", val) | ||
} | ||
num = val[:sep+1] | ||
sfx = val[sep+1:] | ||
} | ||
|
||
size, err := strconv.ParseFloat(num, 64) | ||
if err != nil { | ||
return -1, err | ||
} | ||
// Backward compatibility: reject negative sizes. | ||
if size < 0 { | ||
return -1, fmt.Errorf("invalid value: %q", val) | ||
} | ||
|
||
if len(sfx) == 0 { | ||
return int64(size), nil | ||
} | ||
|
||
// Process the suffix. | ||
if len(sfx) > 3 { // Too long. | ||
goto badSuffix | ||
} | ||
sfx = strings.ToLower(sfx) | ||
// Trivial case: b suffix. | ||
if sfx[0] == 'b' { | ||
if len(sfx) > 1 { // no extra characters allowed after b. | ||
goto badSuffix | ||
} | ||
return int64(size), nil | ||
} | ||
|
||
if mul := getMultiplier(sfx[0]); mul != 0 { | ||
size *= float64(mul) | ||
} else { | ||
goto badSuffix | ||
} | ||
|
||
// The suffix may have extra "b" or "ib" (e.g. KiB or MB). | ||
switch { | ||
case len(sfx) == 2 && sfx[1] != 'b': | ||
goto badSuffix | ||
case len(sfx) == 3 && sfx[1:] != "ib": | ||
goto badSuffix | ||
} | ||
|
||
return int64(size), nil | ||
|
||
badSuffix: | ||
return -1, fmt.Errorf("invalid suffix: '%s'", sfx) | ||
} | ||
|
||
const ( | ||
kb = 1024 | ||
mb = 1024 * kb | ||
gb = 1024 * mb | ||
tb = 1024 * gb | ||
pb = 1024 * tb | ||
) | ||
|
||
func getMultiplier(suffix byte) int64 { | ||
switch suffix { | ||
case 'k': | ||
return kb | ||
case 'm': | ||
return mb | ||
case 'g': | ||
return gb | ||
case 't': | ||
return tb | ||
case 'p': | ||
return pb | ||
} | ||
|
||
return 0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package units | ||
|
||
import ( | ||
"reflect" | ||
"runtime" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestRAMInBytes(t *testing.T) { | ||
assertEqual(t, RAMInBytes, "-1", -1) | ||
assertEqual(t, RAMInBytes, "32", 32) | ||
assertEqual(t, RAMInBytes, "32b", 32) | ||
assertEqual(t, RAMInBytes, "32B", 32) | ||
assertEqual(t, RAMInBytes, "32k", 32*kb) | ||
assertEqual(t, RAMInBytes, "32K", 32*kb) | ||
assertEqual(t, RAMInBytes, "32kb", 32*kb) | ||
assertEqual(t, RAMInBytes, "32Kb", 32*kb) | ||
assertEqual(t, RAMInBytes, "32Kib", 32*kb) | ||
assertEqual(t, RAMInBytes, "32KIB", 32*kb) | ||
assertEqual(t, RAMInBytes, "32Mb", 32*mb) | ||
assertEqual(t, RAMInBytes, "32Gb", 32*gb) | ||
assertEqual(t, RAMInBytes, "32Tb", 32*tb) | ||
assertEqual(t, RAMInBytes, "32Pb", 32*pb) | ||
assertEqual(t, RAMInBytes, "32PB", 32*pb) | ||
assertEqual(t, RAMInBytes, "32P", 32*pb) | ||
|
||
assertEqual(t, RAMInBytes, "32.3", 32) | ||
tmp := 32.3 * mb | ||
assertEqual(t, RAMInBytes, "32.3 mb", int64(tmp)) | ||
tmp = 0.3 * mb | ||
assertEqual(t, RAMInBytes, "0.3MB", int64(tmp)) | ||
|
||
assertError(t, RAMInBytes, "") | ||
assertError(t, RAMInBytes, "hello") | ||
assertError(t, RAMInBytes, "-32") | ||
assertError(t, RAMInBytes, " 32 ") | ||
assertError(t, RAMInBytes, "32m b") | ||
assertError(t, RAMInBytes, "32bm") | ||
} | ||
|
||
type parseFn func(string) (int64, error) | ||
|
||
func (fn parseFn) String() string { | ||
fnName := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name() | ||
return fnName[strings.LastIndex(fnName, ".")+1:] | ||
} | ||
|
||
func assertEqual(t *testing.T, fn parseFn, arg string, expected int64) { | ||
t.Helper() | ||
res, err := fn(arg) | ||
if err != nil || res != expected { | ||
t.Errorf("%s(\"%s\") -> expected '%d' but got '%d' with error '%v'", fn, arg, expected, res, err) | ||
} | ||
} | ||
|
||
func assertError(t *testing.T, fn parseFn, arg string) { | ||
t.Helper() | ||
res, err := fn(arg) | ||
if err == nil && res != -1 { | ||
t.Errorf("%s(\"%s\") -> expected error but got '%d'", fn, arg, res) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.