|
1 | 1 | // Package fastcache implements fast in-memory cache. |
2 | 2 | // |
3 | 3 | // The package has been extracted from https://victoriametrics.com/ |
4 | | -package fastcache |
| 4 | +package turbocache |
5 | 5 |
|
6 | 6 | import ( |
7 | 7 | "fmt" |
@@ -254,35 +254,44 @@ func (b *bucket) Init(maxBytes uint64) { |
254 | 254 | b.m = make(map[uint64]uint64) |
255 | 255 | b.Reset() |
256 | 256 | b.setBuf = make(chan *insertValue, setBufSize) |
257 | | - go func() { |
258 | | - t := time.Tick(maxDelayMillis * time.Millisecond) |
259 | | - var firstTimeTimestamp int64 |
260 | | - keys := make([][]byte, 0, 64) |
261 | | - values := make([][]byte, 0, 64) |
262 | | - for { |
263 | | - select { |
264 | | - case i := <-b.setBuf: |
265 | | - if firstTimeTimestamp == 0 { |
266 | | - firstTimeTimestamp = time.Now().UnixMilli() |
267 | | - } |
268 | | - keys = append(keys, i.K) |
269 | | - values = append(values, i.V) |
270 | | - if len(keys) >= writeSizeThreshold || time.Since(time.UnixMilli(firstTimeTimestamp)).Milliseconds() >= maxDelayMillis { |
271 | | - b.setBatch(keys, values) |
272 | | - firstTimeTimestamp = 0 |
273 | | - keys = make([][]byte, 0, 64) |
274 | | - values = make([][]byte, 0, 64) |
275 | | - } |
276 | | - case _ = <-t: |
277 | | - if firstTimeTimestamp != 0 && (len(keys) >= writeSizeThreshold || time.Since(time.UnixMilli(firstTimeTimestamp)).Milliseconds() >= maxDelayMillis) { |
278 | | - b.setBatch(keys, values) |
279 | | - firstTimeTimestamp = 0 |
280 | | - keys = make([][]byte, 0, 64) |
281 | | - values = make([][]byte, 0, 64) |
| 257 | + go b.processWriteQueue() |
| 258 | +} |
| 259 | + |
| 260 | +func (b *bucket) processWriteQueue() { |
| 261 | + t := time.Tick(maxDelayMillis * time.Millisecond) |
| 262 | + var firstTimeTimestamp int64 |
| 263 | + keys := make([][]byte, 0, 64) |
| 264 | + values := make([][]byte, 0, 64) |
| 265 | + waitGroups := make([]*sync.WaitGroup, 0, 64) |
| 266 | + for { |
| 267 | + select { |
| 268 | + case i := <-b.setBuf: |
| 269 | + if firstTimeTimestamp == 0 { |
| 270 | + firstTimeTimestamp = time.Now().UnixMilli() |
| 271 | + } |
| 272 | + keys = append(keys, i.K) |
| 273 | + values = append(values, i.V) |
| 274 | + waitGroups = append(waitGroups, i.waitGroup) |
| 275 | + if len(keys) >= writeSizeThreshold || time.Since(time.UnixMilli(firstTimeTimestamp)).Milliseconds() >= maxDelayMillis { |
| 276 | + b.setBatch(keys, values) |
| 277 | + firstTimeTimestamp = 0 |
| 278 | + keys = make([][]byte, 0, 64) |
| 279 | + values = make([][]byte, 0, 64) |
| 280 | + waitGroups = make([]*sync.WaitGroup, 0, 64) |
| 281 | + } |
| 282 | + case _ = <-t: |
| 283 | + if firstTimeTimestamp != 0 && (len(keys) >= writeSizeThreshold || time.Since(time.UnixMilli(firstTimeTimestamp)).Milliseconds() >= maxDelayMillis) { |
| 284 | + b.setBatch(keys, values) |
| 285 | + for _, group := range waitGroups { |
| 286 | + group.Done() |
282 | 287 | } |
| 288 | + firstTimeTimestamp = 0 |
| 289 | + keys = make([][]byte, 0, 64) |
| 290 | + values = make([][]byte, 0, 64) |
| 291 | + waitGroups = make([]*sync.WaitGroup, 0, 64) |
283 | 292 | } |
284 | 293 | } |
285 | | - }() |
| 294 | + } |
286 | 295 | } |
287 | 296 |
|
288 | 297 | func (b *bucket) Reset() { |
@@ -394,9 +403,12 @@ func (b *bucket) set(k, v []byte, h uint64) { |
394 | 403 | } |
395 | 404 |
|
396 | 405 | func (b *bucket) Set(k, v []byte, h uint64) { |
| 406 | + var wg sync.WaitGroup |
| 407 | + wg.Add(1) |
397 | 408 | b.setBuf <- &insertValue{ |
398 | | - K: k, |
399 | | - V: v, |
| 409 | + K: k, |
| 410 | + V: v, |
| 411 | + waitGroup: &wg, |
400 | 412 | } |
401 | 413 | } |
402 | 414 |
|
@@ -467,5 +479,6 @@ func (b *bucket) Del(h uint64) { |
467 | 479 | } |
468 | 480 |
|
469 | 481 | type insertValue struct { |
470 | | - K, V []byte |
| 482 | + K, V []byte |
| 483 | + waitGroup *sync.WaitGroup |
471 | 484 | } |
0 commit comments