/* Ċ Ġ* Ġ ĠCopyright Ġ 2 0 1 8 Ġa coder 2 0 1 3 Ċ Ġ* Ċ Ġ* Ġ Ġ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 . Ċ Ġ*/ Ċ Ċ // ĠCopyright Ġ 2 0 1 5 ĠThe Ġetcd ĠAuthors Ċ // Ċ // Ġ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 . song . y ama . raft Ċ Ċ import Ġcom . song . y ama . common . utils . Result Ċ import Ġcom . song . y ama . raft . exception . Raft Exception Ċ import Ġcom . song . y ama . raft . protobuf . Raft Proto Buf Ċ import Ġcom . song . y ama . raft . protobuf . Raft Proto Buf . Entry Ċ import Ġcom . song . y ama . raft . protobuf . Raft Proto Buf . Snapshot Ċ import Ġcom . song . y ama . raft . utils . ErrorCode Ċ import Ġcom . song . y ama . raft . utils . Utils Ċ import Ġorg . apache . commons . collections 4 . Collection Utils Ċ import Ġorg . slf 4 j . LoggerFactory Ċ Ċ class ĠR aft Log Ġ@ Jvm Over loads Ġconstructor ( ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġstorage Ġcontains Ġall Ġstable Ġentries Ġsince Ġthe Ġlast Ġsnapshot ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġra ft Storage : ĠR aft Storage , Ġvar Ġmax Msg Size : ĠLong Ġ= Ġjava . lang . Long . MAX _ VALUE ) Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġun stable Ġcontains Ġall Ġun stable Ġentries Ġand Ġsnapshot . Ġthey Ġwill Ġbe Ġsaved Ġinto Ġstorage ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġun stable : ĠUn stable ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġcommitted Ġis Ġthe Ġhighest Ġlog Ġposition Ġthat Ġis Ġknown Ġto Ġbe Ġin Ġstable Ġstorage Ġon Ġa Ġqu orum Ġof Ġnodes . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġcommitted : ĠLong Ġ= Ġ 0 ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġapplied Ġis Ġthe Ġhighest Ġlog Ġposition Ġthat Ġthe Ġapplication Ġhas Ġbeen Ġinstruct ed Ġto Ġapply Ġto Ġits Ġstate Ġmachine . ĊĠĠĠĠ Ġ* ĠIn variant : Ġapplied Ġ<= Ġcommitted ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġapplied : ĠLong Ġ= Ġ 0 ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfirst Index Ġ= Ġra ft Storage . first Index () ĊĠĠĠĠĠĠĠ Ġval Ġlast Index Ġ= Ġra ft Storage . last Index () ĊĊĠĠĠĠĠĠĠ Ġthis . unstable Ġ= ĠUn stable () ĊĠĠĠĠĠĠĠ Ġthis . unstable . offset Ġ= Ġlast Index Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠ Ġthis . committed Ġ= Ġfirst Index Ġ- Ġ 1 ĊĠĠĠĠĠĠĠ Ġthis . applied Ġ= Ġfirst Index Ġ- Ġ 1 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġmaybe Append Ġreturns Ġ( 0 , Ġfalse ) Ġif Ġthe Ġentries Ġcannot Ġbe Ġappended . ĠOtherwise , Ġit Ġreturns Ġ( last Ġindex Ġof Ġnew ĊĠĠĠĠ Ġ* Ġentries , Ġtrue ). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġmaybe Append ( index : ĠLong , Ġlog Term : ĠLong , Ġcommitted : ĠLong , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġent s : ĠList < Raft Proto Buf . Entry >): ĠResult < Long > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( match Term ( index , Ġlog Term )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast new i Ġ= Ġindex Ġ+ ĠCollection Utils . size ( ents ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġci Ġ= Ġfind Conflict ( ents ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ci Ġ== Ġ 0 L ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( ci Ġ<= Ġthis . committed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= ĠString ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. format (" entry Ġ% d Ġconflict Ġwith Ġcommitted Ġentry Ġ[ committed (% d )] ", Ġci , Ġthis . committed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠR aft Exception ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoffset Ġ= Ġindex Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend ( ents . sub List (( ci Ġ- Ġoffset ). toInt (), Ġent s . size ). to Mutable List ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommit To ( Math . min ( committed , Ġlast new i )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠResult . success ( last new i ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠResult . fail ( 0 L ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ/ Ġfind Conflict Ġfinds Ġthe Ġindex Ġof Ġthe Ġconflict . ĠIt Ġreturns Ġthe Ġfirst Ġpair Ġof Ġconflicting Ġentries Ġbetween Ġthe ĊĠĠĠĠ Ġ* Ġexisting Ġentries Ġand Ġthe Ġgiven Ġentries , Ġif Ġthere Ġare Ġany . ĠIf Ġthere Ġis Ġno Ġconflicting Ġentries , Ġand Ġthe Ġexisting ĊĠĠĠĠ Ġ* Ġentries Ġcontains Ġall Ġthe Ġgiven Ġentries , Ġzero Ġwill Ġbe Ġreturned . ĠIf Ġthere Ġis Ġno Ġconflicting Ġentries , Ġbut Ġthe Ġgiven ĊĠĠĠĠ Ġ* Ġentries Ġcontains Ġnew Ġentries , Ġthe Ġindex Ġof Ġthe Ġfirst Ġnew Ġentry Ġwill Ġbe Ġreturned . ĠAn Ġentry Ġis Ġconsidered Ġto Ġbe ĊĠĠĠĠ Ġ* Ġconflicting Ġif Ġit Ġhas Ġthe Ġsame Ġindex Ġbut Ġa Ġdifferent Ġterm . ĠThe Ġfirst Ġentry ĠMUST Ġhave Ġan Ġindex Ġequal Ġto Ġthe ĊĠĠĠĠ Ġ* Ġargument Ġ' from '. ĠThe Ġindex Ġof Ġthe Ġgiven Ġentries ĠMUST Ġbe Ġcontinuous ly Ġincreasing . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġfind Conflict ( ents : ĠList < Raft Proto Buf . Entry >? ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( ents Ġ!= Ġnull Ġ&& Ġent s . size Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( entry Ġin Ġent s ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! match Term ( entry . index , Ġentry . term )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entry . index Ġ<= Ġlast Index ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info ( String . format ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" found Ġconflict Ġat Ġindex Ġ% d Ġ[ existing Ġterm : Ġ% d , Ġconflicting Ġterm : Ġ% d ]", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . index , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . zero Term On Err Compact ed ( this . term ( entry . index ). data , Ġnull ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . term )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġentry . index ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġun stable Entries (): ĠList < Raft Proto Buf . Entry > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( Collection Utils . isEmpty ( this . unstable !!. entries )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġempty List () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġthis . unstable !!. entries ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġnext Ent s Ġreturns Ġall Ġthe Ġavailable Ġentries Ġfor Ġexecution . ĠIf Ġapplied Ġis Ġsmaller Ġthan Ġthe Ġindex Ġof Ġsnapshot , Ġit ĊĠĠĠĠ Ġ* Ġreturns Ġall Ġcommitted Ġentries Ġafter Ġthe Ġindex Ġof Ġsnapshot . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġnext Ent s (): ĠList < Entry > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoff Ġ= ĠMath . max ( this . applied Ġ+ Ġ 1 , Ġfirst Index ()) ĊĠĠĠĠĠĠĠ Ġif Ġ( this . committed Ġ+ Ġ 1 Ġ> Ġoff ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġslice ( off , Ġthis . committed Ġ+ Ġ 1 , Ġmax Msg Size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result . is Failure ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠString . format (" unexpected Ġerror Ġwhen Ġgetting Ġun applied Ġentries Ġ(% s )", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠErrorCode . getBy Code ( result . code ). desc )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult . data ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġempty List () ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġhas Next Ent s Ġreturns Ġif Ġthere Ġis Ġany Ġavailable Ġentries Ġfor Ġexecution . ĠThis Ġis Ġa Ġfast Ġcheck Ġwithout Ġheavy ĊĠĠĠĠ Ġ* Ġra ft Log . slice () Ġin Ġra ft Log . next Ent s (). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġhas Next Ent s (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoff Ġ= ĠMath . max ( this . applied Ġ+ Ġ 1 , Ġfirst Index ()) ĊĠĠĠĠĠĠĠ Ġreturn Ġthis . committed Ġ+ Ġ 1 Ġ> Ġoff ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġsnapshot (): ĠResult < Snapshot > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( this . unstable !!. snapshot Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResult . success ( this . unstable !!. snapshot ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġthis . raft Storage !!. snapshot () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġcommit To ( to Commit : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġnever Ġdecrease Ġcommit ĊĠĠĠĠĠĠĠ Ġif Ġ( this . committed Ġ< Ġto Commit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( last Index () Ġ< Ġto Commit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( String . format ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" to commit (% d ) Ġis Ġout Ġof Ġrange Ġ[ last Index (% d )]. ĠWas Ġthe Ġra ft Ġlog Ġcorrupted , Ġtruncated , Ġor Ġlost ?", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Commit , Ġlast Index ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . committed Ġ= Ġto Commit ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġapplied To ( i : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( i Ġ== Ġ 0 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( committed Ġ< Ġi Ġ|| Ġi Ġ< Ġapplied ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( String ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. format (" applied (% d ) Ġis Ġout Ġof Ġrange Ġ[ prev Applied (% d ), Ġcommitted (% d )] ", Ġi , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . applied , Ġthis . committed )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġapplied Ġ= Ġi ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġstable To ( i : ĠLong , Ġt : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . unstable !!. stable To ( i , Ġt ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġstable Snap To ( i : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . unstable !!. stable Snap To ( i ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġlast Term (): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġterm ( last Index ()) ĊĠĠĠĠĠĠĠ Ġif Ġ( result . is Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult . data ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthrow ĠR aft Exception (" Unexpected Ġerror Ġwhen Ġgetting Ġthe Ġlast Ġterm Ġ: Ġ" Ġ+ Ġresult . code ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġappend ( entries : ĠMutable List < Entry >): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( Collection Utils . isEmpty ( entries )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġlast Index () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġafter Ġ= Ġentries [ 0 ]. index Ġ- Ġ 1 ĊĠĠĠĠĠĠĠ Ġif Ġ( after Ġ< Ġcommitted ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠString . format (" after (% d ) Ġis Ġout Ġof Ġrange Ġ[ committed (% d )] ", Ġafter , Ġthis . committed )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġthis . unstable . truncate And Append ( entries ) ĊĠĠĠĠĠĠĠ Ġreturn Ġlast Index () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġfirst Index (): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġthis . unstable !!. maybe First Index () ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( result . is Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . data ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġthis . raft Storage !!. first Index () ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġlast Index (): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġun stable !!. maybe Last Index () ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( result . is Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . data ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġra ft Storage . last Index () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġterm ( i : ĠLong ): ĠResult < Long > Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġthe Ġvalid Ġterm Ġrange Ġis Ġ[ index Ġof Ġdummy Ġentry , Ġlast Ġindex ] ĊĠĠĠĠĠĠĠ Ġval Ġdummy Index Ġ= Ġfirst Index () Ġ- Ġ 1 ĊĠĠĠĠĠĠĠ Ġif Ġ( i Ġ< Ġdummy Index Ġ|| Ġi Ġ> Ġlast Index ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠResult . success ( 0 L ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġthis . unstable !!. maybe Term ( i ) ĊĠĠĠĠĠĠĠ Ġif Ġ( result . is Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġterm Result Ġ= Ġthis . raft Storage !!. term ( i ) ĊĠĠĠĠĠĠĠ Ġif Ġ( term Result . is Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġterm Result ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( result . code Ġ== ĠErrorCode . Err Compact ed . code Ġ|| Ġresult . code Ġ== ĠErrorCode . Err Unavailable . code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠResult . success ( 0 L ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Unexpected Ġerror " Ġ+ ĠErrorCode . getBy Code ( result . code ). desc ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġentries ( i : ĠLong , ĠmaxSize : ĠLong ): ĠResult < List < Entry >> Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( i Ġ> Ġlast Index ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResult . success ( emptyList ()) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġslice ( i , Ġlast Index () Ġ+ Ġ 1 , ĠmaxSize ) ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġall Entries (): ĠList < Entry > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġentries ( first Index (), Ġjava . lang . Long . MAX _ VALUE ) ĊĠĠĠĠĠĠĠ Ġif Ġ( result . is Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult . data ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( result . code Ġ== ĠErrorCode . Err Compact ed ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// TODO : try Ġagain Ġif Ġthere Ġwas Ġa Ġr acing Ġcomp action ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġall Entries () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// FIX ME : handle Ġerror ĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( ErrorCode . getBy Code ( result . code ). desc ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġis Up ToDate Ġdetermines Ġif Ġthe Ġgiven Ġ( last Index , term ) Ġlog Ġis Ġmore Ġup - to - date Ġby Ġcomparing Ġthe Ġindex Ġand Ġterm Ġof Ġthe ĊĠĠĠĠ Ġ* Ġlast Ġentries Ġin Ġthe Ġexisting Ġlogs . ĠIf Ġthe Ġlogs Ġhave Ġlast Ġentries Ġwith Ġdifferent Ġterms , Ġthen Ġthe Ġlog Ġwith Ġthe ĊĠĠĠĠ Ġ* Ġlater Ġterm Ġis Ġmore Ġup - to - date . ĠIf Ġthe Ġlogs Ġend Ġwith Ġthe Ġsame Ġterm , Ġthen Ġwh iche ver Ġlog Ġhas Ġthe Ġlarger Ġlast Index Ġis ĊĠĠĠĠ Ġ* Ġmore Ġup - to - date . ĠIf Ġthe Ġlogs Ġare Ġthe Ġsame , Ġthe Ġgiven Ġlog Ġis Ġup - to - date . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġis Up ToDate ( last i : ĠLong , Ġterm : ĠLong ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġterm Ġ> Ġlast Term () Ġ|| Ġterm Ġ== Ġlast Term () Ġ&& Ġlast i Ġ>= Ġlast Index () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġmatch Term ( i : ĠLong , Ġterm : ĠLong ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġterm ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult . is Success Ġ&& Ġresult . data Ġ== Ġterm ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn ( e . message , Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġmaybe Commit ( max Index : ĠLong , Ġterm : ĠLong ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( max Index Ġ> Ġthis . committed Ġ&& Ġzero Term On Err Compact ed ( term ( max Index ). data , Ġnull ) Ġ== Ġterm ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommit To ( max Index ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġrestore ( snapshot : ĠR aft Proto Buf . Snapshot ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . info ( String . format (" log Ġ[% s ] Ġstarts Ġto Ġrestore Ġsnapshot Ġ[ index : Ġ% d , Ġterm : Ġ% d ]", Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsnapshot . metadata . index , Ġsnapshot . metadata . term )) ĊĠĠĠĠĠĠĠ Ġthis . committed Ġ= Ġsnapshot . metadata . index ĊĠĠĠĠĠĠĠ Ġthis . unstable !!. restore ( snapshot ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġslice ( lo : ĠLong , Ġhi : ĠLong , ĠmaxSize : ĠLong ): ĠResult < List < Entry >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠerrorCode Ġ= Ġmust Check OutOfBounds ( lo , Ġhi ) ĊĠĠĠĠĠĠĠ Ġif Ġ( errorCode Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠResult . fail ( errorCode . code , ĠerrorCode . desc , Ġempty List ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( lo Ġ== Ġhi ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠResult . success ( emptyList ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar Ġent s : ĠMutable List < Entry >? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġif Ġ( lo Ġ< Ġthis . unstable . offset ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġra ft Storage ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. entries ( lo , ĠMath . min ( hi , Ġthis . unstable . offset ), ĠmaxSize ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result . is Failure ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcode Ġ= ĠErrorCode . getBy Code ( result . code ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( code Ġ=== ĠErrorCode . Err Compact ed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠResult . fail ( code . code , Ġcode . desc , Ġempty List ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( code Ġ=== ĠErrorCode . Err Unavailable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( String ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. format (" entries [% d :% d ) Ġis Ġunavailable Ġfrom Ġstorage ", Ġlo , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMath . min ( hi , Ġthis . unstable . offset ))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( code . desc ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result . data . size Ġ< ĠMath . min ( hi , Ġthis . unstable !!. offset ) Ġ- Ġlo ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠResult . success ( result . data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġent s Ġ= Ġresult . data . to Mutable List () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( hi Ġ> Ġthis . unstable !!. offset ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentries Ġ= Ġthis . unstable !!. slice ( Math . max ( lo , Ġthis . unstable !!. offset ), Ġhi ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Collection Utils . isNotEmpty ( ents )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġent s !!. addAll ( entries ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġent s Ġ= Ġentries ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠResult . success ( Utils . limit Size ( ents !! , ĠmaxSize )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġl . first Index Ġ<= Ġlo Ġ<= Ġhi Ġ<= Ġl . first Index Ġ+ Ġlen ( l . entries ) ĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġmust Check OutOfBounds ( lo : ĠLong , Ġhi : ĠLong ): ĠErrorCode ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( lo Ġ> Ġhi ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( String . format (" invalid Ġslice Ġ% d Ġ> Ġ% d ", Ġlo , Ġhi )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġfi Ġ= Ġfirst Index () ĊĊĠĠĠĠĠĠĠ Ġif Ġ( lo Ġ< Ġfi ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠErrorCode . Err Compact ed ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġlength Ġ= Ġlast Index () Ġ+ Ġ 1 Ġ- Ġfi ĊĠĠĠĠĠĠĠ Ġif Ġ( lo Ġ< Ġfi Ġ|| Ġhi Ġ> Ġfi Ġ+ Ġlength ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠString . format (" slice [% d ,% d ) Ġout Ġof Ġbound Ġ[% d ,% d ]", Ġlo , Ġhi , Ġfi , Ġlast Index ())) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġzero Term On Err Compact ed ( t : ĠLong ?, ĠerrorCode : ĠErrorCode ?): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġt Ġ= Ġt ĊĠĠĠĠĠĠĠ Ġif Ġ( t Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" t Ġis Ġnull Ġ, Ġchange Ġit Ġinto Ġzero ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġt Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( errorCode Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġt ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( errorCode Ġ=== ĠErrorCode . Err Compact ed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠString . format (" unexpected Ġerror Ġ(% d )", ĠerrorCode . code )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlog Ġ= ĠLoggerFactory . getLogger ( Raft Log :: class . java ) ĊĠĠĠ Ġ} Ċ } Ċ