Remove mutex and simplify dimension handling

Lookups are now done via a slice where possible.
This commit is contained in:
kortschak
2013-10-10 12:19:41 +10:30
parent d3da6ef3ad
commit 7601daed10

View File

@@ -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
@@ -37,11 +36,10 @@ const (
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",
@@ -50,7 +48,9 @@ var dimensionToSymbol map[Dimension]string = map[Dimension]string{
TimeDim: "s", TimeDim: "s",
AngleDim: "rad", AngleDim: "rad",
} }
var symbolToDimension map[string]Dimension = map[string]Dimension{
// for guaranteeing there aren't two identical symbols
dimensions = map[string]Dimension{
"A": CurrentDim, "A": CurrentDim,
"m": LengthDim, "m": LengthDim,
"cd": LuminousIntensityDim, "cd": LuminousIntensityDim,
@@ -113,7 +113,8 @@ var symbolToDimension map[string]Dimension = map[string]Dimension{
"R": reserved, "R": reserved,
"rd": reserved, "rd": reserved,
"rem": reserved, "rem": reserved,
} // for guaranteeing there aren't two identical symbols }
)
// 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)