@@ -4,17 +4,26 @@ internal class Registry {
44 // TODO: Should we eliminate this singleton and make clients keep track?
55 internal static let instance = Registry ( )
66
7- // Store units as a dictionary based on symbol for fast access
8- // TODO: Change to Unit to avoid creating multiple Units in memory
9- private var units : [ String : DefinedUnit ]
7+ // Quick access based on symbol
8+ private var symbolMap : [ String : DefinedUnit ]
9+ // Quick access based on name
10+ private var nameMap : [ String : DefinedUnit ]
11+
1012 private init ( ) {
11- units = [ : ]
13+ symbolMap = [ : ]
14+ nameMap = [ : ]
1215 for defaultUnit in Registry . defaultUnits {
1316 // Protect against double-defining symbols
14- if units [ defaultUnit. symbol] != nil {
17+ if symbolMap [ defaultUnit. symbol] != nil {
1518 fatalError ( " Duplicate symbol: \( defaultUnit. symbol) " )
1619 }
17- units [ defaultUnit. symbol] = defaultUnit
20+ symbolMap [ defaultUnit. symbol] = defaultUnit
21+
22+ // Protect against double-defining names
23+ if nameMap [ defaultUnit. name] != nil {
24+ fatalError ( " Duplicate name: \( defaultUnit. name) " )
25+ }
26+ nameMap [ defaultUnit. name] = defaultUnit
1827 }
1928 }
2029
@@ -28,21 +37,30 @@ internal class Registry {
2837 guard exponent != 0 else {
2938 continue
3039 }
31- let definedUnit = try definedUnitFromSymbol ( symbol : definedUnitSymbol)
40+ let definedUnit = try getUnit ( bySymbol : definedUnitSymbol)
3241 compositeUnits [ definedUnit] = exponent
3342 }
3443 return compositeUnits
3544 }
3645
3746 /// Returns a defined unit given a defined unit symbol. It is expected that the caller has
3847 /// verified that this is not a composite unit.
39- internal func definedUnitFromSymbol ( symbol: String ) throws -> DefinedUnit {
40- guard let definedUnit = units [ symbol] else {
48+ internal func getUnit ( bySymbol symbol: String ) throws -> DefinedUnit {
49+ guard let definedUnit = symbolMap [ symbol] else {
4150 throw UnitError . unitNotFound ( message: " Symbol ' \( symbol) ' not recognized " )
4251 }
4352 return definedUnit
4453 }
4554
55+ /// Returns a defined unit given a defined unit name. It is expected that the caller has
56+ /// verified that this is not a composite unit.
57+ internal func getUnit( byName name: String ) throws -> DefinedUnit {
58+ guard let definedUnit = nameMap [ name] else {
59+ throw UnitError . unitNotFound ( message: " Name ' \( name) ' not recognized " )
60+ }
61+ return definedUnit
62+ }
63+
4664 /// Define a new unit to add to the registry
4765 /// - parameter name: The string name of the unit.
4866 /// - parameter symbol: The string symbol of the unit. Symbols may not contain the characters `*`, `/`, or `^`.
@@ -64,16 +82,22 @@ internal class Registry {
6482 constant: constant
6583 )
6684 // Protect against double-defining symbols
67- if units [ symbol] != nil {
85+ if symbolMap [ symbol] != nil {
6886 throw UnitError . invalidSymbol ( message: " Duplicate symbol: \( symbol) " )
6987 }
70- units [ symbol] = newUnit
88+ symbolMap [ symbol] = newUnit
89+
90+ // Protect against double-defining names
91+ if nameMap [ name] != nil {
92+ fatalError ( " Duplicate name: \( name) " )
93+ }
94+ nameMap [ name] = newUnit
7195 }
7296
7397 /// Returns all units currently defined by the registry
7498 internal func allUnits( ) -> [ Unit ] {
7599 var allUnits = [ Unit] ( )
76- for (_, unit) in units {
100+ for (_, unit) in symbolMap {
77101 allUnits. append ( Unit ( definedBy: unit) )
78102 }
79103 return allUnits
0 commit comments