@@ -10,13 +10,15 @@ import (
1010
1111type LayeredCache struct {
1212 * Configuration
13- list * list.List
14- buckets []* layeredBucket
15- bucketMask uint32
16- size int64
17- deletables chan * Item
18- promotables chan * Item
19- donec chan struct {}
13+ list * list.List
14+ buckets []* layeredBucket
15+ bucketMask uint32
16+ size int64
17+ deletables chan * Item
18+ promotables chan * Item
19+ donec chan struct {}
20+ getDroppedReq chan struct {}
21+ getDroppedRes chan int
2022}
2123
2224// Create a new layered cache with the specified configuration.
@@ -39,6 +41,8 @@ func Layered(config *Configuration) *LayeredCache {
3941 bucketMask : uint32 (config .buckets ) - 1 ,
4042 buckets : make ([]* layeredBucket , config .buckets ),
4143 deletables : make (chan * Item , config .deleteBuffer ),
44+ getDroppedReq : make (chan struct {}),
45+ getDroppedRes : make (chan int ),
4246 }
4347 for i := 0 ; i < int (config .buckets ); i ++ {
4448 c .buckets [i ] = & layeredBucket {
@@ -162,6 +166,13 @@ func (c *LayeredCache) Stop() {
162166 <- c .donec
163167}
164168
169+ // Gets the number of items removed from the cache due to memory pressure since
170+ // the last time GetDropped was called
171+ func (c * LayeredCache ) GetDropped () int {
172+ c .getDroppedReq <- struct {}{}
173+ return <- c .getDroppedRes
174+ }
175+
165176func (c * LayeredCache ) restart () {
166177 c .promotables = make (chan * Item , c .promoteBuffer )
167178 c .donec = make (chan struct {})
@@ -189,14 +200,15 @@ func (c *LayeredCache) promote(item *Item) {
189200
190201func (c * LayeredCache ) worker () {
191202 defer close (c .donec )
203+ dropped := 0
192204 for {
193205 select {
194206 case item , ok := <- c .promotables :
195207 if ok == false {
196208 return
197209 }
198210 if c .doPromote (item ) && c .size > c .maxSize {
199- c .gc ()
211+ dropped += c .gc ()
200212 }
201213 case item := <- c .deletables :
202214 if item .element == nil {
@@ -208,6 +220,9 @@ func (c *LayeredCache) worker() {
208220 }
209221 c .list .Remove (item .element )
210222 }
223+ case _ = <- c .getDroppedReq :
224+ c .getDroppedRes <- dropped
225+ dropped = 0
211226 }
212227 }
213228}
@@ -229,11 +244,12 @@ func (c *LayeredCache) doPromote(item *Item) bool {
229244 return true
230245}
231246
232- func (c * LayeredCache ) gc () {
247+ func (c * LayeredCache ) gc () int {
233248 element := c .list .Back ()
249+ dropped := 0
234250 for i := 0 ; i < c .itemsToPrune ; i ++ {
235251 if element == nil {
236- return
252+ return dropped
237253 }
238254 prev := element .Prev ()
239255 item := element .Value .(* Item )
@@ -242,7 +258,9 @@ func (c *LayeredCache) gc() {
242258 c .size -= item .size
243259 c .list .Remove (element )
244260 item .promotions = - 2
261+ dropped += 1
245262 }
246263 element = prev
247264 }
265+ return dropped
248266}
0 commit comments