Skip to content

Commit

Permalink
Document type registry and make safe for concurrent use
Browse files Browse the repository at this point in the history
  • Loading branch information
magiconair committed Jul 11, 2019
1 parent 8c6f237 commit 32c4f51
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions ua/typereg.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,53 @@ package ua
import (
"fmt"
"reflect"
"sync"
)

// TypeRegistry maps numeric ids to Go types.
// The implementation is safe for concurrent use.
type TypeRegistry struct {
mu sync.RWMutex
types map[uint32]reflect.Type
ids map[reflect.Type]uint32
}

// NewTypeRegistry returns a new type registry.
func NewTypeRegistry() *TypeRegistry {
return &TypeRegistry{
types: make(map[uint32]reflect.Type),
ids: make(map[reflect.Type]uint32),
}
}

// New returns a new instance of the type with the given id.
// If the id is not known the function returns nil.
func (r *TypeRegistry) New(id uint32) interface{} {
r.mu.RLock()
defer r.mu.RUnlock()

typ, ok := r.types[id]
if !ok {
return nil
}
return reflect.New(typ.Elem()).Interface()
}

// Lookup returns the id of the type of v or zero if the
// type is not registered.
func (r *TypeRegistry) Lookup(v interface{}) uint32 {
r.mu.RLock()
defer r.mu.RUnlock()

return r.ids[reflect.TypeOf(v)]
}

// Register adds a new type to the registry. If either the type
// or the id is already registered the function returns an error.
func (r *TypeRegistry) Register(id uint32, v interface{}) error {
r.mu.Lock()
defer r.mu.Unlock()

typ := reflect.TypeOf(v)

if r.types[id] != nil {
Expand Down

0 comments on commit 32c4f51

Please sign in to comment.