@@ -8,29 +8,37 @@ import (
88 "sync"
99 "time"
1010
11- "github.com/dgraph-io/badger/v4"
12-
11+ "github.com/jaegertracing/jaeger-idl/model/v1"
1312 "github.com/jaegertracing/jaeger/storage/spanstore"
1413)
1514
1615// CacheStore saves expensive calculations from the K/V store
1716type CacheStore struct {
1817 // Given the small amount of data these will store, we use the same structure as the memory store
19- cacheLock sync.Mutex // write heavy - Mutex is faster than RWMutex for writes
20- services map [string ]uint64
21- operations map [string ]map [string ]uint64
18+ cacheLock sync.Mutex // write heavy - Mutex is faster than RWMutex for writes
19+ services map [string ]uint64
20+ // This map is for the hierarchy: service name, kind and operation name.
21+ // Each service contains the span kinds, and then operation names belonging to that kind.
22+ // This structure will look like:
23+ /*
24+ "service1":{
25+ SpanKind.unspecified: {
26+ "operation1": uint64
27+ }
28+ }
29+ */
30+ // The uint64 value is the expiry time of operation
31+ operations map [string ]map [model.SpanKind ]map [string ]uint64
2232
23- store * badger.DB
24- ttl time.Duration
33+ ttl time.Duration
2534}
2635
2736// NewCacheStore returns initialized CacheStore for badger use
28- func NewCacheStore (db * badger. DB , ttl time.Duration ) * CacheStore {
37+ func NewCacheStore (ttl time.Duration ) * CacheStore {
2938 cs := & CacheStore {
3039 services : make (map [string ]uint64 ),
31- operations : make (map [string ]map [string ]uint64 ),
40+ operations : make (map [string ]map [model. SpanKind ] map [ string ]uint64 ),
3241 ttl : ttl ,
33- store : db ,
3442 }
3543 return cs
3644}
@@ -48,67 +56,73 @@ func (c *CacheStore) AddService(service string, keyTTL uint64) {
4856}
4957
5058// AddOperation adds the cache with operation names with most updated expiration time
51- func (c * CacheStore ) AddOperation (service , operation string , keyTTL uint64 ) {
59+ func (c * CacheStore ) AddOperation (service , operation string , kind model. SpanKind , keyTTL uint64 ) {
5260 c .cacheLock .Lock ()
5361 defer c .cacheLock .Unlock ()
5462 if _ , found := c .operations [service ]; ! found {
55- c .operations [service ] = make (map [string ]uint64 )
63+ c .operations [service ] = make (map [model. SpanKind ] map [ string ]uint64 )
5664 }
57- if v , found := c.operations [service ][operation ]; found {
65+ if _ , found := c.operations [service ][kind ]; ! found {
66+ c.operations [service ][kind ] = make (map [string ]uint64 )
67+ }
68+ if v , found := c.operations [service ][kind ][operation ]; found {
5869 if v > keyTTL {
5970 return
6071 }
6172 }
62- c.operations [service ][operation ] = keyTTL
73+ c.operations [service ][kind ][ operation ] = keyTTL
6374}
6475
6576// Update caches the results of service and service + operation indexes and maintains their TTL
66- func (c * CacheStore ) Update (service , operation string , expireTime uint64 ) {
77+ func (c * CacheStore ) Update (service , operation string , kind model. SpanKind , expireTime uint64 ) {
6778 c .cacheLock .Lock ()
6879
6980 c .services [service ] = expireTime
70- if _ , ok := c .operations [service ]; ! ok {
71- c .operations [service ] = make (map [string ]uint64 )
81+ if _ , found := c .operations [service ]; ! found {
82+ c .operations [service ] = make (map [model.SpanKind ]map [string ]uint64 )
83+ }
84+ if _ , found := c.operations [service ][kind ]; ! found {
85+ c.operations [service ][kind ] = make (map [string ]uint64 )
7286 }
73- c.operations [service ][operation ] = expireTime
87+ c.operations [service ][kind ][ operation ] = expireTime
7488 c .cacheLock .Unlock ()
7589}
7690
7791// GetOperations returns all operations for a specific service & spanKind traced by Jaeger
78- func (c * CacheStore ) GetOperations (service string ) ([]spanstore.Operation , error ) {
79- operations := make ([]string , 0 , len (c .services ))
92+ func (c * CacheStore ) GetOperations (service string , kind string ) ([]spanstore.Operation , error ) {
93+ operations := make ([]spanstore. Operation , 0 , len (c .services ))
8094 //nolint: gosec // G115
81- t := uint64 (time .Now ().Unix ())
95+ currentTime := uint64 (time .Now ().Unix ())
8296 c .cacheLock .Lock ()
8397 defer c .cacheLock .Unlock ()
84-
85- if v , ok := c .services [service ]; ok {
86- if v < t {
98+ if expiryTimeOfService , ok := c .services [service ]; ok {
99+ if expiryTimeOfService < currentTime {
87100 // Expired, remove
88101 delete (c .services , service )
89102 delete (c .operations , service )
90103 return []spanstore.Operation {}, nil // empty slice rather than nil
91104 }
92- for o , e := range c .operations [service ] {
93- if e > t {
94- operations = append (operations , o )
95- } else {
96- delete (c .operations [service ], o )
105+ for sKind := range c .operations [service ] {
106+ if kind != "" && kind != string (sKind ) {
107+ continue
108+ }
109+ for o , expiryTimeOfOperation := range c.operations [service ][sKind ] {
110+ if expiryTimeOfOperation > currentTime {
111+ op := spanstore.Operation {Name : o , SpanKind : string (sKind )}
112+ operations = append (operations , op )
113+ } else {
114+ delete (c.operations [service ][sKind ], o )
115+ }
116+ sort .Slice (operations , func (i , j int ) bool {
117+ if operations [i ].SpanKind == operations [j ].SpanKind {
118+ return operations [i ].Name < operations [j ].Name
119+ }
120+ return operations [i ].SpanKind < operations [j ].SpanKind
121+ })
97122 }
98123 }
99124 }
100-
101- sort .Strings (operations )
102-
103- // TODO: https://github.com/jaegertracing/jaeger/issues/1922
104- // - return the operations with actual spanKind
105- result := make ([]spanstore.Operation , 0 , len (operations ))
106- for _ , op := range operations {
107- result = append (result , spanstore.Operation {
108- Name : op ,
109- })
110- }
111- return result , nil
125+ return operations , nil
112126}
113127
114128// GetServices returns all services traced by Jaeger
0 commit comments