Rename some functions and fix tests accordingly. Fix README

This commit is contained in:
Thomas Roehl 2022-03-18 14:09:35 +01:00
parent 70cc2cbe8e
commit 92a0c64422
3 changed files with 98 additions and 20 deletions

View File

@ -14,7 +14,7 @@ type Unit interface {
Valid() bool Valid() bool
String() string String() string
Short() string Short() string
AddDivisorUnit(div Measure) AddUnitDenominator(div Measure)
} }
``` ```
@ -69,7 +69,7 @@ if err == nil {
value, ok := metric.GetField("value") value, ok := metric.GetField("value")
if ok { if ok {
out_unit = NewUnit(in_unit) out_unit = NewUnit(in_unit)
out_unit.AddDivisorUnit("seconds") out_unit.AddUnitDenominator("seconds")
seconds := timeDiff.Seconds() seconds := timeDiff.Seconds()
y, err := lp.New(metric.Name()+"_bw", y, err := lp.New(metric.Name()+"_bw",
metric.Tags(), metric.Tags(),

View File

@ -15,19 +15,21 @@ type Unit interface {
Valid() bool Valid() bool
String() string String() string
Short() string Short() string
AddDivisorUnit(div Measure) AddUnitDenominator(div Measure)
getPrefix() Prefix getPrefix() Prefix
getMeasure() Measure getMeasure() Measure
getDivMeasure() Measure getUnitDenominator() Measure
setPrefix(p Prefix) setPrefix(p Prefix)
} }
var INVALID_UNIT = NewUnit("foobar") var INVALID_UNIT = NewUnit("foobar")
// Check whether a unit is a valid unit. It requires at least a prefix and a measure. The unit denominator is optional
func (u *unit) Valid() bool { func (u *unit) Valid() bool {
return u.measure != InvalidMeasure return u.prefix != InvalidPrefix && u.measure != InvalidMeasure
} }
// Get the long string for the unit like 'KiloHertz'
func (u *unit) String() string { func (u *unit) String() string {
if u.divMeasure != InvalidMeasure { if u.divMeasure != InvalidMeasure {
return fmt.Sprintf("%s%s/%s", u.prefix.String(), u.measure.String(), u.divMeasure.String()) return fmt.Sprintf("%s%s/%s", u.prefix.String(), u.measure.String(), u.divMeasure.String())
@ -36,6 +38,7 @@ func (u *unit) String() string {
} }
} }
// Get the short string for the unit like 'KHz' (recommened over String()!)
func (u *unit) Short() string { func (u *unit) Short() string {
if u.divMeasure != InvalidMeasure { if u.divMeasure != InvalidMeasure {
return fmt.Sprintf("%s%s/%s", u.prefix.Prefix(), u.measure.Short(), u.divMeasure.Short()) return fmt.Sprintf("%s%s/%s", u.prefix.Prefix(), u.measure.Short(), u.divMeasure.Short())
@ -44,7 +47,8 @@ func (u *unit) Short() string {
} }
} }
func (u *unit) AddDivisorUnit(div Measure) { //
func (u *unit) AddUnitDenominator(div Measure) {
u.divMeasure = div u.divMeasure = div
} }
@ -60,25 +64,95 @@ func (u *unit) getMeasure() Measure {
return u.measure return u.measure
} }
func (u *unit) getDivMeasure() Measure { func (u *unit) getUnitDenominator() Measure {
return u.divMeasure return u.divMeasure
} }
func GetPrefixPrefixFactor(in Prefix, out Prefix) func(value float64) float64 { // This creates the default conversion function between two prefixes
func GetPrefixPrefixFactor(in Prefix, out Prefix) func(value interface{}) interface{} {
var factor = 1.0 var factor = 1.0
var in_prefix = float64(in) var in_prefix = float64(in)
var out_prefix = float64(out) var out_prefix = float64(out)
factor = in_prefix / out_prefix factor = in_prefix / out_prefix
return func(value float64) float64 { return factor } conv := func(value interface{}) interface{} {
switch v := value.(type) {
case float64:
return v * factor
case float32:
return float32(float64(v) * factor)
case int:
return int(float64(v) * factor)
case int32:
return int32(float64(v) * factor)
case int64:
return int64(float64(v) * factor)
case uint:
return uint(float64(v) * factor)
case uint32:
return uint32(float64(v) * factor)
case uint64:
return uint64(float64(v) * factor)
}
return value
}
return conv
} }
func GetPrefixStringPrefixStringFactor(in string, out string) func(value float64) float64 { // This is the conversion function between temperatures in Celsius to Fahrenheit
func convertTempC2TempF(value interface{}) interface{} {
switch v := value.(type) {
case float64:
return (v * 1.8) + 32
case float32:
return (v * 1.8) + 32
case int:
return int((float64(v) * 1.8) + 32)
case int32:
return int32((float64(v) * 1.8) + 32)
case int64:
return int64((float64(v) * 1.8) + 32)
case uint:
return uint((float64(v) * 1.8) + 32)
case uint32:
return uint32((float64(v) * 1.8) + 32)
case uint64:
return uint64((float64(v) * 1.8) + 32)
}
return value
}
// This is the conversion function between temperatures in Fahrenheit to Celsius
func convertTempF2TempC(value interface{}) interface{} {
switch v := value.(type) {
case float64:
return (v - 32) / 1.8
case float32:
return (v - 32) / 1.8
case int:
return int(((float64(v) - 32) / 1.8))
case int32:
return int32(((float64(v) - 32) / 1.8))
case int64:
return int64(((float64(v) - 32) / 1.8))
case uint:
return uint(((float64(v) - 32) / 1.8))
case uint32:
return uint32(((float64(v) - 32) / 1.8))
case uint64:
return uint64(((float64(v) - 32) / 1.8))
}
return value
}
// If we only have strings with the prefixes, this is a handy wrapper
func GetPrefixStringPrefixStringFactor(in string, out string) func(value interface{}) interface{} {
var i Prefix = NewPrefix(in) var i Prefix = NewPrefix(in)
var o Prefix = NewPrefix(out) var o Prefix = NewPrefix(out)
return GetPrefixPrefixFactor(i, o) return GetPrefixPrefixFactor(i, o)
} }
func GetUnitPrefixFactor(in Unit, out Prefix) (func(value float64) float64, Unit) { // Get the conversion function and resulting unit for a unit and a prefix
func GetUnitPrefixFactor(in Unit, out Prefix) (func(value interface{}) interface{}, Unit) {
outUnit := NewUnit(in.Short()) outUnit := NewUnit(in.Short())
if outUnit.Valid() { if outUnit.Valid() {
outUnit.setPrefix(out) outUnit.setPrefix(out)
@ -88,27 +162,31 @@ func GetUnitPrefixFactor(in Unit, out Prefix) (func(value float64) float64, Unit
return nil, INVALID_UNIT return nil, INVALID_UNIT
} }
func GetUnitPrefixStringFactor(in Unit, out string) (func(value float64) float64, Unit) { // Get the conversion function and resulting unit for a unit and a prefix as string
func GetUnitPrefixStringFactor(in Unit, out string) (func(value interface{}) interface{}, Unit) {
var o Prefix = NewPrefix(out) var o Prefix = NewPrefix(out)
return GetUnitPrefixFactor(in, o) return GetUnitPrefixFactor(in, o)
} }
func GetUnitStringPrefixStringFactor(in string, out string) (func(value float64) float64, Unit) { // Get the conversion function and resulting unit for a unit and a prefix when both are only string representations
func GetUnitStringPrefixStringFactor(in string, out string) (func(value interface{}) interface{}, Unit) {
var i = NewUnit(in) var i = NewUnit(in)
return GetUnitPrefixStringFactor(i, out) return GetUnitPrefixStringFactor(i, out)
} }
func GetUnitUnitFactor(in Unit, out Unit) (func(value float64) float64, error) { // Get the conversion function and (maybe) error for unit to unit conversion
func GetUnitUnitFactor(in Unit, out Unit) (func(value interface{}) interface{}, error) {
if in.getMeasure() == TemperatureC && out.getMeasure() == TemperatureF { if in.getMeasure() == TemperatureC && out.getMeasure() == TemperatureF {
return func(value float64) float64 { return (value * 1.8) + 32 }, nil return convertTempC2TempF, nil
} else if in.getMeasure() == TemperatureF && out.getMeasure() == TemperatureC { } else if in.getMeasure() == TemperatureF && out.getMeasure() == TemperatureC {
return func(value float64) float64 { return (value - 32) / 1.8 }, nil return convertTempF2TempC, nil
} else if in.getMeasure() != out.getMeasure() || in.getDivMeasure() != out.getDivMeasure() { } else if in.getMeasure() != out.getMeasure() || in.getUnitDenominator() != out.getUnitDenominator() {
return func(value float64) float64 { return 1.0 }, fmt.Errorf("invalid measures in in and out Unit") return func(value interface{}) interface{} { return 1.0 }, fmt.Errorf("invalid measures in in and out Unit")
} }
return GetPrefixPrefixFactor(in.getPrefix(), out.getPrefix()), nil return GetPrefixPrefixFactor(in.getPrefix(), out.getPrefix()), nil
} }
// Create a new unit out of a string representing a unit like 'Mbyte/s' or 'GHz'.
func NewUnit(unitStr string) Unit { func NewUnit(unitStr string) Unit {
u := &unit{ u := &unit{
prefix: InvalidPrefix, prefix: InvalidPrefix,

View File

@ -66,7 +66,7 @@ func TestUnitsExact(t *testing.T) {
{"F/B", NewUnit("flops/Bytes")}, {"F/B", NewUnit("flops/Bytes")},
} }
compareUnitExact := func(in, out Unit) bool { compareUnitExact := func(in, out Unit) bool {
if in.getMeasure() == out.getMeasure() && in.getDivMeasure() == out.getDivMeasure() && in.getPrefix() == out.getPrefix() { if in.getMeasure() == out.getMeasure() && in.getUnitDenominator() == out.getUnitDenominator() && in.getPrefix() == out.getPrefix() {
return true return true
} }
return false return false
@ -96,7 +96,7 @@ func TestUnitUnitConversion(t *testing.T) {
{"mb", NewUnit("MBytes"), 1.0}, {"mb", NewUnit("MBytes"), 1.0},
} }
compareUnitWithPrefix := func(in, out Unit, factor float64) bool { compareUnitWithPrefix := func(in, out Unit, factor float64) bool {
if in.getMeasure() == out.getMeasure() && in.getDivMeasure() == out.getDivMeasure() { if in.getMeasure() == out.getMeasure() && in.getUnitDenominator() == out.getUnitDenominator() {
if f := GetPrefixPrefixFactor(in.getPrefix(), out.getPrefix()); f(1.0) == factor { if f := GetPrefixPrefixFactor(in.getPrefix(), out.getPrefix()); f(1.0) == factor {
return true return true
} else { } else {