18
18
package kvstore
19
19
20
20
import (
21
+ regexp2 "regexp"
21
22
"strings"
22
23
"sync"
23
24
24
25
"github.com/apache/servicecomb-service-center/pkg/util"
25
26
)
26
27
28
+ const InitCount = 1
29
+ const InitLayer = 2
30
+ const SPLIT = "/"
31
+ const DomainProjectLayer = 6
32
+
27
33
// KvCache implements Cache.
28
34
// KvCache is dedicated to stores service discovery data,
29
35
// e.g. service, instance, lease.
30
36
type KvCache struct {
31
- Cfg * Options
32
- name string
33
- store map [string ]map [string ]* KeyValue
34
- rwMux sync.RWMutex
35
- dirty bool
37
+ Cfg * Options
38
+ name string
39
+ store map [string ]map [string ]* KeyValue
40
+ rwMux sync.RWMutex
41
+ dirty bool
42
+ count map [string ]int // the number of leaf node
43
+ keyLayers int // the number of layers of leaf nodes
36
44
}
37
45
38
46
func (c * KvCache ) Name () string {
@@ -63,6 +71,12 @@ func (c *KvCache) GetAll(arr *[]*KeyValue) (count int) {
63
71
return
64
72
}
65
73
74
+ func (c * KvCache ) getCacheDomainProjectKey (key string ) string {
75
+ regexp , _ := regexp2 .Compile (`/(\w)+-(\w)+/(\w)+/(\w)+/(\w)+/(\w)+/` )
76
+ domainProjectKey := regexp .FindString (key )
77
+ return domainProjectKey
78
+ }
79
+
66
80
func (c * KvCache ) GetPrefix (prefix string , arr * []* KeyValue ) (count int ) {
67
81
c .rwMux .RLock ()
68
82
count = c .getPrefixKey (arr , prefix )
@@ -124,6 +138,11 @@ func (c *KvCache) getPrefixKey(arr *[]*KeyValue, prefix string) (count int) {
124
138
return 0
125
139
}
126
140
141
+ if arr == nil && strings .Count (prefix , SPLIT ) == DomainProjectLayer {
142
+ count = c .count [prefix ]
143
+ return
144
+ }
145
+
127
146
// TODO support sort option
128
147
if arr == nil {
129
148
for key := range keysRef {
@@ -156,6 +175,10 @@ func (c *KvCache) addPrefixKey(key string, val *KeyValue) {
156
175
return
157
176
}
158
177
keys , ok := c .store [prefix ]
178
+ if strings .Count (key , SPLIT ) > c .keyLayers {
179
+ c .count [c .getCacheDomainProjectKey (key )] = InitCount
180
+ c .keyLayers = strings .Count (key , SPLIT )
181
+ }
159
182
if ! ok {
160
183
// build parent index key and new child nodes
161
184
keys = make (map [string ]* KeyValue )
@@ -166,6 +189,8 @@ func (c *KvCache) addPrefixKey(key string, val *KeyValue) {
166
189
keys [key ] = val
167
190
}
168
191
return
192
+ } else if _ , ok := keys [key ]; ! ok {
193
+ c .count [c .getCacheDomainProjectKey (key )]++
169
194
}
170
195
171
196
keys [key ], key = val , prefix
@@ -178,6 +203,9 @@ func (c *KvCache) deletePrefixKey(key string) {
178
203
if ! ok {
179
204
return
180
205
}
206
+ if strings .Count (key , SPLIT ) == c .keyLayers {
207
+ c .count [c .getCacheDomainProjectKey (key )]--
208
+ }
181
209
delete (m , key )
182
210
183
211
// remove parent which has no child
@@ -189,8 +217,10 @@ func (c *KvCache) deletePrefixKey(key string) {
189
217
190
218
func NewKvCache (name string , cfg * Options ) * KvCache {
191
219
return & KvCache {
192
- Cfg : cfg ,
193
- name : name ,
194
- store : make (map [string ]map [string ]* KeyValue ),
220
+ Cfg : cfg ,
221
+ name : name ,
222
+ store : make (map [string ]map [string ]* KeyValue ),
223
+ count : make (map [string ]int ),
224
+ keyLayers : InitLayer ,
195
225
}
196
226
}
0 commit comments