@@ -40,15 +40,14 @@ var (
40
40
type VectorChunkManager struct {
41
41
cacheStorage ChunkManager
42
42
vectorStorage ChunkManager
43
- cache * cache.LRU [string , * mmap.ReaderAt ]
43
+ cache cache.LoadingCache [string , * mmap.ReaderAt ]
44
44
45
45
insertCodec * InsertCodec
46
46
47
47
cacheEnable bool
48
48
cacheLimit int64
49
49
cacheSize int64
50
50
cacheSizeMutex sync.Mutex
51
- fixSize bool // Prevent cache capactiy from changing too frequently
52
51
}
53
52
54
53
var _ ChunkManager = (* VectorChunkManager )(nil )
@@ -64,31 +63,50 @@ func NewVectorChunkManager(ctx context.Context, cacheStorage ChunkManager, vecto
64
63
cacheEnable : cacheEnable ,
65
64
cacheLimit : cacheLimit ,
66
65
}
67
- if cacheEnable {
68
- if cacheLimit <= 0 {
69
- return nil , errors .New ("cache limit must be positive if cacheEnable" )
66
+
67
+ err := vcm .initCache (ctx )
68
+ if err != nil {
69
+ return nil , err
70
+ }
71
+
72
+ return vcm , nil
73
+ }
74
+
75
+ func (vcm * VectorChunkManager ) initCache (ctx context.Context ) error {
76
+ if ! vcm .cacheEnable {
77
+ return nil
78
+ }
79
+
80
+ if vcm .cacheLimit <= 0 {
81
+ return errors .New ("cache limit must be positive if cacheEnable" )
82
+ }
83
+
84
+ loader := func (filePath string ) (* mmap.ReaderAt , error ) {
85
+ return vcm .readFile (ctx , filePath )
86
+ }
87
+
88
+ onRemoveFn := func (filePath string , v * mmap.ReaderAt ) {
89
+ size := v .Len ()
90
+ err := v .Close ()
91
+ if err != nil {
92
+ log .Error ("close mmap file failed" , zap .Any ("file" , filePath ))
70
93
}
71
- c , err := cache .NewLRU (defaultLocalCacheSize , func (k string , v * mmap.ReaderAt ) {
72
- size := v .Len ()
73
- err := v .Close ()
74
- if err != nil {
75
- log .Error ("Unmmap file failed" , zap .Any ("file" , k ))
76
- }
77
- err = cacheStorage .Remove (ctx , k )
78
- if err != nil {
79
- log .Error ("cache storage remove file failed" , zap .Any ("file" , k ))
80
- }
81
- vcm .cacheSizeMutex .Lock ()
82
- vcm .cacheSize -= int64 (size )
83
- vcm .cacheSizeMutex .Unlock ()
84
- })
94
+ err = vcm .cacheStorage .Remove (ctx , filePath )
85
95
if err != nil {
86
- return nil , err
96
+ log . Error ( "cache storage remove file failed" , zap . Any ( "file" , filePath ))
87
97
}
88
- vcm .cache = c
98
+
99
+ vcm .cacheSizeMutex .Lock ()
100
+ vcm .cacheSize -= int64 (size )
101
+ vcm .cacheSizeMutex .Unlock ()
89
102
}
90
103
91
- return vcm , nil
104
+ vcm .cache = cache .NewLoadingCache (loader ,
105
+ cache.WithRemovalListener [string , * mmap.ReaderAt ](onRemoveFn ),
106
+ cache.WithMaximumSize [string , * mmap.ReaderAt ](vcm .cacheLimit ),
107
+ )
108
+
109
+ return nil
92
110
}
93
111
94
112
// For vector data, we will download vector file from storage. And we will
@@ -146,7 +164,7 @@ func (vcm *VectorChunkManager) Exist(ctx context.Context, filePath string) (bool
146
164
return vcm .vectorStorage .Exist (ctx , filePath )
147
165
}
148
166
149
- func (vcm * VectorChunkManager ) readWithCache (ctx context.Context , filePath string ) ([] byte , error ) {
167
+ func (vcm * VectorChunkManager ) readFile (ctx context.Context , filePath string ) (* mmap. ReaderAt , error ) {
150
168
contents , err := vcm .vectorStorage .Read (ctx , filePath )
151
169
if err != nil {
152
170
return nil , err
@@ -159,45 +177,31 @@ func (vcm *VectorChunkManager) readWithCache(ctx context.Context, filePath strin
159
177
if err != nil {
160
178
return nil , err
161
179
}
180
+
162
181
r , err := vcm .cacheStorage .Mmap (ctx , filePath )
163
182
if err != nil {
164
183
return nil , err
165
184
}
166
- size , err := vcm .cacheStorage .Size (ctx , filePath )
167
- if err != nil {
168
- return nil , err
169
- }
170
185
vcm .cacheSizeMutex .Lock ()
171
- vcm .cacheSize += size
186
+ vcm .cacheSize += int64 ( r . Len ())
172
187
vcm .cacheSizeMutex .Unlock ()
173
- if ! vcm .fixSize {
174
- if vcm .cacheSize < vcm .cacheLimit {
175
- if vcm .cache .Len () == vcm .cache .Capacity () {
176
- newSize := float32 (vcm .cache .Capacity ()) * 1.25
177
- vcm .cache .Resize (int (newSize ))
178
- }
179
- } else {
180
- // +1 is for add current value
181
- vcm .cache .Resize (vcm .cache .Len () + 1 )
182
- vcm .fixSize = true
183
- }
184
- }
185
- vcm .cache .Add (filePath , r )
186
- return results , nil
188
+ return r , nil
187
189
}
188
190
189
191
// Read reads the pure vector data. If cached, it reads from local.
190
192
func (vcm * VectorChunkManager ) Read (ctx context.Context , filePath string ) ([]byte , error ) {
191
193
if vcm .cacheEnable {
192
- if r , ok := vcm .cache .Get (filePath ); ok {
193
- p := make ([]byte , r .Len ())
194
- _ , err := r .ReadAt (p , 0 )
195
- if err != nil {
196
- return p , err
197
- }
198
- return p , nil
194
+ r , err := vcm .cache .Get (filePath )
195
+ if err != nil {
196
+ return nil , err
199
197
}
200
- return vcm .readWithCache (ctx , filePath )
198
+
199
+ p := make ([]byte , r .Len ())
200
+ _ , err = r .ReadAt (p , 0 )
201
+ if err != nil {
202
+ return nil , err
203
+ }
204
+ return p , nil
201
205
}
202
206
contents , err := vcm .vectorStorage .Read (ctx , filePath )
203
207
if err != nil {
@@ -238,7 +242,7 @@ func (vcm *VectorChunkManager) ListWithPrefix(ctx context.Context, prefix string
238
242
239
243
func (vcm * VectorChunkManager ) Mmap (ctx context.Context , filePath string ) (* mmap.ReaderAt , error ) {
240
244
if vcm .cacheEnable && vcm .cache != nil {
241
- if r , ok := vcm .cache .Get (filePath ); ok {
245
+ if r , err := vcm .cache .Get (filePath ); err == nil {
242
246
return r , nil
243
247
}
244
248
}
@@ -252,19 +256,17 @@ func (vcm *VectorChunkManager) Reader(ctx context.Context, filePath string) (Fil
252
256
// ReadAt reads specific position data of vector. If cached, it reads from local.
253
257
func (vcm * VectorChunkManager ) ReadAt (ctx context.Context , filePath string , off int64 , length int64 ) ([]byte , error ) {
254
258
if vcm .cacheEnable {
255
- if r , ok := vcm .cache .Get (filePath ); ok {
256
- p := make ([]byte , length )
257
- _ , err := r .ReadAt (p , off )
258
- if err != nil {
259
- return nil , err
260
- }
261
- return p , nil
259
+ r , err := vcm .cache .Get (filePath )
260
+ if err != nil {
261
+ return nil , err
262
262
}
263
- results , err := vcm .readWithCache (ctx , filePath )
263
+
264
+ p := make ([]byte , length )
265
+ _ , err = r .ReadAt (p , off )
264
266
if err != nil {
265
267
return nil , err
266
268
}
267
- return results [ off : off + length ] , nil
269
+ return p , nil
268
270
}
269
271
contents , err := vcm .vectorStorage .Read (ctx , filePath )
270
272
if err != nil {
@@ -292,7 +294,7 @@ func (vcm *VectorChunkManager) Remove(ctx context.Context, filePath string) erro
292
294
return err
293
295
}
294
296
if vcm .cacheEnable {
295
- vcm .cache .Remove (filePath )
297
+ vcm .cache .Invalidate (filePath )
296
298
}
297
299
return nil
298
300
}
@@ -304,7 +306,7 @@ func (vcm *VectorChunkManager) MultiRemove(ctx context.Context, filePaths []stri
304
306
}
305
307
if vcm .cacheEnable {
306
308
for _ , p := range filePaths {
307
- vcm .cache .Remove (p )
309
+ vcm .cache .Invalidate (p )
308
310
}
309
311
}
310
312
return nil
@@ -321,7 +323,7 @@ func (vcm *VectorChunkManager) RemoveWithPrefix(ctx context.Context, prefix stri
321
323
return err
322
324
}
323
325
for _ , p := range filePaths {
324
- vcm .cache .Remove (p )
326
+ vcm .cache .Invalidate (p )
325
327
}
326
328
}
327
329
return nil
0 commit comments