/* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 ĠGoogle ĠLLC . Ċ Ġ* Ċ Ġ* ĠThis Ġcode Ġmay Ġonly Ġbe Ġused Ġunder Ġthe ĠBSD Ġstyle Ġlicense Ġfound Ġat Ċ Ġ* Ġhttp :// polymer . github . io / LICENSE . txt Ċ Ġ* Ċ Ġ* ĠCode Ġdistributed Ġby ĠGoogle Ġas Ġpart Ġof Ġthis Ġproject Ġis Ġalso Ġsubject Ġto Ġan Ġadditional ĠIP Ġrights Ċ Ġ* Ġgrant Ġfound Ġat Ċ Ġ* Ġhttp :// polymer . github . io / PAT ENTS . txt Ċ Ġ*/ Ċ Ċ package Ġar cs . android . storage . service Ċ Ċ import Ġandroidx . annotation . Visible ForTesting Ċ import Ġar cs . core . cr dt . Cr dt Data Ċ import Ġar cs . core . cr dt . Cr dt Operation Ċ import Ġar cs . core . storage . Active Store Ċ import Ġar cs . core . storage . Driver Factory Ċ import Ġar cs . core . storage . Storage Key Ċ import Ġar cs . core . storage . Store Options Ċ import Ġar cs . core . storage . Unt yped Active Store Ċ import Ġar cs . core . storage . Write Back Provider Ċ import Ġar cs . core . util . gu arded By Ċ import Ġkotlinx . atomic fu . Atomic Int Ċ import Ġkotlinx . atomic fu . atomic Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . sync . Mutex Ċ import Ġkotlinx . coroutines . sync . with Lock Ċ Ċ /** Ċ Ġ* ĠThread - safe Ġdata - structure Ġthat Ġkeeps Ġtrack Ġof Ġthe Ġactive Ġ[ Active Store ] s Ġand Ġthe Ġnumber Ġof Ċ Ġ* Ġchannels Ġreferencing Ġthem . Ċ Ġ*/ Ċ class ĠRefer enced Stores ( ĊĠ Ġ/** ĠThese Ġare Ġused Ġwhen Ġconstructing Ġ[ Active Store ] s Ġ*/ ĊĠ Ġprivate Ġval Ġscope : ĠCor outine Scope , ĊĠ Ġprivate Ġval Ġdriver Factory : ĠDriver Factory , ĊĠ Ġprivate Ġval Ġwrite Back Provider : ĠWrite Back Provider , ĊĠ Ġprivate Ġval Ġdev Tools Proxy : ĠDev Tools Proxy Impl ? Ċ ) Ġ{ ĊĊĠ Ġprivate Ġval Ġmutex Ġ= ĠMutex () ĊĠ Ġprivate Ġval Ġstores Ġby Ġgu arded By ( mutex , Ġmutable Map Of < Storage Key , ĠRefer enced Store >()) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠIn crements Ġthe Ġcount Ġof Ġa Ġ[ Referenced Store ] Ġidentified Ġby Ġ[ Storage Options . Storage Key ] Ġand ĊĠĠ Ġ* Ġreturns Ġa Ġcorresponding Ġ[ Re le as able Store ]. ĠIf Ġno Ġsuch Ġ[ Referenced Store ] Ġfor ĊĠĠ Ġ* Ġ[ Storage Options . Storage Key ] Ġexists , Ġcreate Ġone Ġby Ġcreating Ġa Ġnew Ġ[ Active Store ] Ġand Ġsetting Ġthe ĊĠĠ Ġ* Ġinitial Ġcount Ġto Ġ 0 . ĊĠĠ Ġ*/ ĊĠ Ġsuspend Ġfun Ġget Or Put ( store Options : ĠStore Options ): ĠRe le as able Store Ġ= Ġmutex . with Lock Ġ{ ĊĠĠĠ Ġval Ġreferenced Store Ġ= Ġstores . get Or Put ( store Options . storage Key ) Ġ{ ĊĠĠĠĠĠ Ġval Ġnew Store Ġ= ĠActive Store < Cr dt Data , ĠCr dt Operation , ĠAny ? >( ĊĠĠĠĠĠĠĠ Ġstore Options , ĊĠĠĠĠĠĠĠ Ġscope , ĊĠĠĠĠĠĠĠ Ġdriver Factory , ĊĠĠĠĠĠĠĠ Ġwrite Back Provider , ĊĠĠĠĠĠĠĠ Ġdev Tools Proxy ĊĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ ĠRefer enced Store ( new Store , Ġatomic ( 0 )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreferenced Store . count . increment AndGet () ĊĠĠĠ ĠRe le as able Store ( referenced Store ) ĊĠ Ġ} ĊĊĠ Ġ/** ĠRemove Ġand Ġclose Ġall Ġ[ Active Store ] s Ġin Ġthe Ġmap . Ġ*/ ĊĠ Ġsuspend Ġfun Ġclear () Ġ{ ĊĠĠĠ Ġval Ġstores Copy : ĠMap < Storage Key , ĠRefer enced Store > ĊĠĠĠ Ġmutex . with Lock Ġ{ ĊĠĠĠĠĠ Ġstores Copy Ġ= Ġstores . toMap () ĊĠĠĠĠĠ Ġstores . clear () ĊĠĠĠ Ġ} ĊĠĠĠ Ġstores Copy . forEach Ġ{ Ġ(_, Ġreferenced Store ) Ġ-> ĊĠĠĠĠĠ Ġreferenced Store . store . close () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĠReturns Ġthe Ġnumber Ġof Ġ[ Active Store ] s Ġthat Ġare Ġcurrently Ġstored . Ġ*/ ĊĠ Ġsuspend Ġfun Ġsize (): ĠInt Ġ= Ġmutex . with Lock Ġ{ Ġstores . size Ġ} ĊĊĠ Ġ/** ĠReturns Ġa Ġ[ Set ] Ġof Ġall Ġ[ Storage Key ] s Ġof Ġthe Ġstored Ġ[ Active Store ] s . Ġ*/ ĊĠ Ġsuspend Ġfun Ġstorage Keys (): ĠSet < Storage Key > Ġ= Ġmutex . with Lock Ġ{ Ġstores . keys Ġ} ĊĊĠ Ġinternal Ġdata Ġclass ĠRefer enced Store ( ĊĠĠĠ Ġval Ġstore : ĠUnt yped Active Store , ĊĠĠĠ Ġval Ġcount : ĠAtomic Int ĊĠ Ġ) ĊĊĠ Ġinner Ġclass ĠRe le as able Store Ġinternal Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġreferenced Store : ĠRefer enced Store ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġval Ġstore : ĠUnt yped Active Store Ġget () Ġ= Ġreferenced Store . store ĊĠĠĠ Ġprivate Ġvar Ġreleased Ġ= Ġfalse ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġval Ġcount : ĠInt Ġget () Ġ= Ġreferenced Store . count . value ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAtom ically Ġde crements Ġthe Ġcount Ġof Ġthe Ġ[ Referenced Store ] Ġby Ġ 1 . ĠIf Ġthe Ġcount Ġis Ġthen Ġ 0 , ĊĠĠĠĠ Ġ* Ġremove Ġitself Ġfrom Ġ[ Referenced Stores . stores ] Ġand Ġclose Ġthe Ġcorresponding Ġ[ Active Store ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġrelease () Ġ{ ĊĠĠĠĠĠ Ġcheck (! released ) Ġ{ Ġ" Re le as able Store Ġhas Ġalready Ġbeen Ġreleased ." Ġ} ĊĊĠĠĠĠĠ Ġvar Ġstore To Close : ĠUnt yped Active Store ? Ġ= Ġnull ĊĠĠĠĠĠ Ġmutex . with Lock Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcount Ġ= Ġreferenced Store . count . decrement AndGet () ĊĠĠĠĠĠĠĠ Ġcheck ( count Ġ>= Ġ 0 ) Ġ{ Ġ" Count Ġfor Ġstorage Ġkey Ġ${ store . storage Key } Ġis Ġnegative ." Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( count Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġstore To Close Ġ= Ġstores . remove ( store . storage Key )?. store ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreleased Ġ= Ġtrue ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġstore To Close ?. close () ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ