-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add measurement unit converter (#2772)
- Loading branch information
1 parent
edf7e98
commit 7086f7e
Showing
12 changed files
with
567 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package converter | ||
|
||
// boolConverter is a Converter implementation for bool | ||
type boolConverter struct{} | ||
|
||
func NewBoolConverter() Converter { | ||
return &boolConverter{} | ||
} | ||
|
||
func (c *boolConverter) Convert(v Value, to Unit) Value { | ||
// There is no conversion to be done for bool | ||
return Value{ | ||
F: v.F, | ||
U: to, | ||
} | ||
} |
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,53 @@ | ||
package converter | ||
|
||
// Unit represents a unit of measurement | ||
type Unit string | ||
|
||
// Value represents a value with a unit of measurement | ||
type Value struct { | ||
F float64 | ||
U Unit | ||
} | ||
|
||
// Converter converts values from one unit to another | ||
type Converter interface { | ||
Convert(v Value, to Unit) Value | ||
} | ||
|
||
// noneConverter is a converter that does not convert | ||
type noneConverter struct{} | ||
|
||
func (c *noneConverter) Convert(v Value, to Unit) Value { | ||
return v | ||
} | ||
|
||
// Converters | ||
var ( | ||
DurationConverter = NewDurationConverter() | ||
DataConverter = NewDataConverter() | ||
DataRateConverter = NewDataRateConverter() | ||
PercentConverter = NewPercentConverter() | ||
BoolConverter = NewBoolConverter() | ||
ThroughputConverter = NewThroughputConverter() | ||
NoneConverter = &noneConverter{} | ||
) | ||
|
||
// FromUnit returns a converter for the given unit | ||
func FromUnit(u Unit) Converter { | ||
switch u { | ||
case "ns", "us", "ms", "s", "m", "h", "d": | ||
return DurationConverter | ||
case "bytes", "decbytes", "bits", "decbits", "kbytes", "decKbytes", "mbytes", "decMbytes", "gbytes", "decGbytes", "tbytes", "decTbytes", "pbytes", "decPbytes": | ||
return DataConverter | ||
case "binBps", "Bps", "binbps", "bps", "KiBs", "Kibits", "KBs", "Kbits", "MiBs", "Mibits", "MBs", "Mbits", "GiBs", "Gibits", "GBs", "Gbits", "TiBs", "Tibits", "TBs", "Tbits", "PiBs", "Pibits", "PBs", "Pbits": | ||
return DataRateConverter | ||
case "percent", "percentunit": | ||
return PercentConverter | ||
case "bool", "bool_yes_no", "bool_true_false", "bool_1_0": | ||
return BoolConverter | ||
case "cps", "ops", "reqps", "rps", "wps", "iops", "cpm", "opm", "rpm", "wpm": | ||
return ThroughputConverter | ||
default: | ||
return NoneConverter | ||
} | ||
} |
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,97 @@ | ||
package converter | ||
|
||
const ( | ||
// base 10 (SI prefixes) | ||
Bit float64 = 1e0 | ||
Kilobit = Bit * 1e3 | ||
Megabit = Bit * 1e6 | ||
Gigabit = Bit * 1e9 | ||
Terabit = Bit * 1e12 | ||
Petabit = Bit * 1e15 | ||
Exabit = Bit * 1e18 | ||
Zettabit = Bit * 1e21 | ||
Yottabit = Bit * 1e24 | ||
Ronnabit = Bit * 1e27 | ||
Quettabit = Bit * 1e30 | ||
|
||
Byte = Bit * 8 | ||
Kilobyte = Byte * 1e3 | ||
Megabyte = Byte * 1e6 | ||
Gigabyte = Byte * 1e9 | ||
Terabyte = Byte * 1e12 | ||
Petabyte = Byte * 1e15 | ||
Exabyte = Byte * 1e18 | ||
Zettabyte = Byte * 1e21 | ||
Yottabyte = Byte * 1e24 | ||
Ronnabyte = Byte * 1e27 | ||
Quettabyte = Byte * 1e30 | ||
|
||
// base 2 (IEC prefixes) | ||
Kibibit = Bit * 1024 | ||
Mebibit = Kibibit * 1024 | ||
Gibibit = Mebibit * 1024 | ||
Tebibit = Gibibit * 1024 | ||
Pebibit = Tebibit * 1024 | ||
Exbibit = Pebibit * 1024 | ||
Zebibit = Exbibit * 1024 | ||
Yobibit = Zebibit * 1024 | ||
|
||
Kibibyte = Byte * 1024 | ||
Mebibyte = Kibibyte * 1024 | ||
Gibibyte = Mebibyte * 1024 | ||
Tebibyte = Gibibyte * 1024 | ||
Pebibyte = Tebibyte * 1024 | ||
Exbibyte = Pebibyte * 1024 | ||
Zebibyte = Exbibyte * 1024 | ||
Yobibyte = Zebibyte * 1024 | ||
) | ||
|
||
// dataConverter is a Converter for data units. | ||
type dataConverter struct { | ||
} | ||
|
||
func NewDataConverter() Converter { | ||
return &dataConverter{} | ||
} | ||
|
||
func FromDataUnit(u Unit) float64 { | ||
switch u { | ||
case "bytes": // base 2 | ||
return Byte | ||
case "decbytes": // base 10 | ||
return Byte | ||
case "bits": // base 2 | ||
return Bit | ||
case "decbits": // base 10 | ||
return Bit | ||
case "kbytes": // base 2 | ||
return Kibibyte | ||
case "deckbytes": // base 10 | ||
return Kilobyte | ||
case "mbytes": // base 2 | ||
return Mebibyte | ||
case "decmbytes": // base 10 | ||
return Megabyte | ||
case "gbytes": // base 2 | ||
return Gibibyte | ||
case "decgbytes": // base 10 | ||
return Gigabyte | ||
case "tbytes": // base 2 | ||
return Tebibyte | ||
case "dectbytes": // base 10 | ||
return Terabyte | ||
case "pbytes": // base 2 | ||
return Pebibyte | ||
case "decpbytes": // base 10 | ||
return Petabyte | ||
default: | ||
return 1 | ||
} | ||
} | ||
|
||
func (c *dataConverter) Convert(v Value, to Unit) Value { | ||
return Value{ | ||
F: v.F * FromDataUnit(v.U) / FromDataUnit(to), | ||
U: to, | ||
} | ||
} |
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,114 @@ | ||
package converter | ||
|
||
const ( | ||
// base 10 (SI prefixes) | ||
BitPerSecond float64 = 1e0 | ||
KilobitPerSecond = BitPerSecond * 1e3 | ||
MegabitPerSecond = BitPerSecond * 1e6 | ||
GigabitPerSecond = BitPerSecond * 1e9 | ||
TerabitPerSecond = BitPerSecond * 1e12 | ||
PetabitPerSecond = BitPerSecond * 1e15 | ||
ExabitPerSecond = BitPerSecond * 1e18 | ||
ZettabitPerSecond = BitPerSecond * 1e21 | ||
YottabitPerSecond = BitPerSecond * 1e24 | ||
|
||
BytePerSecond = BitPerSecond * 8 | ||
KilobytePerSecond = BytePerSecond * 1e3 | ||
MegabytePerSecond = BytePerSecond * 1e6 | ||
GigabytePerSecond = BytePerSecond * 1e9 | ||
TerabytePerSecond = BytePerSecond * 1e12 | ||
PetabytePerSecond = BytePerSecond * 1e15 | ||
ExabytePerSecond = BytePerSecond * 1e18 | ||
ZettabytePerSecond = BytePerSecond * 1e21 | ||
YottabytePerSecond = BytePerSecond * 1e24 | ||
|
||
// base 2 (IEC prefixes) | ||
KibibitPerSecond = BitPerSecond * 1024 | ||
MebibitPerSecond = KibibitPerSecond * 1024 | ||
GibibitPerSecond = MebibitPerSecond * 1024 | ||
TebibitPerSecond = GibibitPerSecond * 1024 | ||
PebibitPerSecond = TebibitPerSecond * 1024 | ||
ExbibitPerSecond = PebibitPerSecond * 1024 | ||
ZebibitPerSecond = ExbibitPerSecond * 1024 | ||
YobibitPerSecond = ZebibitPerSecond * 1024 | ||
|
||
KibibytePerSecond = BytePerSecond * 1024 | ||
MebibytePerSecond = KibibytePerSecond * 1024 | ||
GibibytePerSecond = MebibytePerSecond * 1024 | ||
TebibytePerSecond = GibibytePerSecond * 1024 | ||
PebibytePerSecond = TebibytePerSecond * 1024 | ||
ExbibytePerSecond = PebibytePerSecond * 1024 | ||
ZebibytePerSecond = ExbibytePerSecond * 1024 | ||
YobibytePerSecond = ZebibytePerSecond * 1024 | ||
) | ||
|
||
// dataRateConverter is a Converter implementation for data rates | ||
type dataRateConverter struct { | ||
} | ||
|
||
func NewDataRateConverter() Converter { | ||
return &dataRateConverter{} | ||
} | ||
|
||
func FromDataRateUnit(u Unit) float64 { | ||
// See https://github.com/SigNoz/signoz/blob/5a81f5f90b34845f5b4b3bdd46acf29d04bf3987/frontend/src/container/NewWidget/RightContainer/dataFormatCategories.ts#L62-L85 | ||
switch u { | ||
case "binBps": // bytes/sec(IEC) | ||
return BytePerSecond | ||
case "Bps": // bytes/sec(SI) | ||
return BytePerSecond | ||
case "binbps": // bits/sec(IEC) | ||
return BitPerSecond | ||
case "bps": // bits/sec(SI) | ||
return BitPerSecond | ||
case "KiBs": // kibibytes/sec | ||
return KibibytePerSecond | ||
case "Kibits": // kibibits/sec | ||
return KibibitPerSecond | ||
case "KBs": // kilobytes/sec | ||
return KilobytePerSecond | ||
case "Kbits": // kilobits/sec | ||
return KilobitPerSecond | ||
case "MiBs": // mebibytes/sec | ||
return MebibytePerSecond | ||
case "Mibits": // mebibits/sec | ||
return MebibitPerSecond | ||
case "MBs": // megabytes/sec | ||
return MegabytePerSecond | ||
case "Mbits": // megabits/sec | ||
return MegabitPerSecond | ||
case "GiBs": // gibibytes/sec | ||
return GibibytePerSecond | ||
case "Gibits": // gibibits/sec | ||
return GibibitPerSecond | ||
case "GBs": // gigabytes/sec | ||
return GigabytePerSecond | ||
case "Gbits": // gigabits/sec | ||
return GigabitPerSecond | ||
case "TiBs": // tebibytes/sec | ||
return TebibytePerSecond | ||
case "Tibits": // tebibits/sec | ||
return TebibitPerSecond | ||
case "TBs": // terabytes/sec | ||
return TerabytePerSecond | ||
case "Tbits": // terabits/sec | ||
return TerabitPerSecond | ||
case "PiBs": // pebibytes/sec | ||
return PebibytePerSecond | ||
case "Pibits": // pebibits/sec | ||
return PebibitPerSecond | ||
case "PBs": // petabytes/sec | ||
return PetabytePerSecond | ||
case "Pbits": // petabits/sec | ||
return PetabitPerSecond | ||
default: | ||
return 1 | ||
} | ||
} | ||
|
||
func (c *dataRateConverter) Convert(v Value, to Unit) Value { | ||
return Value{ | ||
F: v.F * FromDataRateUnit(v.U) / FromDataRateUnit(to), | ||
U: to, | ||
} | ||
} |
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,67 @@ | ||
package converter | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestDataRate(t *testing.T) { | ||
dataRateConverter := NewDataRateConverter() | ||
// names and ids for data rate units | ||
// { name: 'bytes/sec(IEC)', id: 'binBps' }, | ||
// { name: 'bytes/sec(SI)', id: 'Bps' }, | ||
// { name: 'bits/sec(IEC)', id: 'binbps' }, | ||
// { name: 'bits/sec(SI)', id: 'bps' }, | ||
// { name: 'kibibytes/sec', id: 'KiBs' }, | ||
// { name: 'kibibits/sec', id: 'Kibits' }, | ||
// { name: 'kilobytes/sec', id: 'KBs' }, | ||
// { name: 'kilobits/sec', id: 'Kbits' }, | ||
// { name: 'mebibytes/sec', id: 'MiBs' }, | ||
// { name: 'mebibits/sec', id: 'Mibits' }, | ||
// { name: 'megabytes/sec', id: 'MBs' }, | ||
// { name: 'megabits/sec', id: 'Mbits' }, | ||
// { name: 'gibibytes/sec', id: 'GiBs' }, | ||
// { name: 'gibibits/sec', id: 'Gibits' }, | ||
// { name: 'gigabytes/sec', id: 'GBs' }, | ||
// { name: 'gigabits/sec', id: 'Gbits' }, | ||
// { name: 'tebibytes/sec', id: 'TiBs' }, | ||
// { name: 'tebibits/sec', id: 'Tibits' }, | ||
// { name: 'terabytes/sec', id: 'TBs' }, | ||
// { name: 'terabits/sec', id: 'Tbits' }, | ||
// { name: 'pebibytes/sec', id: 'PiBs' }, | ||
// { name: 'pebibits/sec', id: 'Pibits' }, | ||
// { name: 'petabytes/sec', id: 'PBs' }, | ||
// { name: 'petabits/sec', id: 'Pbits' }, | ||
|
||
// 8 bits = 1 byte | ||
assert.Equal(t, Value{F: 1, U: "binBps"}, dataRateConverter.Convert(Value{F: 8, U: "binbps"}, "binBps")) | ||
// 1024 bytes = 1 kbytes | ||
assert.Equal(t, Value{F: 1, U: "KiBs"}, dataRateConverter.Convert(Value{F: 1024, U: "binBps"}, "KiBs")) | ||
// 1 byte = 8 bits | ||
assert.Equal(t, Value{F: 8, U: "binbps"}, dataRateConverter.Convert(Value{F: 1, U: "binBps"}, "binbps")) | ||
// 1 mbytes = 1024 kbytes | ||
assert.Equal(t, Value{F: 1, U: "MiBs"}, dataRateConverter.Convert(Value{F: 1024, U: "KiBs"}, "MiBs")) | ||
// 1 kbytes = 1024 bytes | ||
assert.Equal(t, Value{F: 1024, U: "binBps"}, dataRateConverter.Convert(Value{F: 1, U: "KiBs"}, "binBps")) | ||
// 1024 kbytes = 1 mbytes | ||
assert.Equal(t, Value{F: 1, U: "MiBs"}, dataRateConverter.Convert(Value{F: 1024, U: "KiBs"}, "MiBs")) | ||
// 1 mbytes = 1024 * 1024 bytes | ||
assert.Equal(t, Value{F: 1024 * 1024, U: "binBps"}, dataRateConverter.Convert(Value{F: 1, U: "MiBs"}, "binBps")) | ||
// 1024 mbytes = 1 gbytes | ||
assert.Equal(t, Value{F: 1, U: "GiBs"}, dataRateConverter.Convert(Value{F: 1024, U: "MiBs"}, "GiBs")) | ||
// 2048 mbytes = 2 gbytes | ||
assert.Equal(t, Value{F: 2, U: "GiBs"}, dataRateConverter.Convert(Value{F: 2048, U: "MiBs"}, "GiBs")) | ||
// 1 gbytes = 1024 mbytes | ||
assert.Equal(t, Value{F: 1024, U: "MiBs"}, dataRateConverter.Convert(Value{F: 1, U: "GiBs"}, "MiBs")) | ||
// 1 gbytes = 1024 * 1024 kbytes | ||
assert.Equal(t, Value{F: 1024 * 1024, U: "KiBs"}, dataRateConverter.Convert(Value{F: 1, U: "GiBs"}, "KiBs")) | ||
// 1 gbytes = 1024 * 1024 * 1024 bytes | ||
assert.Equal(t, Value{F: 1024 * 1024 * 1024, U: "binBps"}, dataRateConverter.Convert(Value{F: 1, U: "GiBs"}, "binBps")) | ||
// 1024 * 1024 bytes = 1 mbytes | ||
assert.Equal(t, Value{F: 1, U: "MiBs"}, dataRateConverter.Convert(Value{F: 1024 * 1024, U: "binBps"}, "MiBs")) | ||
// 1024 * 1024 kbytes = 1 gbytes | ||
assert.Equal(t, Value{F: 1, U: "GiBs"}, dataRateConverter.Convert(Value{F: 1024 * 1024, U: "KiBs"}, "GiBs")) | ||
// 1024 * 1024 * 1024 bytes = 1 gbytes | ||
assert.Equal(t, Value{F: 1, U: "GiBs"}, dataRateConverter.Convert(Value{F: 1024 * 1024 * 1024, U: "binBps"}, "GiBs")) | ||
} |
Oops, something went wrong.