/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 1 9 ĠSpotify ĠAB . Ċ Ġ* Ċ Ġ* ĠLicensed Ġto Ġthe ĠApache ĠSoftware ĠFoundation Ġ( ASF ) Ġunder Ġone Ċ Ġ* Ġor Ġmore Ġcontributor Ġlicense Ġagreements . Ġ ĠSee Ġthe ĠNOTICE Ġfile Ċ Ġ* Ġdistributed Ġwith Ġthis Ġwork Ġfor Ġadditional Ġinformation Ċ Ġ* Ġregarding Ġcopyright Ġownership . Ġ ĠThe ĠASF Ġlicenses Ġthis Ġfile Ċ Ġ* Ġto Ġyou Ġ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 . spotify . hero ic . aggregation . simple Ċ Ċ import Ġcom . spotify . hero ic . aggregation . Abstract Bucket Ċ import Ġcom . spotify . hero ic . metric . Metric Ċ import Ġcom . spotify . hero ic . metric . Point Ċ import Ġcom . spotify . hero ic . metric . Spread Ċ import Ġjava . util . concurrent . atomic . Double Accumulator Ċ import Ġjava . util . concurrent . atomic . Double Ad der Ċ import Ġjava . util . concurrent . atomic . Long Ad der Ċ Ċ /** Ċ Ġ* ĠBucket Ġthat Ġkeeps Ġtrack Ġof Ġthe Ġamount Ġof Ġdata Ġpoints Ġseen , Ġand Ġthere Ġsum med Ġvalue . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠTake Ġcare Ġto Ġnot Ġblind ly Ġtrust Ġ[. value ] Ġsince Ġit Ġis Ġinitialized Ġto Ġ 0 Ġfor Ġsimplicity . Ċ Ġ* ĠAlways Ġcheck Ġ[. count ], Ġwhich Ġif Ġzero Ġindicates Ġthat Ġthe Ġ[. value ] Ġis Ġundefined Ċ Ġ* Ġ( e . g . ĠNaN ). Ċ Ġ* Ċ Ġ* Ġ@ author Ġ udo prog Ċ Ġ*/ Ċ data Ġclass ĠSp read Bucket ( override Ġval Ġtimestamp : ĠLong ) Ġ: ĠAbstract Bucket () Ġ{ ĊĊĠĠĠ Ġinternal Ġval Ġcount Ġ= ĠLong Ad der () ĊĠĠĠ Ġinternal Ġval Ġsum Ġ= ĠDouble Ad der () ĊĠĠĠ Ġinternal Ġval Ġsum 2 Ġ= ĠDouble Ad der () ĊĠĠĠ Ġinternal Ġval Ġmax Ġ= ĠDouble Accumulator ( max Fn , Ġjava . lang . Double . NEGATIVE _ INFINITY ) ĊĠĠĠ Ġinternal Ġval Ġmin Ġ= ĠDouble Accumulator ( min Fn , Ġjava . lang . Double . POSITIVE _ INFINITY ) ĊĊĠĠĠ Ġoverride Ġfun Ġupdate Spread ( key : ĠMap < String , ĠString >, Ġd : ĠSp read ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcount . add ( d . count ) ĊĠĠĠĠĠĠĠ Ġsum . add ( d . sum ) ĊĠĠĠĠĠĠĠ Ġsum 2 . add ( d . sum 2 ) ĊĠĠĠĠĠĠĠ Ġmax . accum ulate ( d . max ) ĊĠĠĠĠĠĠĠ Ġmin . accum ulate ( d . min ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġupdate Point ( key : ĠMap < String , ĠString >, Ġd : ĠPoint ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġd . value ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! java . lang . Double . is Finite ( value )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcount . increment () ĊĠĠĠĠĠĠĠ Ġsum . add ( value ) ĊĠĠĠĠĠĠĠ Ġsum 2 . add ( value Ġ* Ġvalue ) ĊĠĠĠĠĠĠĠ Ġmax . accum ulate ( value ) ĊĠĠĠĠĠĠĠ Ġmin . accum ulate ( value ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġnew Spread (): ĠMetric Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcount Ġ= Ġthis . count . sum () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( count Ġ== Ġ 0 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMetric . invalid () ĊĠĠĠĠĠĠĠ Ġ} Ġelse ĠSp read ( timestamp , Ġcount , Ġsum . sum (), Ġsum 2 . sum (), Ġmin . get (), Ġmax . get ()) ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġinternal Ġval Ġmin Fn Ġ= Ġ{ Ġleft : ĠDouble , Ġright : ĠDouble Ġ-> ĠMath . min ( left , Ġright ) Ġ} ĊĠĠĠĠĠĠĠ Ġinternal Ġval Ġmax Fn Ġ= Ġ{ Ġleft : ĠDouble , Ġright : ĠDouble Ġ-> ĠMath . max ( left , Ġright ) Ġ} ĊĠĠĠ Ġ} Ċ } Ċ