package Ġio . no isy fox . resources h aring . res manager . downloader Ċ Ċ import Ġio . no isy fox . lib file manager . Marked FileWriter Ċ import Ġio . no isy fox . resources h aring . res manager .* Ċ import Ġorg . iot ivity . base . Oc Resource Ċ import Ġorg . slf 4 j . Logger Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġjava . io . Closeable Ċ import Ġjava . util . concurrent . atomic . Atomic Long Ċ import Ġkotlin . math . ceil Ċ Ċ enum Ġclass ĠDown loader Status Ġ{ ĊĠĠĠ ĠStarting , ĊĠĠĠ ĠRunning , ĊĠĠĠ ĠSto pping , ĊĠĠĠ ĠSto pped , ĊĠĠĠ ĠStart After Stopped , ĊĠĠĠ ĠStop After Started Ċ } Ċ Ċ enum Ġclass ĠBasic Download Strategy Ġ{ ĊĠĠĠ ĠHttp Only , ĊĠĠĠ ĠP 2 P Only , ĊĠĠĠ ĠBal anced , ĊĠĠĠ ĠHttp Priority , ĊĠĠĠ ĠP 2 P Priority ; ĊĊĠĠĠ Ġfun Ġis Http Enabled (): ĠBoolean Ġ= Ġthis Ġ!= ĠP 2 P Only ĊĊĠĠĠ Ġfun Ġis P 2 p Enabled (): ĠBoolean Ġ= Ġthis Ġ!= ĠHttp Only Ċ } Ċ Ċ internal Ġclass ĠMain Downloader ( ĊĠĠĠĠĠĠĠ Ġinternal Ġval Ġres Context : ĠRes Context Ċ ) Ġ: ĠBlock Downloader Listener , ĠResource Find Listener , ĠClose able Ġ{ ĊĠĠĠ Ġprivate Ġval Ġservice Ġ= Ġres Context . service ĊĠĠĠ Ġprivate Ġval Ġlisteners Ġ= Ġservice . download Listeners ĊĠĠĠ Ġprivate Ġval Ġfile Ġ= Ġres Context . file ĊĊĠĠĠ Ġprivate Ġval Ġ_ download Statistics Ġ= ĠDown loader Statistics () ĊĠĠĠ Ġval Ġdownload Statistics : ĠDown loader Statistics ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ_ download Statistics . copy () ĊĊĠĠĠ Ġprivate Ġvar Ġfile Writer : ĠMark ed FileWriter ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġval Ġcomponent Ed en Ġ= Ġmutable ListOf < Downloader Component >() ĊĠĠĠ Ġprivate Ġval Ġcomponents Ġ= Ġmutable ListOf < Downloader Component >() ĊĠĠĠ Ġprivate Ġval Ġblock Distribut e Map : ĠMutable Map < Long , ĠPair < Block Downloader , ĠMutable Set < Int >>> Ġ= Ġmutable Map Of () ĊĠĠĠ Ġprivate Ġval Ġnext Downloader Id : ĠAtomic Long Ġ= ĠAtomic Long ( 0 ) ĊĊĠĠĠ Ġvar Ġcurrent Status : ĠDown loader Status Ġ= ĠDown loader Status . Stopped ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġprivate Ġvar Ġ_ download Strategy : ĠBasic Download Strategy Ġ= ĠBasic Download Strategy . Bal anced ĊĠĠĠ Ġinternal Ġvar Ġdownload Strategy : ĠBasic Download Strategy ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ_ download Strategy ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservice . assert On Working Thread () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( current Status ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopped Ġ-> Ġ_ download Strategy Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException (" Can 't Ġchange Ġduring Ġdownload !") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġstart (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . assert On Working Thread () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( current Status ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopping Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Start After Stopped ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Start After Stopped Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stop After Started Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Starting ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Running Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Starting Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopped Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( components . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Components Ġnot Ġempty ! ĠF et al Ġerror !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġw Ġ= Ġfile . try Open Writer () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIllegalStateException (" Unable Ġto Ġopen Ġwriter !") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Writer Ġ= Ġw ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Starting ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeek Speed Count Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġh atch New Downloader ( Download Monitor ( this , Ġ_ download Statistics )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( download Strategy ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBasic Download Strategy . Http Only , ĠBasic Download Strategy . Http Priority Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġd Ġ= ĠHttp Block Downloader ( next Downloader Id . get And Increment (), Ġfile . metadata . url , Ġw , Ġ_ download Statistics ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( h atch New Downloader ( d )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd . download Listeners Ġ+= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBasic Download Strategy . P 2 P Only , ĠBasic Download Strategy . P 2 P Priority Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfinder Ġ= ĠRes Finder ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġh atch New Downloader ( finder ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBasic Download Strategy . Bal anced Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġd Ġ= ĠHttp Block Downloader ( next Downloader Id . get And Increment (), Ġfile . metadata . url , Ġw , Ġ_ download Statistics ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( h atch New Downloader ( d )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd . download Listeners Ġ+= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfinder Ġ= ĠRes Finder ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġh atch New Downloader ( finder ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component Ed en . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Running ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ download Statistics . on Download Started () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre balance Blocks () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġstop (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . assert On Working Thread () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( current Status ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Starting Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Stop After Started ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopping Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopped Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Start After Stopped Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Stopping ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stop After Started Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Running Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponents . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . stop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponents . remove ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component Ed en . isEmpty () Ġ&& Ġcomponents . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Stopped ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Writer ?. safe Close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Writer Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Stopping ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġis Stopped (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . assert On Working Thread () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Status Ġ== ĠDown loader Status . Stopped ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Block Distribution (): ĠMap < String , ĠSet < Int >> Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . assert On Working Thread () ĊĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġmutable Map Of < String , ĠMutable Set < Int >>() ĊĠĠĠĠĠĠĠ Ġblock Distribut e Map . values . forEach Ġ{ Ġ( d , Ġb ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġu Ġ= Ġwhen Ġ( d ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠHttp Block Downloader Ġ-> Ġd . url ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠSh aring Block Downloader Ġ-> Ġd . resource . url ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ" Unknown " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . get Or Put ( u ) Ġ{ Ġmutable Set Of () Ġ}. addAll ( b ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠStart / stop Ġsub Ġdownload ers Ġbased Ġon Ġdownload Strategy ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinternal Ġfun Ġupdate Downloader () Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . run On Working Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( download Strategy ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBasic Download Strategy . Http Priority Ġ-> Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBasic Download Strategy . P 2 P Priority Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdo P 2 P Priority Check () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġpeek Speed Count : ĠInt Ġ= Ġ 0 ĊĊĠĠĠ Ġprivate Ġfun Ġdo P 2 P Priority Check () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠCheck Ġif Ġhttp Ġdownload Ġalready Ġstarted ĊĠĠĠĠĠĠĠ Ġval Ġhttp Download ers Ġ= Ġ( components Ġ+ Ġcomponent Ed en ). filter Is Instance < Http Block Downloader >() ĊĠĠĠĠĠĠĠ Ġif Ġ( http Download ers . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatistics Ġ= Ġdownload Statistics ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( statistics . p 2 p Download Peek Speed Ġ> Ġ 5 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeek Speed Count ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeek Speed Count Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( peek Speed Count Ġ< Ġ 5 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġpeek Speed Count Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠP 2 p Ġdownload Ġis Ġfast Ġenough , Ġshutdown Ġhttp Ġdownload ers ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhttp Download ers . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġin Ġcomponents ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . stop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Component Stopped ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatistics Ġ= Ġdownload Statistics ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( statistics . download Time Ġ< Ġ 6 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( statistics . p 2 p Download Peek Speed Ġ< Ġ 5 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeek Speed Count ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeek Speed Count Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( peek Speed Count Ġ< Ġ 5 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpeek Speed Count Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠToo Ġslow ! ĠStart Ġhttp Ġdownload ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġw Ġ= Ġfile Writer !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġd Ġ= ĠHttp Block Downloader ( next Downloader Id . get And Increment (), Ġfile . metadata . url , Ġw , Ġ_ download Statistics ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( h atch New Downloader ( d )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd . download Listeners Ġ+= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRe balance Ġblocks Ġamong Ġdownload ers ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġre balance Blocks () Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . assert On Working Thread () ĊĊĠĠĠĠĠĠĠ Ġval Ġw Ġ= Ġfile Writer !! ĊĊĠĠĠĠĠĠĠ Ġval Ġhttp Download ers Ġ= Ġcomponents . filter Is Instance < Http Block Downloader >() ĊĠĠĠĠĠĠĠ Ġval Ġsharing Download ers Ġ= Ġcomponents . filter Is Instance < Sharing Block Downloader >() ĊĊĠĠĠĠĠĠĠ Ġ// ĠRemove Ġabsent Ġfrom Ġblock Distribut e Map ĊĠĠĠĠĠĠĠ Ġval Ġall Download ers Ġ= Ġ( http Download ers Ġ+ Ġsharing Download ers ) ĊĠĠĠĠĠĠĠ Ġval Ġids Ġ= Ġall Download ers . map Ġ{ Ġit . id Ġ}. toSet () ĊĠĠĠĠĠĠĠ Ġval Ġabsent Ġ= Ġblock Distribut e Map . keys . filter Ġ{ Ġit Ġ! in Ġids Ġ} ĊĠĠĠĠĠĠĠ Ġblock Distribut e Map Ġ-= Ġabsent ĊĊĠĠĠĠĠĠĠ Ġval Ġhd Count Ġ= Ġhttp Download ers . size ĊĠĠĠĠĠĠĠ Ġval Ġsd Count Ġ= Ġsharing Download ers . size ĊĊĠĠĠĠĠĠĠ Ġval Ġtotal Ġ= Ġhd Count Ġ+ Ġsd Count ĊĠĠĠĠĠĠĠ Ġif Ġ( total Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEven ly Ġdistribute Ġfor Ġnow , ĠTODO : Ġadd Ġblock Ġre balance Ġstrategy ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremain Blocks Ġ= Ġw . writable Blocks ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsize Ġ= Ġceil ( remain Blocks . size . toFloat () Ġ/ Ġtotal . toFloat ()). toInt () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRemove Ġblocks Ġif Ġassigned Ġmore Ġthan Ġ< size > Ġblocks ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Distribut e Map . forEach Ġ{ Ġ_, Ġ( downloader , Ġblocks ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( blocks . size Ġ> Ġsize ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġextra Ġ= Ġwhen Ġ( downloader ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠHttp Block Downloader Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblocks . toList (). sorted Descending (). take ( blocks . size Ġ- Ġsize ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblocks . toList (). sorted (). take ( blocks . size Ġ- Ġsize ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toSet () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdown loader . un assign Blocks 2 ( extra ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun assigned Blocks Ġ= Ġ( remain Blocks Ġ- Ġ( block Distribut e Map . values . map Ġ{ Ġit . second Ġ}. flatten ())). sorted (). to Mutable List () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġall Download ers . map Ġ{ ĠPair ( it . get Assigned Blocks Count (), Ġit ) Ġ}. sorted By Ġ{ Ġit . first Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġ( c , Ġdown loader ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs Ġ= Ġwhen Ġ( downloader ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠHttp Block Downloader Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġun assigned Blocks . take ( size Ġ- Ġc ). toSet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġun assigned Blocks . take Last ( size Ġ- Ġc ). toSet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġun assigned Blocks . removeAll ( s ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdown loader . assign Blocks 2 ( s ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( un assigned Blocks . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠHmm mm , Ġshouldn 't Ġhappen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGive Ġall Ġto Ġthe Ġlast Ġdown loader ! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall Download ers . last (). assign Blocks 2 ( un assigned Blocks . toSet ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġres Context . block Inspector . with Block Re dest ributed ( getBlock Distribution ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠBlock Downloader . get Assigned Blocks Count (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . assert On Working Thread () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġblock Distribut e Map [ id ]?. second ?. size Ġ?: Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠBlock Downloader . un assign Blocks 2 ( blocks : ĠSet < Int >) Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . assert On Working Thread () ĊĊĠĠĠĠĠĠĠ Ġblock Distribut e Map [ id ]?. second ?. removeAll ( blocks ) ĊĠĠĠĠĠĠĠ Ġthis . un assign Blocks ( blocks ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠBlock Downloader . assign Blocks 2 ( blocks : ĠSet < Int >) Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . assert On Working Thread () ĊĊĠĠĠĠĠĠĠ Ġblock Distribut e Map . get Or Put ( id ) Ġ{ ĠPair ( this , Ġmutable Set Of ()) Ġ}. second . addAll ( blocks ) ĊĠĠĠĠĠĠĠ Ġthis . assign Blocks ( blocks ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġh atch New Downloader ( downloader : ĠDown loader Component ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . assert On Working Thread () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( current Status ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Starting Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent Ed en . add ( downloader ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( downloader . start ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent Ed en . remove ( downloader ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponents . add ( downloader ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Running Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent Ed en . add ( downloader ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( downloader . start ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Component Started ( downloader ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopping Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopped Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Start After Stopped Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stop After Started Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Component Started ( component : ĠDown loader Component ) Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . run On Working Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component Ġ! in Ġcomponent Ed en ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Downloader Ġnot Ġin ĠEd en !") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent Ed en . remove ( component ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcomponents . add ( component ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( current Status ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Starting Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component Ed en . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Running ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ download Statistics . on Download Started () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Download Started ( service , Ġfile . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre balance Blocks () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stop After Started Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component Ed en . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Running ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Download Stopped ( service , Ġfile . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Running Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre balance Blocks () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopping , ĠDown loader Status . Start After Stopped Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠO ops ! ĠGod Ġtold Ġus Ġto Ġstop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component . stop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Component Stopped ( component ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopped Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSomething Ġgoes Ġwrong ! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error (" Child Ġdown loader Ġstarted Ġafter Ġmain Ġdown loader Ġstopped ! ĠNot Ġgood !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component . stop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservice . post On Working Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Component Stopped ( component ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Component Stopped ( component : ĠDown loader Component ) Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . run On Working Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( component ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġcomponent Ed en Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn (" Child Ġdown loader Ġdi ed Ġin ĠEd en !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent Ed en . remove ( component ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġcomponents Ġ-> Ġcomponents . remove ( component ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException (" Downloader Ġnot Ġin Ġlist !") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component Ġis ĠBlock Downloader ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Distribut e Map . remove ( component . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġres Context . block Inspector . with Block Re dest ributed ( getBlock Distribution ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( current Status ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Starting , ĠDown loader Status . Stop After Started Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIgnore d ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug (" Child Ġdown loader Ġstopped Ġduring Ġmain Ġdown loader Ġstarting .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component Ed en . isEmpty () Ġ&& Ġcomponents . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error (" All Ġchild Ġdown loader Ġstopped Ġduring Ġmain Ġdown loader Ġstarting !") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Running ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Download Stopped ( service , Ġfile . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Running Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component Ed en . isEmpty () Ġ&& Ġcomponents . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error (" All Ġchild Ġdown loader Ġstopped Ġduring Ġmain Ġdown loader Ġrunning !") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Download Stopped ( service , Ġfile . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre balance Blocks () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopping Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component Ed en . isEmpty () Ġ&& Ġcomponents . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Stopped ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Writer ?. safe Close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Writer Ġ= Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Download Stopped ( service , Ġfile . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Start After Stopped Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( component Ed en . isEmpty () Ġ&& Ġcomponents . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Status Ġ= ĠDown loader Status . Stopped ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Writer ?. safe Close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Writer Ġ= Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( start ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Download Started ( service , Ġfile . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre balance Blocks () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDown loader Status . Stopped Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIgnore d ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn (" Child Ġdown loader Ġstopped Ġafter Ġmain Ġdown loader Ġstopped . ĠNot Ġideal .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Block Downloaded ( downloader : ĠBlock Downloader , Ġblock : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . run On Working Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdown loader . un assign Blocks 2 ( set Of ( block )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( downloader ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠHttp Block Downloader Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġres Context . block Inspector . with Block Downloaded ( block , Ġdown loader . url ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠSh aring Block Downloader Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġres Context . block Inspector . with Block Downloaded ( block , Ġdown loader . resource . url ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info (" Block Ġ$ block /${ file . metadata . blocks . size Ġ- Ġ 1 } Ġdownload Ġcompleted Ġfor Ġfile Ġ${ file . id } Ġby Ġdown loader Ġ$ downloader .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Block Downloaded ( service , Ġfile . id , Ġblock ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġw Ġ= Ġfile Writer !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( w . writable Blocks . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Download Completed ( service , Ġfile . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Download Stopped ( service , Ġfile . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Block Download Failed ( downloader : ĠBlock Downloader , Ġblock : ĠInt , Ġex : ĠThrowable ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġservice . run On Working Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdown loader . un assign Blocks 2 ( set Of ( block )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info (" Block Ġ$ block /${ file . metadata . blocks . size Ġ- Ġ 1 } Ġdownload Ġfailed Ġfor Ġfile Ġ${ file . id } Ġby Ġdown loader Ġ$ downloader .", Ġex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . safe ForEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Block Download Failed ( service , Ġfile . id , Ġblock , Ġex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġretry Ġfor ĠX Ġtimes Ġor Ġfailed ! ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Resource Found ( r : ĠO c Resource ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . debug (" Resource Ġfound : Ġ${ r . url }") ĊĊĠĠĠĠĠĠĠ Ġservice . run On Working Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( download Strategy . is P 2 p Enabled ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġw Ġ= Ġfile Writer Ġ?: Ġreturn @ run On Working Thread ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġd Ġ= ĠSh aring Block Downloader ( next Downloader Id . get And Increment (), Ġr , Ġw , Ġ_ download Statistics ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( h atch New Downloader ( d )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd . download Listeners Ġ+= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Resource Lost ( r : ĠO c Resource ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . debug (" Resource Ġlost : Ġ${ r . url }") ĊĊĠĠĠĠĠĠĠ Ġservice . run On Working Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( components Ġ+ Ġcomponent Ed en ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġis ĠSh aring Block Downloader ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġit . resource . unique Identifier Ġ== Ġr . unique Identifier ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . stop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Component Stopped ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlogger : ĠLogger Ġ= ĠLoggerFactory . getLogger ( Main Downloader :: class . java ) ĊĠĠĠ Ġ} Ċ }