mirror of
https://github.com/gonum/gonum.git
synced 2025-10-28 17:31:56 +08:00
Remove mutex and simplify dimension handling
Lookups are now done via a slice where possible.
This commit is contained in:
171
unittype.go
171
unittype.go
@@ -3,7 +3,6 @@ package unit
|
|||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Uniter is an interface representing a type that can be converted
|
// Uniter is an interface representing a type that can be converted
|
||||||
@@ -36,84 +35,86 @@ const (
|
|||||||
TemperatureDim
|
TemperatureDim
|
||||||
TimeDim
|
TimeDim
|
||||||
// Other common SI Dimensions
|
// Other common SI Dimensions
|
||||||
AngleDim // e.g. radians
|
AngleDim // e.g. radians
|
||||||
lastPackageDimension // Used in create dimension
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var lastCreatedDimension Dimension = lastPackageDimension
|
var (
|
||||||
var dimensionToSymbol map[Dimension]string = map[Dimension]string{
|
symbols = []string{
|
||||||
CurrentDim: "A",
|
CurrentDim: "A",
|
||||||
LengthDim: "m",
|
LengthDim: "m",
|
||||||
LuminousIntensityDim: "cd",
|
LuminousIntensityDim: "cd",
|
||||||
MassDim: "kg",
|
MassDim: "kg",
|
||||||
TemperatureDim: "K",
|
TemperatureDim: "K",
|
||||||
TimeDim: "s",
|
TimeDim: "s",
|
||||||
AngleDim: "rad",
|
AngleDim: "rad",
|
||||||
}
|
}
|
||||||
var symbolToDimension map[string]Dimension = map[string]Dimension{
|
|
||||||
"A": CurrentDim,
|
|
||||||
"m": LengthDim,
|
|
||||||
"cd": LuminousIntensityDim,
|
|
||||||
"kg": MassDim,
|
|
||||||
"K": TemperatureDim,
|
|
||||||
"s": TimeDim,
|
|
||||||
"rad": AngleDim,
|
|
||||||
|
|
||||||
// Reserve common SI symbols
|
// for guaranteeing there aren't two identical symbols
|
||||||
// base units
|
dimensions = map[string]Dimension{
|
||||||
"mol": reserved,
|
"A": CurrentDim,
|
||||||
// prefixes
|
"m": LengthDim,
|
||||||
"Y": reserved,
|
"cd": LuminousIntensityDim,
|
||||||
"Z": reserved,
|
"kg": MassDim,
|
||||||
"E": reserved,
|
"K": TemperatureDim,
|
||||||
"P": reserved,
|
"s": TimeDim,
|
||||||
"T": reserved,
|
"rad": AngleDim,
|
||||||
"G": reserved,
|
|
||||||
"M": reserved,
|
// Reserve common SI symbols
|
||||||
"k": reserved,
|
// base units
|
||||||
"h": reserved,
|
"mol": reserved,
|
||||||
"da": reserved,
|
// prefixes
|
||||||
"d": reserved,
|
"Y": reserved,
|
||||||
"c": reserved,
|
"Z": reserved,
|
||||||
"μ": reserved,
|
"E": reserved,
|
||||||
"n": reserved,
|
"P": reserved,
|
||||||
"p": reserved,
|
"T": reserved,
|
||||||
"f": reserved,
|
"G": reserved,
|
||||||
"a": reserved,
|
"M": reserved,
|
||||||
"z": reserved,
|
"k": reserved,
|
||||||
"y": reserved,
|
"h": reserved,
|
||||||
// SI Derived units with special symbols
|
"da": reserved,
|
||||||
"sr": reserved,
|
"d": reserved,
|
||||||
"F": reserved,
|
"c": reserved,
|
||||||
"C": reserved,
|
"μ": reserved,
|
||||||
"S": reserved,
|
"n": reserved,
|
||||||
"H": reserved,
|
"p": reserved,
|
||||||
"V": reserved,
|
"f": reserved,
|
||||||
"Ω": reserved,
|
"a": reserved,
|
||||||
"J": reserved,
|
"z": reserved,
|
||||||
"N": reserved,
|
"y": reserved,
|
||||||
"Hz": reserved,
|
// SI Derived units with special symbols
|
||||||
"lx": reserved,
|
"sr": reserved,
|
||||||
"lm": reserved,
|
"F": reserved,
|
||||||
"Wb": reserved,
|
"C": reserved,
|
||||||
"W": reserved,
|
"S": reserved,
|
||||||
"Pa": reserved,
|
"H": reserved,
|
||||||
"Bq": reserved,
|
"V": reserved,
|
||||||
"Gy": reserved,
|
"Ω": reserved,
|
||||||
"Sv": reserved,
|
"J": reserved,
|
||||||
"kat": reserved,
|
"N": reserved,
|
||||||
// Units in use with SI
|
"Hz": reserved,
|
||||||
"ha": reserved,
|
"lx": reserved,
|
||||||
"L": reserved,
|
"lm": reserved,
|
||||||
"l": reserved,
|
"Wb": reserved,
|
||||||
// Units in Use Temporarily with SI
|
"W": reserved,
|
||||||
"bar": reserved,
|
"Pa": reserved,
|
||||||
"b": reserved,
|
"Bq": reserved,
|
||||||
"Ci": reserved,
|
"Gy": reserved,
|
||||||
"R": reserved,
|
"Sv": reserved,
|
||||||
"rd": reserved,
|
"kat": reserved,
|
||||||
"rem": reserved,
|
// Units in use with SI
|
||||||
} // for guaranteeing there aren't two identical symbols
|
"ha": reserved,
|
||||||
|
"L": reserved,
|
||||||
|
"l": reserved,
|
||||||
|
// Units in Use Temporarily with SI
|
||||||
|
"bar": reserved,
|
||||||
|
"b": reserved,
|
||||||
|
"Ci": reserved,
|
||||||
|
"R": reserved,
|
||||||
|
"rd": reserved,
|
||||||
|
"rem": reserved,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// TODO: Should we actually reserve "common" SI unit symbols ("N", "J", etc.) so there isn't confusion
|
// TODO: Should we actually reserve "common" SI unit symbols ("N", "J", etc.) so there isn't confusion
|
||||||
// TODO: If we have a fancier ParseUnit, maybe the 'reserved' symbols should be a different map
|
// TODO: If we have a fancier ParseUnit, maybe the 'reserved' symbols should be a different map
|
||||||
@@ -124,8 +125,6 @@ var symbolToDimension map[string]Dimension = map[string]Dimension{
|
|||||||
// dimension is zero. Dimensions is used in conjuction with NewUnit
|
// dimension is zero. Dimensions is used in conjuction with NewUnit
|
||||||
type Dimensions map[Dimension]int
|
type Dimensions map[Dimension]int
|
||||||
|
|
||||||
var newUnitMutex *sync.Mutex = &sync.Mutex{} // so there is no race condition for dimension
|
|
||||||
|
|
||||||
// NewDimension returns a new dimension variable which will have a
|
// NewDimension returns a new dimension variable which will have a
|
||||||
// unique representation across packages to prevent accidental overlap.
|
// unique representation across packages to prevent accidental overlap.
|
||||||
// The input string represents a symbol name which will be used for printing
|
// The input string represents a symbol name which will be used for printing
|
||||||
@@ -138,18 +137,16 @@ var newUnitMutex *sync.Mutex = &sync.Mutex{} // so there is no race condition fo
|
|||||||
// if the symbol matching an existing symbol
|
// if the symbol matching an existing symbol
|
||||||
// NewDimension should only be called for unit types that are actually orthogonal
|
// NewDimension should only be called for unit types that are actually orthogonal
|
||||||
// to the base dimensions defined in this package. Please see the package-level
|
// to the base dimensions defined in this package. Please see the package-level
|
||||||
// documentation for further explanation
|
// documentation for further explanation. Calls to NewDimension are not thread safe.
|
||||||
func NewDimension(symbol string) Dimension {
|
func NewDimension(symbol string) Dimension {
|
||||||
newUnitMutex.Lock()
|
_, ok := dimensions[symbol]
|
||||||
defer newUnitMutex.Unlock()
|
|
||||||
lastCreatedDimension++
|
|
||||||
_, ok := symbolToDimension[symbol]
|
|
||||||
if ok {
|
if ok {
|
||||||
panic("unit: dimension string " + symbol + " already used")
|
panic("unit: dimension string " + symbol + " already used")
|
||||||
}
|
}
|
||||||
dimensionToSymbol[lastCreatedDimension] = symbol
|
symbols = append(symbols, symbol)
|
||||||
symbolToDimension[symbol] = lastCreatedDimension
|
d := Dimension(len(symbols))
|
||||||
return lastCreatedDimension
|
dimensions[symbol] = d
|
||||||
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unit is a type a value with generic SI units. Most useful for
|
// Unit is a type a value with generic SI units. Most useful for
|
||||||
@@ -272,7 +269,7 @@ func (u *Unit) String() string {
|
|||||||
data := make(unitPrinters, 0, 10)
|
data := make(unitPrinters, 0, 10)
|
||||||
for dimension, power := range u.dimensions {
|
for dimension, power := range u.dimensions {
|
||||||
if power != 0 {
|
if power != 0 {
|
||||||
data = append(data, symbolString{dimensionToSymbol[dimension], power})
|
data = append(data, symbolString{symbols[dimension], power})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Sort(data)
|
sort.Sort(data)
|
||||||
|
|||||||
Reference in New Issue
Block a user