File tree Expand file tree Collapse file tree 2 files changed +49
-7
lines changed Expand file tree Collapse file tree 2 files changed +49
-7
lines changed Original file line number Diff line number Diff line change @@ -445,14 +445,45 @@ func (c *Cache[K, V]) Len() int {
445
445
c .items .mu .RLock ()
446
446
defer c .items .mu .RUnlock ()
447
447
448
- size := 0
449
- for _ , elem := range c .items .values {
450
- if ! elem .Value .(* Item [K , V ]).isExpiredUnsafe () {
451
- size ++
448
+ total := c .items .expQueue .Len ()
449
+ if total == 0 {
450
+ return 0
451
+ }
452
+
453
+ // search the heap-based expQueue by BFS
454
+ countExpired := func () int {
455
+ var (
456
+ q []int
457
+ res int
458
+ )
459
+
460
+ item := c .items .expQueue [0 ].Value .(* Item [K , V ])
461
+ if ! item .isExpiredUnsafe () {
462
+ return res
463
+ }
464
+
465
+ q = append (q , 0 )
466
+ for len (q ) > 0 {
467
+ pop := q [0 ]
468
+ q = q [1 :]
469
+ res ++
470
+
471
+ for i := 1 ; i <= 2 ; i ++ {
472
+ idx := 2 * pop + i
473
+ if idx >= total {
474
+ break
475
+ }
476
+
477
+ item = c .items .expQueue [idx ].Value .(* Item [K , V ])
478
+ if item .isExpiredUnsafe () {
479
+ q = append (q , idx )
480
+ }
481
+ }
452
482
}
483
+ return res
453
484
}
454
485
455
- return size
486
+ return total - countExpired ()
456
487
}
457
488
458
489
// Keys returns all unexpired keys in the cache.
Original file line number Diff line number Diff line change @@ -803,8 +803,19 @@ func Test_Cache_Touch(t *testing.T) {
803
803
}
804
804
805
805
func Test_Cache_Len (t * testing.T ) {
806
- cache := prepCache (time .Hour , "1" , "2" )
807
- addToCache (cache , time .Nanosecond , "3" )
806
+ cache := prepCache (time .Hour )
807
+ assert .Equal (t , 0 , cache .Len ())
808
+
809
+ addToCache (cache , time .Hour , "1" )
810
+ assert .Equal (t , 1 , cache .Len ())
811
+
812
+ addToCache (cache , time .Nanosecond , "2" )
813
+ assert .Equal (t , 1 , cache .Len ())
814
+
815
+ addToCache (cache , time .Hour , "3" )
816
+ for i := 4 ; i < 30 ; i ++ {
817
+ addToCache (cache , time .Nanosecond , fmt .Sprint (i ))
818
+ }
808
819
assert .Equal (t , 2 , cache .Len ())
809
820
}
810
821
You can’t perform that action at this time.
0 commit comments