mirror of https://github.com/grpc/grpc-go.git
Make use of cache maps
This commit is contained in:
parent
8c8bcdd402
commit
1be569e2d5
|
@ -13,6 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type serverReflectionServer struct {
|
type serverReflectionServer struct {
|
||||||
|
// TODO mu is not used. Add lock() and unlock().
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
typeToNameMap map[reflect.Type]string
|
typeToNameMap map[reflect.Type]string
|
||||||
nameToTypeMap map[string]reflect.Type
|
nameToTypeMap map[string]reflect.Type
|
||||||
|
@ -33,28 +34,27 @@ type protoMessage interface {
|
||||||
Descriptor() ([]byte, []int)
|
Descriptor() ([]byte, []int)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO return an error rather than a bool
|
|
||||||
func (s *serverReflectionServer) fileDescForType(st reflect.Type) (*dpb.FileDescriptorProto, []int, error) {
|
func (s *serverReflectionServer) fileDescForType(st reflect.Type) (*dpb.FileDescriptorProto, []int, error) {
|
||||||
|
// Indexes list is not stored in cache.
|
||||||
|
// So this step is needed to get idxs.
|
||||||
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(protoMessage)
|
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(protoMessage)
|
||||||
if !ok {
|
if !ok {
|
||||||
// TODO better print content.
|
|
||||||
return nil, nil, fmt.Errorf("failed to create message from type: %v", st)
|
return nil, nil, fmt.Errorf("failed to create message from type: %v", st)
|
||||||
}
|
}
|
||||||
enc, idxs := m.Descriptor()
|
enc, idxs := m.Descriptor()
|
||||||
|
|
||||||
// TODO Check cache first.
|
// Check type to fileDesc cache.
|
||||||
// if fn, ok := s.typeToFilenameMap[st]; ok {
|
if fd, ok := s.typeToFileDescMap[st]; ok {
|
||||||
// if fd, ok := s.filenameToDescMap[fn]; ok {
|
return fd, idxs, nil
|
||||||
// return fd, idxs, ok
|
}
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
// Cache missed, try to decode.
|
||||||
fd, err := s.decodeFileDesc(enc)
|
fd, err := s.decodeFileDesc(enc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
// TODO Cache missed, add to cache.
|
// Add to cache.
|
||||||
// s.typeToFilenameMap[st] = fd.GetName()
|
s.typeToFileDescMap[st] = fd
|
||||||
return fd, idxs, nil
|
return fd, idxs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,9 +68,9 @@ func (s *serverReflectionServer) decodeFileDesc(enc []byte) (*dpb.FileDescriptor
|
||||||
if err := proto.Unmarshal(raw, fd); err != nil {
|
if err := proto.Unmarshal(raw, fd); err != nil {
|
||||||
return nil, fmt.Errorf("bad descriptor: %v", err)
|
return nil, fmt.Errorf("bad descriptor: %v", err)
|
||||||
}
|
}
|
||||||
// TODO If decodeFileDesc is called, it's the first time this file is seen.
|
// If decodeFileDesc is called, it's the first time this file is seen.
|
||||||
// Add it to cache.
|
// Add it to cache.
|
||||||
// s.filenameToDescMap[fd.GetName()] = fd
|
s.filenameToDescMap[fd.GetName()] = fd
|
||||||
return fd, nil
|
return fd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,25 +89,38 @@ func decompress(b []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serverReflectionServer) typeForName(name string) (reflect.Type, error) {
|
func (s *serverReflectionServer) typeForName(name string) (reflect.Type, error) {
|
||||||
// TODO cache
|
// Check cache first.
|
||||||
|
if st, ok := s.nameToTypeMap[name]; ok {
|
||||||
|
return st, nil
|
||||||
|
}
|
||||||
|
|
||||||
pt := proto.MessageType(name)
|
pt := proto.MessageType(name)
|
||||||
if pt == nil {
|
if pt == nil {
|
||||||
return nil, fmt.Errorf("unknown type: %q", name)
|
return nil, fmt.Errorf("unknown type: %q", name)
|
||||||
}
|
}
|
||||||
st := pt.Elem()
|
st := pt.Elem()
|
||||||
// TODO cache
|
|
||||||
// s.typeToNameMap[st] = name
|
// Add to cache.
|
||||||
// s.nameToTypeMap[name] = st
|
s.typeToNameMap[st] = name
|
||||||
// fd, _, ok := s.fileDescForType(st)
|
s.nameToTypeMap[name] = st
|
||||||
// if ok {
|
|
||||||
// s.typeToFilenameMap[st] = fd.GetName()
|
// TODO is this necessary?
|
||||||
// }
|
// In most cases, the returned type will be used to search
|
||||||
|
// for file descriptor.
|
||||||
|
// Add it to cache now.
|
||||||
|
fd, _, err := s.fileDescForType(st)
|
||||||
|
if err == nil {
|
||||||
|
s.typeToFileDescMap[st] = fd
|
||||||
|
}
|
||||||
|
|
||||||
return st, nil
|
return st, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serverReflectionServer) nameForType(st reflect.Type) (string, error) {
|
func (s *serverReflectionServer) nameForType(st reflect.Type) (string, error) {
|
||||||
// TODO cache
|
// Check cache first.
|
||||||
|
if name, ok := s.typeToNameMap[st]; ok {
|
||||||
|
return name, nil
|
||||||
|
}
|
||||||
|
|
||||||
var name string
|
var name string
|
||||||
fd, idxs, err := s.fileDescForType(st)
|
fd, idxs, err := s.fileDescForType(st)
|
||||||
|
@ -123,6 +136,11 @@ func (s *serverReflectionServer) nameForType(st reflect.Type) (string, error) {
|
||||||
if fd.Package != nil {
|
if fd.Package != nil {
|
||||||
name = *fd.Package + "." + name
|
name = *fd.Package + "." + name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add to cache.
|
||||||
|
s.typeToNameMap[st] = name
|
||||||
|
s.nameToTypeMap[name] = st
|
||||||
|
|
||||||
return name, nil
|
return name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +149,11 @@ func (s *serverReflectionServer) nameForPointer(i interface{}) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serverReflectionServer) filenameForType(st reflect.Type) (string, error) {
|
func (s *serverReflectionServer) filenameForType(st reflect.Type) (string, error) {
|
||||||
|
// Check cache first. The value of cache is descriptor, not filename.
|
||||||
|
if fd, ok := s.typeToFileDescMap[st]; ok {
|
||||||
|
return fd.GetName(), nil
|
||||||
|
}
|
||||||
|
|
||||||
fd, _, err := s.fileDescForType(st)
|
fd, _, err := s.fileDescForType(st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -159,8 +182,12 @@ func (s *serverReflectionServer) fileDescContainingExtension(st reflect.Type, ex
|
||||||
}
|
}
|
||||||
|
|
||||||
extT := reflect.TypeOf(extDesc.ExtensionType).Elem()
|
extT := reflect.TypeOf(extDesc.ExtensionType).Elem()
|
||||||
// TODO doesn't work if extT is simple types, like int32
|
// TODO this doesn't work if extT is simple types, like int32
|
||||||
// TODO check cache
|
// Check cache.
|
||||||
|
if fd, ok := s.typeToFileDescMap[extT]; ok {
|
||||||
|
return fd, nil
|
||||||
|
}
|
||||||
|
|
||||||
fd, _, err := s.fileDescForType(extT)
|
fd, _, err := s.fileDescForType(extT)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in New Issue