package Ġcom . scri bd . arm ad illo . download Ċ Ċ import Ġandroidx . annotation . Visible ForTesting Ċ import Ġcom . google . android . ex op layer 2 . C Ċ import Ġcom . google . android . ex op layer 2 . upstream . cache . Cache Ċ import Ġcom . google . android . ex op layer 2 . upstream . cache . Cache Ev ictor Ċ import Ġcom . google . android . ex op layer 2 . upstream . cache . Cache Span Ċ import Ġjava . util . Deque Ċ import Ġjava . util . LinkedList Ċ Ċ /** Ċ Ġ* ĠThis Ġcache Ġev ictor Ġwill : Ċ Ġ* Ġ Ġ- Ġprefer entially Ġremove Ġcontent Ġthat Ġis Ġolder Ġthen Ġ[ content Max Age Millis ] Ċ Ġ* Ġ Ġ- Ġthen Ġfunction Ġas Ġan Ġl ru Ġcache Ġfor Ġvalid Ġcontent Ċ Ġ* Ġ Ġ- Ġif Ġ[ Int . MAX _ VALUE ] Ġis Ġpassed Ġfor Ġ[ content Max Age Millis ], Ġthis Ġcache Ġwill Ġfunction Ġas Ġan ĠL RU Ġcache Ċ Ġ*/ Ċ internal Ġclass ĠMax Age Cache Ev ictor ( ĊĠĠĠ Ġprivate Ġval Ġmax Bytes : ĠLong , ĊĠĠĠ Ġprivate Ġval Ġcontent Max Age Millis : ĠInt Ġ= ĠCONTENT _ MAX _ AGE _ M ILL IS , ĊĠĠĠ Ġprivate Ġval Ġclock : ĠClock Ġ= Ġobject Ġ: ĠClock Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠcurrentTime Millis (): ĠLong Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠ Ġ}, Ċ ) Ġ: ĠCache Ev ictor Ġ{ ĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġinterface ĠClock Ġ{ ĊĠĠĠĠĠĠĠ Ġfun ĠcurrentTime Millis (): ĠLong ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġdata Ġclass ĠCache Span Expiration ( val Ġkey : ĠInt , Ġval Ġexpiration : ĠLong ) ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġval Ġcontent Ġ= Ġmutable Map Of < Int , ĠCache Span >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠTrack s Ġhow Ġlong Ġa Ġspan Ġhas Ġbeen Ġcached Ġfor . ĠOnly Ġbe Ġmodified Ġwhen Ġa Ġspan Ġis Ġadded Ġor Ġremoved . ĠAn ĊĠĠĠĠ Ġ* Ġupdate Ġdoes Ġnot Ġtrigger Ġchanges . ĠThe ĠOS Ġoften Ġmoves Ġaround Ġ[ Cache Span ] s Ġinternally Ġto Ġoptimize Ġstorage , Ġthese ĊĠĠĠĠ Ġ* Ġupdates Ġdo Ġnot Ġcorrespond Ġto Ġref res hes Ġwith Ġthe Ġnetwork Ġand Ġtherefore Ġdo Ġnot Ġmodify Ġthe Ġexpiration Ġtimes . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġval Ġexp ir ations : ĠDe que < Cache Span Expiration > Ġ= ĠLinkedList () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHandles Ġl ru Ġordering . ĊĠĠĠĠ Ġ* ĠNew Ġelements Ġare Ġen queued Ġto Ġhead Ġand Ġold Ġare Ġde queued Ġfrom Ġtail ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġval Ġl ru Arr : ĠDe que < Int > Ġ= ĠLinkedList () ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġvar Ġcurrent Size : ĠLong Ġ= Ġ 0 ĊĊĠĠĠ Ġprivate Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠCONTENT _ MAX _ AGE _ M ILL IS Ġ= Ġ 1 0 0 0 Ġ* Ġ 6 0 Ġ* Ġ 6 0 Ġ* Ġ 1 2 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġrequires Cache Span Tou ches () Ġ= Ġtrue ĊĊĠĠĠ Ġoverride Ġfun Ġon Cache Initialized () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠDo Ġnothing . ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonStart File ( cache : ĠCache , Ġkey : ĠString , Ġposition : ĠLong , Ġlength : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( length Ġ!= ĠC . LENGTH _ UN SET . to Long ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġev ict Cache ( cache , Ġlength ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Span Added ( cache : ĠCache , Ġspan : ĠCache Span ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġspan . key () ĊĠĠĠĠĠĠĠ Ġif Ġ(! content . containsKey ( key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexp ir ations . add First ( Cache Span Expiration ( key , Ġexpiration Timestamp ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Size Ġ+= Ġspan . length ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġl ru Arr . remove ( key ) ĊĠĠĠĠĠĠĠ Ġl ru Arr . add First ( key ) ĊĠĠĠĠĠĠĠ Ġcontent [ key ] Ġ= Ġspan ĊĠĠĠĠĠĠĠ Ġev ict Cache ( cache , Ġ 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġis Ġtriggered Ġby Ġcalls Ġin Ġ[ ev ict Cache ] Ġto Ġ[ Cache . remove Span ] ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIt Ġis Ġexpected Ġthat Ġthis Ġmethod Ġwill Ġreturn Ġbecause Ġall Ġthe Ġwork Ġis Ġalready Ġdone Ġin Ġ[ ev ict Cache ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġon Span Removed ( cache : ĠCache , Ġspan : ĠCache Span ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġspan . key () ĊĠĠĠĠĠĠĠ Ġcontent [ key ] Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġcontent . remove ( key ) ĊĠĠĠĠĠĠĠ Ġl ru Arr . remove ( key ) ĊĠĠĠĠĠĠĠ Ġremove Expired Content ( key ) ĊĠĠĠĠĠĠĠ Ġcurrent Size Ġ-= Ġspan . length ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Span Tou ched ( cache : ĠCache , Ġold Span : ĠCache Span , Ġnew Span : ĠCache Span ) Ġ{ ĊĠĠĠĠĠĠĠ Ġon Span Added ( cache , Ġnew Span ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġev ict Cache ( cache : ĠCache , Ġrequired Space : ĠLong ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// Ġremove Ġexpired Ġcontent ĊĠĠĠĠĠĠĠ Ġwhile Ġ( exp ir ations . peek Last ()?. is Expired () Ġ== Ġtrue ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpired Wrapper Ġ= Ġexp ir ations . poll Last () Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġexpired Wrapper . key ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpired Span Ġ= Ġcontent [ key ] Ġ?: Ġcontinue ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġl ru Arr . remove ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontent . remove ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Size Ġ-= Ġexpired Span . length ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠT riggers Ġ[ on Span Removed ] ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcache . remove Span ( expired Span ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠL RU Ġbehavior ĊĠĠĠĠĠĠĠ Ġwhile Ġ( current Size Ġ+ Ġrequired Space Ġ> Ġmax Bytes Ġ&& Ġl ru Arr . peek Last () Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġl ru Arr . poll Last () Ġ?: Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcache Span Ġ= Ġcontent [ key ] Ġ?: Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Size Ġ-= Ġcache Span . length ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠT riggers Ġ[ on Span Removed ] ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcache . remove Span ( cache Span ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġremove Expired Content ( key : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġiterator Ġ= Ġexp ir ations . iterator () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( iterator . hasNext ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Ġ= Ġiterator . next () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current . key Ġ== Ġkey ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexp ir ations . remove ( current ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠCache Span Expiration . is Expired () Ġ= Ġclock . currentTimeMillis () Ġ> Ġexpiration ĊĠĠĠ Ġprivate Ġfun Ġexpiration Timestamp () Ġ= Ġclock . currentTimeMillis () Ġ+ Ġcontent Max Age Millis Ċ } Ċ Ċ @ Visible ForTesting Ċ internal Ġfun ĠCache Span . key (): ĠInt Ġ= Ġthis . toString (). hashCode () Ċ