@@ -34,32 +34,27 @@ import (
3434 "go.opentelemetry.io/otel"
3535 "go.opentelemetry.io/otel/attribute"
3636 "google.golang.org/protobuf/proto"
37- "google.golang.org/protobuf/reflect/protodesc"
3837 "google.golang.org/protobuf/reflect/protoreflect"
3938 "google.golang.org/protobuf/types/dynamicpb"
4039
4140 "go.linka.cloud/protodb/internal/badgerd"
4241 "go.linka.cloud/protodb/internal/protodb"
42+ "go.linka.cloud/protodb/internal/registry"
4343 protopts "go.linka.cloud/protodb/protodb"
4444)
4545
4646var idxTracer = otel .Tracer ("protodb.indexer" )
4747
48- type FileRegistry interface {
49- RangeFiles (func (protoreflect.FileDescriptor ) bool )
50- }
51-
5248type Tx interface {
5349 Txn () badgerd.Tx
5450 UID (ctx context.Context , key []byte , inc bool ) (uint64 , bool , error )
5551}
5652
5753type Indexer struct {
58- reg protodesc.Resolver
59- freg FileRegistry
54+ reg * registry.Registry
6055 unmarshal func ([]byte , proto.Message ) error
6156 mu sync.RWMutex
62- entries map [protoreflect.FullName ]entryCache
57+ keys map [protoreflect.FullName ]entryCache
6358}
6459
6560type FindOpts struct {
@@ -73,8 +68,8 @@ type entryCache struct {
7368 entries []string
7469}
7570
76- func NewIndexer (reg protodesc. Resolver , freg FileRegistry , unmarshal func ([]byte , proto.Message ) error ) * Indexer {
77- return & Indexer {reg : reg , freg : freg , unmarshal : unmarshal }
71+ func NewIndexer (reg * registry. Registry , unmarshal func ([]byte , proto.Message ) error ) * Indexer {
72+ return & Indexer {reg : reg , unmarshal : unmarshal }
7873}
7974
8075func (idx * Indexer ) RebuildIfNeeded (ctx context.Context , tx Tx , files ... protoreflect.FileDescriptor ) error {
@@ -88,7 +83,7 @@ func (idx *Indexer) Rebuild(ctx context.Context, tx Tx, files ...protoreflect.Fi
8883 defer span .End ()
8984 msgs := collectMessagesFromFiles (files )
9085 if len (files ) == 0 {
91- msgs = collectMessageDescriptors (idx .freg )
86+ msgs = collectMessageDescriptors (idx .reg )
9287 }
9388 span .SetAttributes (
9489 attribute .Int ("index.messages" , len (msgs )),
@@ -137,18 +132,18 @@ func (idx *Indexer) SchemaEntries(ctx context.Context, tx badgerd.Tx, md protore
137132func (idx * Indexer ) CollectEntries (md protoreflect.MessageDescriptor ) []string {
138133 sig := entrySig (md )
139134 idx .mu .RLock ()
140- if ent , ok := idx .entries [md .FullName ()]; ok && ent .sig == sig {
135+ if ent , ok := idx .keys [md .FullName ()]; ok && ent .sig == sig {
141136 entries := append ([]string (nil ), ent .entries ... )
142137 idx .mu .RUnlock ()
143138 return entries
144139 }
145140 idx .mu .RUnlock ()
146141 entries := collectIndexEntries (md )
147142 idx .mu .Lock ()
148- if idx .entries == nil {
149- idx .entries = map [protoreflect.FullName ]entryCache {}
143+ if idx .keys == nil {
144+ idx .keys = map [protoreflect.FullName ]entryCache {}
150145 }
151- idx .entries [md .FullName ()] = entryCache {sig : sig , entries : entries }
146+ idx .keys [md .FullName ()] = entryCache {sig : sig , entries : entries }
152147 idx .mu .Unlock ()
153148 return append ([]string (nil ), entries ... )
154149}
@@ -175,7 +170,7 @@ func (idx *Indexer) IndexableFilter(m proto.Message, f protodb.Filter) (bool, er
175170 if f == nil || f .Expr () == nil {
176171 return false , nil
177172 }
178- return isIndexableExpr (m .ProtoReflect ().New (), f .Expr ())
173+ return idx . isIndexableExpr (m .ProtoReflect ().New (), f .Expr ())
179174}
180175
181176func (idx * Indexer ) EnforceUnique (ctx context.Context , tx Tx , m proto.Message , uid uint64 ) error {
@@ -820,7 +815,7 @@ func collectIndexEntries(md protoreflect.MessageDescriptor) []string {
820815 walk (fd .Message (), prefix + fmt .Sprintf ("%d" , fd .Number ())+ "." )
821816 continue
822817 }
823- if ! proto .HasExtension (fd .Options (), protopts .E_Index ) || ! isIndexableField (fd ) {
818+ if ! proto .HasExtension (fd .Options (), protopts .E_Index ) || ! IsIndexableLeaf (fd ) {
824819 continue
825820 }
826821 entries = append (entries , fmt .Sprintf ("%s%d|%s|%d" , prefix , fd .Number (), fd .Kind (), fd .Cardinality ()))
@@ -831,12 +826,12 @@ func collectIndexEntries(md protoreflect.MessageDescriptor) []string {
831826 return entries
832827}
833828
834- func collectMessageDescriptors (freg FileRegistry ) []protoreflect.MessageDescriptor {
835- if freg == nil {
829+ func collectMessageDescriptors (reg * registry. Registry ) []protoreflect.MessageDescriptor {
830+ if reg == nil {
836831 return nil
837832 }
838833 var out []protoreflect.MessageDescriptor
839- freg .RangeFiles (func (fd protoreflect.FileDescriptor ) bool {
834+ reg .RangeFiles (func (fd protoreflect.FileDescriptor ) bool {
840835 out = append (out , collectMessages (fd .Messages ())... )
841836 return true
842837 })
@@ -937,32 +932,32 @@ func collectUniqueFromMsgList(val protoreflect.Value, fds ...protoreflect.FieldD
937932 return out , nil
938933}
939934
940- func isIndexableExpr (msg protoreflect.Message , expr * filters.Expression ) (bool , error ) {
935+ func ( idx * Indexer ) isIndexableExpr (msg protoreflect.Message , expr * filters.Expression ) (bool , error ) {
941936 if expr == nil {
942937 return true , nil
943938 }
944939 if expr .Condition != nil {
945- ok , err := isIndexableFieldPath (msg , expr .Condition .GetField ())
940+ ok , err := idx . isIndexableFieldPath (msg , expr .Condition .GetField ())
946941 if err != nil || ! ok {
947942 return ok , err
948943 }
949944 }
950945 for _ , v := range expr .AndExprs {
951- ok , err := isIndexableExpr (msg , v )
946+ ok , err := idx . isIndexableExpr (msg , v )
952947 if err != nil || ! ok {
953948 return ok , err
954949 }
955950 }
956951 for _ , v := range expr .OrExprs {
957- ok , err := isIndexableExpr (msg , v )
952+ ok , err := idx . isIndexableExpr (msg , v )
958953 if err != nil || ! ok {
959954 return ok , err
960955 }
961956 }
962957 return true , nil
963958}
964959
965- func isIndexableFieldPath (msg protoreflect.Message , fieldPath string ) (bool , error ) {
960+ func ( idx * Indexer ) isIndexableFieldPath (msg protoreflect.Message , fieldPath string ) (bool , error ) {
966961 if fieldPath == "" {
967962 return false , nil
968963 }
@@ -974,26 +969,33 @@ func isIndexableFieldPath(msg protoreflect.Message, fieldPath string) (bool, err
974969 if proto .HasExtension (fd .Options (), protopts .E_Index ) {
975970 return isIndexableFieldPathDescriptors (fds ), nil
976971 }
977- if ! isKeyField (msg .Descriptor (), fds ) {
972+ if ! idx . isKeyField (msg .Descriptor (), fds ) {
978973 return false , nil
979974 }
980975 return isIndexableFieldPathDescriptors (fds ), nil
981976}
982977
983- func isKeyField (md protoreflect.MessageDescriptor , fds []protoreflect.FieldDescriptor ) bool {
978+ func ( idx * Indexer ) isKeyField (md protoreflect.MessageDescriptor , fds []protoreflect.FieldDescriptor ) bool {
984979 if md == nil {
985980 return false
986981 }
987982 if len (fds ) == 0 {
988983 return false
989984 }
990- field , ok := protodb . KeyFieldName (md )
985+ field , ok := keyName (md , idx . reg )
991986 if ! ok {
992987 return false
993988 }
994989 return field == fieldPathFromNames (fds )
995990}
996991
992+ func keyName (md protoreflect.MessageDescriptor , reg * registry.Registry ) (string , bool ) {
993+ if reg == nil {
994+ return protodb .KeyFieldName (md )
995+ }
996+ return reg .KeyFieldName (md )
997+ }
998+
997999func isIndexableFieldPathDescriptors (fds []protoreflect.FieldDescriptor ) bool {
9981000 if len (fds ) == 0 {
9991001 return false
@@ -1016,10 +1018,6 @@ func isIndexableFieldPathDescriptors(fds []protoreflect.FieldDescriptor) bool {
10161018 return IsIndexableLeaf (last )
10171019}
10181020
1019- func isIndexableField (fd protoreflect.FieldDescriptor ) bool {
1020- return IsIndexableLeaf (fd )
1021- }
1022-
10231021// IsIndexableLeaf reports whether a field descriptor supports index ordering/lookup.
10241022func IsIndexableLeaf (fd protoreflect.FieldDescriptor ) bool {
10251023 switch fd .Kind () {
0 commit comments