Created
October 10, 2017 18:37
-
-
Save benley/d90ddcbf5e5165616ac83ef85fbc262c to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// Helper functions and stuff related to unit conversions | |
{ | |
// Parse a k8s memory resource value and return it in bytes as an integer | |
// | |
// From the Kubernetes API docs: | |
// > You can express memory as a plain integer or as a fixed-point integer using | |
// > one of these suffixes: E, P, T, G, M, K. You can also use the power-of-two | |
// > equivalents: Ei, Pi, Ti, Gi, Mi, Ki. | |
parseMemory(x):: | |
local xs = std.toString(x), | |
num2 = std.parseInt(xs[:std.length(xs)-2]), | |
tail2 = xs[std.length(xs)-2:], | |
num1 = std.parseInt(xs[:std.length(xs)-1]), | |
tail1 = xs[std.length(xs)-1:]; | |
if std.type(x) == "number" then x | |
else if std.length(xs) < 2 then error "Invalid memory spec: %s" % x | |
else if tail1 == "K" then num1 * self.K | |
else if tail1 == "M" then num1 * self.M | |
else if tail1 == "G" then num1 * self.G | |
else if tail1 == "T" then num1 * self.T | |
else if tail1 == "P" then num1 * self.P | |
else if tail1 == "E" then num1 * self.E | |
else if tail2 == "Ki" then num2 * self.Ki | |
else if tail2 == "Mi" then num2 * self.Mi | |
else if tail2 == "Gi" then num2 * self.Gi | |
else if tail2 == "Ti" then num2 * self.Ti | |
else if tail2 == "Pi" then num2 * self.Pi | |
else if tail2 == "Ei" then num2 * self.Ei | |
else if self.isNumeric(tail1) then std.parseInt(xs) | |
else error "I don't know how to parse this memory spec: %s" % x | |
, | |
K: 1000, | |
M: self.K * 1000, | |
G: self.M * 1000, | |
T: self.G * 1000, | |
P: self.T * 1000, | |
E: self.P * 1000, | |
Ki: 1024, | |
Mi: self.Ki * 1024, | |
Gi: self.Mi * 1024, | |
Ti: self.Gi * 1024, | |
Pi: self.Ti * 1024, | |
Ei: self.Pi * 1024, | |
assert self.parseMemory(1048576) == 1048576, | |
assert self.parseMemory("1048576") == 1048576, | |
assert self.parseMemory("128M") == 128 * self.M, | |
assert self.parseMemory("128Mi") == 128 * self.Mi, | |
assert self.parseMemory("5G") == 5 * self.G, | |
assert self.parseMemory("16G") == 16 * self.M * 1000, | |
assert self.parseMemory("10T") == 10 * self.T, | |
assert self.parseMemory("10Ti") == 10 * self.Ti, | |
assert self.parseMemory("12345") == 12345, | |
// Return true if x is either a number or a string containing only digits | |
isNumeric(x):: | |
local digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; | |
std.setUnion(std.set(std.toString(x)), digits) == digits, | |
assert self.isNumeric(12345), | |
assert self.isNumeric("98512"), | |
assert ! self.isNumeric("fifteen"), | |
} |
There are some languages that extend numeric literals to include things like 1G and 1M. It's worth thinking about.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This looks useful enough for the stdlib