/*** Ċ Ġ* ĠCopyright Ġ 2 0 1 8 ĠH adi ĠL ash k ari ĠG hou chan i Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ* Ċ Ġ* Ġ*/ Ċ package Ġcom . gitlab . sample . data . common . db . datasource Ċ Ċ import Ġandroidx . paging . Position al DataSource Ċ import Ġandroid . util . Log Ċ import Ġio . object box . query . Query Ċ import Ġio . object box . reactive . Data Observer Ċ import Ġjava . util . concurrent . atomic . Atomic Integer Ċ Ċ class ĠLimit Offset DataSource < T >( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġquery : ĠQuery < T >, ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġdata HashCode : ĠAtomicInteger Ċ ) Ġ: ĠPosition al DataSource < T >(), ĠData Observer < List < T >> Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġon Data ( data : ĠList < T >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠhashCode Ġ= Ġdata . hashCode () ĊĠĠĠĠĠĠĠ Ġif Ġ( hashCode Ġ!= Ġdata HashCode . get AndSet ( hashCode ) Ġ&& Ġdata . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġload Initial ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparams : ĠLoad Initial Params , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback : ĠLoad Initial Callback < T ?> ĊĠĠĠ Ġ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġtotal Count Ġ= Ġcount Items () ĊĠĠĠĠĠĠĠ Ġif Ġ( total Count Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . on Result ( emptyList (), Ġ 0 , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠLog . d ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Limit Offset DataSource ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" load Initial : Ġ${ params . requested Start Position }, Ġ${ params . requested Load Size }, Ġ$ total Count " ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġbound Ġthe Ġsize Ġrequested , Ġbased Ġon Ġknown Ġcount ĊĠĠĠĠĠĠĠ Ġval Ġfirst Load Position Ġ= Ġcompute Initial Load Position ( params , Ġtotal Count ) ĊĠĠĠĠĠĠĠ Ġval Ġfirst Load Size Ġ= Ġcompute Initial Load Size ( params , Ġfirst Load Position , Ġtotal Count ) ĊĊĠĠĠĠĠĠĠ Ġval Ġlist Ġ= Ġload Range ( first Load Position , Ġfirst Load Size ) ĊĠĠĠĠĠĠĠ Ġif Ġ( list . size Ġ== Ġfirst Load Size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . on Result ( list , Ġfirst Load Position , Ġtotal Count ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnull Ġlist , Ġor Ġsize Ġdoesn 't Ġmatch Ġrequest Ġ- ĠDB Ġmodified Ġbetween Ġcount Ġand Ġload ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġload Range ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparams : ĠLoad Range Params , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback : ĠLoad Range Callback < T ?> ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlist Ġ= Ġload Range ( params . start Position , Ġparams . load Size ) ĊĠĠĠĠĠĠĠ Ġcallback . on Result ( list ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCount Ġnumber Ġof Ġrows Ġquery Ġcan Ġreturn ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcount Items (): ĠInt Ġ= Ġquery . count (). toInt () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġrows Ġfrom Ġstart Pos Ġto Ġstart Pos Ġ+ Ġload Count ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġload Range ( start Position : ĠInt , Ġload Count : ĠInt ): ĠList < T > Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d (" Limit Offset DataSource ", Ġ" load Range : Ġ$ start Position , Ġ$ load Count ") ĊĠĠĠĠĠĠĠ Ġreturn Ġquery . find ( start Position . to Long (), Ġload Count . to Long ()) ĊĠĠĠ Ġ} Ċ } ĊĊ