/* Ċ Ġ* Ġ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 Ġorg . mode lix . model . api Ċ Ċ import Ġkotlin . jvm . Volatile Ċ Ċ class ĠP Branch Ġconstructor (@ field : Volatile Ġprivate Ġvar Ġtree : ĠI Tree , Ġprivate Ġval Ġid Generator : ĠI Id Generator ) Ġ: ĠI Branch Ġ{ ĊĠĠĠ Ġprivate Ġval Ġwrite Lock Ġ= ĠAny () ĊĠĠĠ Ġprivate Ġval Ġcontext Transactions Ġ= ĠContext Value < Transaction ?> () ĊĠĠĠ Ġprivate Ġvar Ġlisteners Ġ= ĠarrayOf < IB r anch Listener >() ĊĠĠĠ Ġprivate Ġval Ġbranch Id : ĠString Ġ= Ġtree . getId () Ġ?: Ġid Generator . generate (). toString () ĊĊĠĠĠ Ġoverride Ġfun ĠgetId (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġbranch Id ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġrun With Transaction ( transaction : ĠI Transaction , Ġrunnable : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontext Transactions . compute With ( transaction Ġas ĠTransaction , Ġrunnable ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġrun Read ( run nable : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġprev Transaction Ġ= Ġcontext Transactions . getValue () ĊĠĠĠĠĠĠĠ Ġif Ġ( prev Transaction Ġis ĠI Read Transaction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrunnable () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Tree Ġ= Ġprev Transaction ?. tree Ġ?: Ġtree ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt Ġ= ĠRead Transaction ( current Tree , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext Transactions . compute With ( t , Ġrunnable ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġrun Write ( run nable : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrun Synchron ized ( write Lock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Transaction Ġ= Ġcontext Transactions . getValue () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( prev Transaction Ġ! is ĠRead Transaction ) Ġ{ Ġ" Cannot Ġrun Ġwrite Ġfrom Ġread " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Write Ġ= Ġprev Transaction Ġas ĠWrite Transaction ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġold Tree : ĠI Tree Ġ= Ġprev Write ?. tree Ġ?: Ġtree ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Write Ġ= ĠWrite Transaction ( old Tree , Ġthis , Ġid Generator ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext Transactions . compute With ( new Write , Ġrunnable ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Write . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Tree : ĠI Tree Ġ= Ġnew Write . tree ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( prev Write Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtree Ġ= Ġnew Tree ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Tree Change ( old Tree , Ġnew Tree ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev Write . tree Ġ= Ġnew Tree ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Write . close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġ< T > Ġcompute Read ( comp utable : Ġ() Ġ-> ĠT ): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresult : ĠT ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġrun Read Ġ{ Ġresult Ġ= Ġcomp utable () Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresult Ġas ĠT ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġ< T > Ġcompute Write ( comp utable : Ġ() Ġ-> ĠT ): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresult : ĠT ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġrun Write Ġ{ Ġresult Ġ= Ġcomp utable () Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresult Ġas ĠT ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġcan Read (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcontext Transactions . getValue () Ġ!= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġcan Write (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcontext Transactions . getValue () Ġis ĠI Write Transaction ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġtransaction : ĠI Transaction ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġcontext Transactions . getValue () Ġ?: Ġthrow ĠIllegalStateException (" Not Ġin Ġa Ġtransaction ") ĊĊĠĠĠ Ġoverride Ġval Ġread Transaction : ĠI Read Transaction ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransaction Ġ= Ġtransaction ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( transaction Ġis ĠRead Transaction ) Ġ{ Ġ" Not Ġin Ġa Ġread Ġtransaction " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtransaction ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġwrite Transaction : ĠI Write Transaction ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransaction Ġ= Ġtransaction ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( transaction Ġis ĠWrite Transaction ) Ġ{ Ġ" Not Ġin Ġa Ġwrite Ġtransaction " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtransaction ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġadd Listener ( l : ĠI Branch Listener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlisteners Ġ= ĠCO W Arrays . add If Absent ( listeners , Ġl ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġremove Listener ( l : ĠI Branch Listener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlisteners Ġ= ĠCO W Arrays . remove ( listeners , Ġl ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġfun Ġnotify Tree Change ( old Tree : ĠI Tree , Ġnew Tree : ĠI Tree ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( old Tree Ġ=== Ġnew Tree ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( l Ġin Ġlisteners ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl . tree Changed ( old Tree , Ġnew Tree ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog Error (" Exception Ġin Ġbranch Ġlistener ", Ġex , ĠP Branch :: class ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ