Skip to content

Instantly share code, notes, and snippets.

@benley
Created October 10, 2017 18:37
Show Gist options
  • Save benley/d90ddcbf5e5165616ac83ef85fbc262c to your computer and use it in GitHub Desktop.
Save benley/d90ddcbf5e5165616ac83ef85fbc262c to your computer and use it in GitHub Desktop.
// 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"),
}
@sparkprime
Copy link

This looks useful enough for the stdlib

@sparkprime
Copy link

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