/* Ċ Ġ* ĠTencent Ġis Ġplease d Ġto Ġsupport Ġthe Ġopen Ġsource Ġcommunity Ġby Ġmaking ĠB K - CI Ġ èĵĿ é² ¸ æĮģ ç»Ń éĽĨ æĪĲ å¹³åı° Ġavailable . Ċ Ġ* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 0 ĠTH L ĠA 2 9 ĠLimited , Ġa ĠTencent Ġcompany . Ġ ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* ĠB K - CI Ġ èĵĿ é² ¸ æĮģ ç»Ń éĽĨ æĪĲ å¹³åı° Ġis Ġlicensed Ġunder Ġthe ĠMIT Ġlicense . Ċ Ġ* Ċ Ġ* ĠA Ġcopy Ġof Ġthe ĠMIT ĠLicense Ġis Ġincluded Ġin Ġthis Ġfile . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠTerms Ġof Ġthe ĠMIT ĠLicense : Ċ Ġ* Ġ------------------------------------------------ --- Ċ Ġ* ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ċ Ġ* Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ċ Ġ* Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ġrights Ċ Ġ* Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ċ Ġ* Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ċ Ġ* Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ġall Ċ Ġ* Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ċ Ġ* ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ċ Ġ* ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ Ġ* ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ċ Ġ* ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , Ċ Ġ* ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN ĠTHE Ċ Ġ* ĠSOFTWARE . Ċ Ġ*/ Ċ Ċ package Ġcom . tencent . bk repo . common . storage . core . cache Ċ Ċ import Ġcom . tencent . bk repo . common . api . constant . String Pool Ċ import Ġcom . tencent . bk repo . common . artifact . hash . sha 2 5 6 Ċ import Ġcom . tencent . bk repo . common . artifact . stream . Range Ċ import Ġcom . tencent . bk repo . common . artifact . stream . artifact Stream Ċ import Ġorg . junit . jupiter . api . After Each Ċ import Ġorg . junit . jupiter . api . Assertions Ċ import Ġorg . junit . jupiter . api . Test Ċ import Ġorg . junit . jupiter . api . assert Throws Ċ import Ġjava . io . ByteArray OutputStream Ċ import Ġjava . io . IOException Ċ import Ġjava . io . InputStream Ċ import Ġjava . nio . charset . Charset Ċ import Ġjava . nio . file . Files Ċ import Ġjava . nio . file . Paths Ċ import Ġjava . util . concurrent . Cyc lic Barrier Ċ import Ġkotlin . concurrent . thread Ċ import Ġkotlin . system . measure Time Millis Ċ Ċ internal Ġclass ĠCached FileWriter Test Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġcache Path Ġ= ĠPaths . get ( System . getProperty (" java . io . tmpdir "), Ġ" cache ") ĊĠĠĠ Ġprivate Ġval Ġtemp Path Ġ= ĠPaths . get ( System . getProperty (" java . io . tmpdir "), Ġ" temp ") ĊĠĠĠ Ġprivate Ġval Ġfilename Ġ= Ġ" test " ĊĊĠĠĠ Ġ@ After Each ĊĠĠĠ Ġfun ĠafterEach () Ġ{ ĊĠĠĠĠĠĠĠ ĠFiles . delete IfExists ( cache Path . resolve ( filename )) ĊĠĠĠĠĠĠĠ ĠFiles . delete IfExists ( temp Path . resolve ( filename )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` test Ġread Ġconcurrent ly `() Ġ{ ĊĠĠĠĠĠĠĠ ĠAssertions . assertFalse Ġ{ Ġcache Path . resolve ( filename ). to File (). exists () Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġsize Ġ= Ġ 1 0 2 4 Ġ* Ġ 1 0 2 4 Ġ* Ġ 1 L ĊĠĠĠĠĠĠĠ Ġval Ġrandom String Ġ= ĠString Pool . random String ( size . toInt ()) ĊĠĠĠĠĠĠĠ Ġval Ġexpected Sha 2 5 6 Ġ= Ġrandom String . sha 2 5 6 () ĊĠĠĠĠĠĠĠ Ġval Ġcount Ġ= Ġ 1 0 ĊĠĠĠĠĠĠĠ Ġval Ġcy clic Barrier Ġ= ĠC yc lic Barrier ( count ) ĊĠĠĠĠĠĠĠ Ġval Ġthread List Ġ= Ġmutable ListOf < Thread >() ĊĠĠĠĠĠĠĠ Ġmeasure Time Millis Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrepeat ( count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġthread Ġ= Ġthread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcy clic Barrier . await () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠinputStream Ġ= Ġrandom String . byte InputStream (). artifact Stream ( Range . full ( size )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġout Ġ= ĠByteArrayOutputStream () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlistener Ġ= ĠCached FileWriter ( cache Path , Ġfilename , Ġtemp Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinputStream . addListener ( listener ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinputStream . use Ġ{ Ġit . copy To ( out ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠtoString Ġ= Ġout . toString ( Charset . default Charset (). name ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAssertions . assertEquals ( expected Sha 2 5 6 , ĠtoString . sha 2 5 6 ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthread List . add ( thread ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthread List . forEach Ġ{ Ġit . join () Ġ} ĊĠĠĠĠĠĠĠ Ġ}. apply Ġ{ Ġprintln (" duration : Ġ$ this Ġms ") Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġsha 2 5 6 Ġ= Ġcache Path . resolve ( filename ). to File (). sha 2 5 6 () ĊĠĠĠĠĠĠĠ ĠAssertions . assertEquals ( expected Sha 2 5 6 , Ġsha 2 5 6 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` test Ġclose Ġwhen Ġtrans f erring Ġpart Ġof Ġcontent `() Ġ{ ĊĠĠĠĠĠĠĠ ĠAssertions . assertFalse Ġ{ ĠFiles . exists ( cache Path . resolve ( filename )) Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġsize Ġ= Ġ 1 0 2 4 Ġ* Ġ 1 0 2 4 Ġ* Ġ 1 L ĊĠĠĠĠĠĠĠ Ġval Ġrandom String Ġ= ĠString Pool . random String ( size . toInt ()) ĊĠĠĠĠĠĠĠ Ġval ĠinputStream Ġ= Ġrandom String . byte InputStream (). artifact Stream ( Range . full ( size )) ĊĠĠĠĠĠĠĠ Ġval Ġlistener Ġ= ĠCached FileWriter ( cache Path , Ġfilename , Ġtemp Path ) ĊĠĠĠĠĠĠĠ ĠinputStream . addListener ( listener ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Exception When IO Copy ( inputStream , Ġsize ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ignored : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġshould Ġnot Ġexist ĊĠĠĠĠĠĠĠ ĠAssertions . assertFalse Ġ{ ĠFiles . exists ( cache Path . resolve ( filename )) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` test Ġpart Ġrange `() Ġ{ ĊĠĠĠĠĠĠĠ ĠAssertions . assertFalse Ġ{ ĠFiles . exists ( cache Path . resolve ( filename )) Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġsize Ġ= Ġ 1 0 2 4 Ġ* Ġ 1 0 2 4 Ġ* Ġ 1 L ĊĠĠĠĠĠĠĠ Ġval Ġrandom String Ġ= ĠString Pool . random String ( size . toInt ()) ĊĠĠĠĠĠĠĠ Ġval Ġrange Ġ= ĠRange ( 0 , Ġsize Ġ/ Ġ 2 , Ġsize ) ĊĠĠĠĠĠĠĠ Ġval ĠinputStream Ġ= Ġrandom String . byte InputStream (). artifact Stream ( range ) ĊĠĠĠĠĠĠĠ Ġval Ġlistener Ġ= ĠCached FileWriter ( cache Path , Ġfilename , Ġtemp Path ) ĊĠĠĠĠĠĠĠ ĠassertThrows < IllegalArgumentException > Ġ{ ĠinputStream . addListener ( listener ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest () Ġ{ ĊĠĠĠĠĠĠĠ ĠAssertions . assertFalse Ġ{ ĠFiles . exists ( cache Path . resolve ( filename )) Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġsize Ġ= Ġ 1 0 2 4 Ġ* Ġ 1 0 2 4 Ġ* Ġ 1 L ĊĠĠĠĠĠĠĠ Ġval Ġrandom String Ġ= ĠString Pool . random String ( size . toInt ()) ĊĠĠĠĠĠĠĠ Ġval Ġexpected Sha 2 5 6 Ġ= Ġrandom String . sha 2 5 6 () ĊĠĠĠĠĠĠĠ Ġval ĠinputStream Ġ= Ġrandom String . byte InputStream (). artifact Stream ( Range . full ( size )) ĊĠĠĠĠĠĠĠ Ġval Ġout Ġ= ĠByteArrayOutputStream () ĊĠĠĠĠĠĠĠ Ġval Ġlistener Ġ= ĠCached FileWriter ( cache Path , Ġfilename , Ġtemp Path ) ĊĠĠĠĠĠĠĠ ĠinputStream . addListener ( listener ) ĊĠĠĠĠĠĠĠ ĠinputStream . use Ġ{ Ġit . copy To ( out ) Ġ} ĊĠĠĠĠĠĠĠ Ġval ĠtoString Ġ= Ġout . toString ( Charset . default Charset (). name ()) ĊĠĠĠĠĠĠĠ ĠAssertions . assertEquals ( expected Sha 2 5 6 , ĠtoString . sha 2 5 6 ()) ĊĠĠĠĠĠĠĠ Ġ// Ġshould Ġexist ĊĠĠĠĠĠĠĠ Ġval Ġcache File Ġ= Ġcache Path . resolve ( filename ). to File () ĊĠĠĠĠĠĠĠ ĠAssertions . assertTrue Ġ{ Ġcache File . exists () Ġ} ĊĠĠĠĠĠĠĠ ĠAssertions . assertEquals ( expected Sha 2 5 6 , Ġcache File . read Text (). sha 2 5 6 ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġthrow Exception When IO Copy ( inputStream : ĠInputStream , Ġsize : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġout Ġ= ĠByteArrayOutputStream () ĊĠĠĠĠĠĠĠ ĠinputStream . use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġbytes Copied : ĠLong Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArray ( 1 0 2 4 Ġ* Ġ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġbytes Ġ= Ġit . read ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( bytes Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . write ( buffer , Ġ 0 , Ġbytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbytes Copied Ġ+= Ġbytes ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbytes Ġ= Ġit . read ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( bytes Copied Ġ> Ġsize Ġ/ Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ