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 {
445445 c .items .mu .RLock ()
446446 defer c .items .mu .RUnlock ()
447447
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+ }
452482 }
483+ return res
453484 }
454485
455- return size
486+ return total - countExpired ()
456487}
457488
458489// 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) {
803803}
804804
805805func 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+ }
808819 assert .Equal (t , 2 , cache .Len ())
809820}
810821
You can’t perform that action at this time.
0 commit comments