package Ġnet . lf n 3 . le th Ċ Ċ import Ġnet . lf n 3 . le th . unsafe . InMemory Partition ed Log Ċ import Ġorg . junit . jupiter . api . Assertions . assert Throws Ċ import Ġorg . junit . jupiter . api . Nested Ċ import Ġjava . util . concurrent . atomic . Atomic Integer Ċ import Ġjava . util . concurrent . atomic . Atomic Long Ċ import Ġjava . util . stream . Collectors Ċ import Ġjava . util . stream . Int Stream Ċ import Ġjava . util . stream . Long Stream Ċ import Ġkotlin . test .* Ċ Ċ abstract Ġclass ĠLog Test ( private Ġval Ġctor : Ġ() Ġ-> ĠLog < Pair < Long , ĠLong >>) Ġ{ ĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` The Ġlog Ġreturns Ġa Ġsingle Ġrecorded Ġentry `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠ Ġval Ġentry Ġ= ĠPair ( 6 L , Ġ 7 L ) ĊĠĠĠĠĠĠĠ Ġval Ġseq Ġ= Ġlog . record ( entry ) ĊĠĠĠĠĠĠĠ Ġval Ġ( quer ied Seq , Ġqueried Val ) Ġ= Ġlog . head With Seq () !! ĊĊĠĠĠĠĠĠĠ ĠassertEquals ( entry , Ġqueried Val ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( seq , Ġqueried Seq ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġlog . size ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Can Ġiterate Ġeverything Ġadded Ġto Ġa Ġlog `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= ĠPair ( 6 L , Ġ 7 L ) ĊĠĠĠĠĠĠĠ Ġval Ġsecond Ġ= ĠPair ( 7 L , Ġ 7 L ) ĊĠĠĠĠĠĠĠ Ġval Ġthird Ġ= ĠPair ( 9 L , Ġ 7 L ) ĊĠĠĠĠĠĠĠ Ġlog . batch Record ( array ListOf ( first , Ġsecond , Ġthird )) ĊĊĠĠĠĠĠĠĠ ĠassertEquals ( 3 , Ġlog . size ) ĊĠĠĠĠĠĠĠ Ġval Ġiter Ġ= Ġlog . iterator () ĊĊĠĠĠĠĠĠĠ ĠassertEquals ( first , Ġiter . next ()) ĊĠĠĠĠĠĠĠ ĠassertEquals ( second , Ġiter . next ()) ĊĠĠĠĠĠĠĠ ĠassertEquals ( third , Ġiter . next ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Iterator Ġshould Ġnot Ġsee Ġnewly Ġadded Ġitems `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= ĠPair ( 6 L , Ġ 7 L ) ĊĠĠĠĠĠĠĠ Ġlog . record ( first ) ĊĊĠĠĠĠĠĠĠ Ġval Ġiter Ġ= Ġlog . iterator () ĊĊĠĠĠĠĠĠĠ ĠassertEquals ( first , Ġiter . next ()) ĊĠĠĠĠĠĠĠ Ġlog . record ( Pair ( 6 L , Ġ 7 L )) ĊĊĠĠĠĠĠĠĠ ĠassertFalse ( iter . hasNext ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Should Ġbe Ġable Ġto Ġpartition Ġlog `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠ Ġval Ġfirst : ĠPair < Long , ĠLong > Ġ= ĠPair ( 1 , Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġlog . record ( first ) ĊĊĠĠĠĠĠĠĠ Ġval Ġindexed Ġ= ĠIn Memory Partition ed Log ( log ) Ġ{ Ġit . first Ġ} ĊĊĠĠĠĠĠĠĠ ĠassertEquals ( first , Ġindexed . head ( 1 )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Should Ġsee Ġnew Ġentries Ġin Ġpartition ed Ġlog `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĠĠĠĠĠĠĠ Ġval Ġindexed Ġ= ĠIn Memory Partition ed Log ( log ) Ġ{ Ġit . first Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġentry : ĠPair < Long , ĠLong > Ġ= ĠPair ( 5 , Ġ 6 ) ĊĠĠĠĠĠĠĠ Ġlog . record ( entry ) ĊĊĠĠĠĠĠĠĠ ĠassertEquals ( entry , Ġlog . head ()) ĊĠĠĠĠĠĠĠ ĠassertEquals ( entry , Ġindexed . head ( 5 )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Can Ġmap Ġover Ġlog `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĠĠĠĠĠĠĠ Ġval Ġmapped Ġ= ĠLog Reader . map ( log ) Ġ{ Ġit . first Ġ+ Ġit . second Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġcounter Ġ= ĠAtomic Long () ĊĊĠĠĠĠĠĠĠ ĠassertNull ( mapped . head ()) ĊĊĠĠĠĠĠĠĠ Ġlog . record ( Pair ( 3 , Ġ 4 )) ĊĊĠĠĠĠĠĠĠ Ġmapped . tail Ġ{ Ġcounter . add AndGet ( it ) Ġ} ĊĊĠĠĠĠĠĠĠ ĠassertEquals ( 7 , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 7 , Ġmapped . head ()) ĊĊĠĠĠĠĠĠĠ Ġlog . record ( Pair ( 2 , Ġ 1 )) ĊĊĠĠĠĠĠĠĠ ĠassertEquals ( 1 0 , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 3 , Ġmapped . head ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Nested ĊĠĠĠ Ġinner Ġclass ĠBatch Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Should Ġbe Ġable Ġto Ġbatch Ġinsert `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Insert : ĠCollection < Pair < Long , ĠLong >> Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLong Stream . range ( 1 , Ġ 1 0 0 ). map To Obj Ġ{ ĠPair ( 1 . to Long (), Ġit ) Ġ}. collect ( Collectors . toList ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . batch Record ( to Insert ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġiter Ġ= Ġto Insert . iterator () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail Ġ{ ĠassertEquals ( iter . next (), Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Batch Ġinsert Ġshould Ġfire Ġob servers `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Ġ= ĠAtomicInteger ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Insert Ġ= Ġ 1 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentries Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠInt Stream . range ( 0 , Ġto Insert ). map To Obj Ġ{ ĠPair ( 1 . to Long (), Ġit . to Long ()) Ġ}. collect ( Collectors . toSet ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcounter . increment AndGet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( entries . contains ( it )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . batch Record ( entries ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( to Insert , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Nested ĊĠĠĠ Ġinner Ġclass ĠT ailing Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Can Ġtail Ġlog `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Ġ= ĠAtomicInteger ( 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail Ġ{ Ġcounter . increment AndGet () Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . record ( Pair ( 5 L , Ġ 1 2 L )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Should Ġsee Ġupdates Ġin Ġtail `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Ġ= ĠAtomicInteger ( 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail Ġ{ Ġcounter . increment AndGet () Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= ĠPair ( 1 2 L , Ġ 3 L ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseq Ġ= Ġlog . record ( entry ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġcounter . get ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . update ({ Ġseq Ġ}, Ġ{ ĠPair ( it . first , Ġit . second Ġ+ Ġ 1 ) Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 2 , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Should Ġsee Ġexisting Ġvalues Ġin Ġtail `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Ġ= ĠAtomicInteger ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . record ( Pair ( 5 L , Ġ 1 2 L )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail Ġ{ Ġcounter . increment AndGet () Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . record ( Pair ( 5 L , Ġ 1 3 L )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 2 , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Can Ġtail Ġfrom Ġa Ġposition Ġin Ġthe Ġlog `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Ġ= ĠAtomicInteger ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . record ( Pair ( 5 L , Ġ 1 2 L )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseq 2 Ġ= Ġlog . record ( Pair ( 5 L , Ġ 1 2 L )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail ( seq 2 ) Ġ{ Ġcounter . increment AndGet () Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . record ( Pair ( 5 L , Ġ 1 2 L )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 2 , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Can Ġtail Ġonly Ġupdates Ġusing Ġseq Ġ+ Ġ 1 `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Ġ= ĠAtomicInteger ( 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= ĠPair ( 1 2 L , Ġ 3 L ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseq Ġ= Ġlog . record ( entry ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail ( seq Ġ+ Ġ 1 ) Ġ{ Ġcounter . increment AndGet () Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 0 , Ġcounter . get ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . update ({ Ġseq Ġ}, Ġ{ ĠPair ( it . first , Ġit . second Ġ+ Ġ 1 ) Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Observer Ġthat Ġthrows Ġshould Ġnot Ġeffect Ġother Ġob servers `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Ġ= ĠAtomicInteger ( 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail Ġ{ Ġthrow ĠIllegalStateException () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail Ġ{ Ġcounter . increment AndGet () Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . record ( Pair ( 5 L , Ġ 1 2 L )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Observer Ġthat Ġthrows Ġshould Ġnot Ġeffect Ġother Ġob servers Ġwhen Ġbatch Ġinserting `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Ġ= ĠAtomicInteger ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Insert Ġ= Ġ 1 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentries Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠInt Stream . range ( 0 , Ġto Insert ). map To Obj Ġ{ ĠPair ( 1 . to Long (), Ġit . to Long ()) Ġ}. collect ( Collectors . toSet ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail Ġ{ Ġthrow ĠIllegalStateException () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail Ġ{ Ġcounter . increment AndGet () Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . batch Record ( entries ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( to Insert , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Nested ĊĠĠĠ Ġinner Ġclass ĠUpdates Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` The Ġlog Ġallows Ġupdates `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= ĠPair ( 1 2 L , Ġ 3 L ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseq Ġ= Ġlog . record ( entry ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . update ({ Ġseq Ġ}, Ġ{ ĠPair ( it . first , Ġit . second Ġ+ Ġ 1 ) Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġupdated Entry Ġ= ĠPair ( 1 2 L , Ġ 4 L ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( updated Entry , Ġlog . head ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 2 , Ġlog . size ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġiter Ġ= Ġlog . iterator () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( entry , Ġiter . next ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( updated Entry , Ġiter . next ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertFalse ( iter . hasNext ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` The Ġlog Ġshould Ġthrow Ġon Ġupdates Ġfor Ġunknown Ġsequences `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= ĠPair ( 1 2 L , Ġ 3 L ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseq Ġ= Ġlog . record ( entry ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Should Ġfail Ġsince Ġwe Ġdon 't Ġhave Ġthis Ġsequence , Ġyet . ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThrows ( Exception :: class . java ) Ġ{ Ġlog . update ({ Ġseq Ġ+ Ġ 1 Ġ}, Ġ{ ĠPair ( it . first , Ġit . second Ġ+ Ġ 1 ) Ġ}) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġlog . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( entry , Ġlog . get ( seq )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Log Ġshould Ġignore Ġupdates Ġto Ġsame Ġvalue `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= ĠPair ( 1 2 L , Ġ 3 L ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseq Ġ= Ġlog . record ( entry ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . tail ( seq Ġ+ Ġ 1 ) Ġ{ Ġfail (" Should Ġnot Ġhave Ġwritten Ġback Ġidentical Ġvalue ") Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . update ({ Ġseq Ġ}, Ġ{ ĠPair ( it . first , Ġit . second ) Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġlog . size ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Should Ġonly Ġapply Ġa Ġsingle Ġconflicting Ġupdate `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseq Ġ= Ġlog . record ( Pair ( 5 , Ġ 1 )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . update ({ Ġseq Ġ}, Ġ{ ĠPair ( it . first , Ġit . second Ġ+ Ġ 1 ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThrows ( java . lang . Exception :: class . java , Ġ{ Ġlog . update ({ Ġseq Ġ}, Ġ{ ĠPair ( it . first , Ġit . second Ġ+ Ġ 1 ) Ġ}) Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 2 , Ġlog . head () !!. second ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġ` Should Ġonly Ġretry Ġupdates Ġ 5 Ġtimes `() Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Ġ= Ġctor . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Ġ= ĠAtomic Long ( 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . record ( Pair ( 0 , Ġ 0 )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠLong Stream . range ( 0 , Ġ 6 ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . update ({ Ġlog . head With Seq () !!. first Ġ}, Ġ{ ĠPair ( it . first , Ġit . second Ġ+ Ġ 1 ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThrows ( java . lang . Exception :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . update ({ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Seq Ġ= Ġcounter . increment AndGet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( 5 Ġ< Ġnext Seq ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfail (" More Ġthan Ġ 5 Ġattempts Ġto Ġget Ġsequence ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Seq ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, Ġ{ ĠPair ( it . first , Ġit . second Ġ+ Ġ 1 ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 5 , Ġcounter . get ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ