Files
boc/aamos-ledger-rust/target/debug/deps/libarc_swap-ec08ea74b5f7d401.rlib
T

1444 lines
527 KiB
Plaintext
Raw Normal View History

!<arch>
/ 0 0 0 0 3874 `
0îÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐîÐ_ZN4core3ptr116drop_in_place$LT$alloc..boxed..Box$LT$core..mem..maybe_uninit..MaybeUninit$LT$arc_swap..debt..list..Node$GT$$GT$$GT$17hc0ea6edc94ef4df0E_ZN72_$LT$alloc..boxed..Box$LT$T$C$A$GT$$u20$as$u20$core..ops..drop..Drop$GT$4drop17hce3b2cd6d5f2b45cE_ZN4core3ptr58drop_in_place$LT$arc_swap..debt..list..NodeReservation$GT$17h1ea9fe3258f50743E_ZN79_$LT$arc_swap..debt..list..NodeReservation$u20$as$u20$core..ops..drop..Drop$GT$4drop17h06b41d45759db406E_ZN4core3ptr7mut_ptr31_$LT$impl$u20$$BP$mut$u20$T$GT$6as_ref17hec601fc01ae0b1e2E_ZN4core3ptr9const_ptr33_$LT$impl$u20$$BP$const$u20$T$GT$6as_ref17h2b16934d7a65b4ebE_ZN4core4cell13Cell$LT$T$GT$3get17h1ee94352da9755d8E_ZN4core4cell13Cell$LT$T$GT$3get17he21b641f2ffecc30E_ZN4core4cell13Cell$LT$T$GT$3set17h5970715363386798E_ZN4core4cell13Cell$LT$T$GT$4take17ha74a485a418e564fE_ZN72_$LT$core..option..Option$LT$T$GT$$u20$as$u20$core..default..Default$GT$7default17hdddad91a7d825813E_ZN4core4sync6atomic11atomic_load17h6f5e199e42e4bdadE_ZN4core4sync6atomic11atomic_load17hcc326f895f15a398E_ZN4core4sync6atomic12atomic_store17h6775a0c4e736977dE_ZN4core4sync6atomic12atomic_store17h71ce22ffffb729a7E_ZN4core4sync6atomic23atomic_compare_exchange17hd2d2eb090b823db3E_ZN4core4sync6atomic27Atomic$LT$$BP$mut$u20$T$GT$21compare_exchange_weak17h079d12a6c60785b5E_ZN4core4sync6atomic28atomic_compare_exchange_weak17h14ee1eec78ea9d0fE_ZN4core4sync6atomic27Atomic$LT$$BP$mut$u20$T$GT$3new17hd3c335be3608627fE_ZN4core4sync6atomic27Atomic$LT$$BP$mut$u20$T$GT$4load17hd741048b7dc5c194E_ZN4core4sync6atomic27Atomic$LT$$BP$mut$u20$T$GT$5store17hd3a8351fece0b576E_ZN4core4sync6atomic27Atomic$LT$$BP$mut$u20$T$GT$7get_mut17h0af4ad3828fdb5b4E_ZN4core5array75_$LT$impl$u20$core..default..Default$u20$for$u20$$u5b$T$u3b$$u20$8$u5d$$GT$7default17ha453e14793ced729E_ZN63_$LT$arc_swap..debt..Debt$u20$as$u20$core..default..Default$GT$7default17hb9fcc4811dad25aeE_ZN4core5slice29_$LT$impl$u20$$u5b$T$u5d$$GT$4iter17had986ad4330c78f2E_ZN4core5slice4iter13Iter$LT$T$GT$3new17h090a3ce1342e9dddE_ZN4core6option15Option$LT$T$GT$14unwrap_or_else17haed191d583d20fa8E_ZN4core6option15Option$LT$T$GT$6expect17h60ca021bede5282cE_ZN4core6option15Option$LT$T$GT$7is_some17hebe5d4cd4820b0aaE_ZN4core6result19Result$LT$T$C$E$GT$3map17h299dbe8def3fee0fE_ZN4core6result19Result$LT$T$C$E$GT$5is_ok17h827ccddc2f1c9d9dE_ZN4core6result19Result$LT$T$C$E$GT$7map_err17hce390abfc528d8f2E_ZN5alloc5boxed16Box$LT$T$C$A$GT$4leak17h4762f059d4e1abbeE_ZN69_$LT$alloc..boxed..Box$LT$T$GT$$u20$as$u20$core..default..Default$GT$7default17h8d595b0fb8ecfdd5E_ZN69_$LT$arc_swap..debt..list..Node$u20$as$u20$core..default..Default$GT$7default17hff7264d2a551c77fE_ZN73_$LT$arc_swap..debt..helping..Slots$u20$as$u20$core..default..Default$GT$7default17h7217f83e19d4074dE_ZN73_$LT$arc_swap..debt..list..LocalNode$u20$as$u20$core..ops..drop..Drop$GT$4drop17hbcd343691805dedaE_ZN8arc_swap4debt4list4Node10fast_slots17h4d64e797ce609cc9E_ZN93_$LT$$RF$arc_swap..debt..fast..Slots$u20$as$u20$core..iter..traits..collect..IntoIterator$GT$9into_iter17hdd094a2c0e54688dE_ZN8arc_swap4debt4list4Node12helping_slot17h4691eb3f79687a66E_ZN8arc_swap4debt4list4Node14reserve_writer17hf27540e99a13a15cE_ZN8arc_swap4debt4list4Node3get17hb671a61f91c7b51aE_ZN8arc_swap4debt4list4Node8traverse17h6d11f71e28ee54e5E_ZN8arc_swap4debt4list9LIST_HEAD17ha9453a00f3ffd6e7E_ZN8arc_swap4debt4list9LocalNode11new_helping17h14b7d31295e9307fE_ZN8arc_swap4debt4list9LocalNode15confirm_helping17habd52a931a9ab730E_ZN8arc_swap4debt4list11THREAD_HEAD29_$u7b$$u7b$constant$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$23__RUST_STD_INTERNAL_VAL17h49f472391cc1119cEDW.ref.rust_eh_personality// 66 `
arc_swap-ec08ea74b5f7d401.arc_swap.222cc81a0dc1998-cgu.0.rcgu.o/
lib.rmeta/ 0 0 0 644 384688 `
ELF·@@GNUÀrust
„Ú#rustc 1.96.0 (ac68faa20 2026-05-25)ÁÀ뉊]!ÜÛê(¹Þ—šên-5be7b69c3ff7b5b8ÁíàÄTËŸ ÜJîÄ)'ß\¥!-3d1337db07d0b3aeÁ¤²XctÔ'ÐÓ©z¨ɽÓ-a4945860e1c53b00Á¤°ð ¾ä-±($²ï=©Ã-7e98a21bfd32b0edÁòÖÀH•‘PIÓHã#£-055f30b747f859b6Árustc_std_workspace_coreÁ­Cçß^ò½èÝ$­Çÿ+Cé-c4878ee60b2242c9ÁŸÃï+Ñ]ŠqB<ÏïW#-8dd1dd90e70d0b6aÁ miniz_oxideÁ€š»J(P>àö÷g\K-1eb618da2918ab7fÁadler2ÁÆ;+Þ®5¥Ìýݰ¦ÛLˆ-f7919172d268e069Á hashbrownÁPäV9ÒÆèÜ"ÊÖVŽ\-0fc2184a5da6723aÁrustc_std_workspace_allocÁs&ØòØy¯s•bæ!‰ýŠ-97e4bf30be240674Á
std_detectÁhŠBîÙºÌI®ËÅš-9dbbf8346ba7ac8bÁrustc_demangleÁûë9´Ç×@Œ’ùXFº-f33013f239bf9f14Ácfg_ifÁÜLhž§Œaã¯>­-0a71c8f33a838301Á addr2lineÁ׎Þ!]8V$É@@-e618e6be60e87ba2ÁgimliÁ¸
°µ~Î1‹Ñt ðÁ€w-1f7768a68858f670ÁobjectÁ
áPÃ?­À¶¼QHJ¥-914cd6a4dbe590d1ÁmemchrÁ›º«8Ór­2Ù $¨ûib-cf21ca6f2bb15dcdÁë
‹ás«LÖ€îâƒ×ɯŒ-ee6f3747e38367f0Á rustversionÁTgÌüÁé¨Cå@Ö'G-f0da710c68354185ÁtestsÁ,Ý[$Ò[ù,ÅF$ºFíOnceCellÁD‡ »experimental-thread-localÁüÏ %í THREAD_HEADÁ\»e»ºüÓd%íù,f$öe¼ù,&$€&Áù,X$…XserdeÁ,ä-»½ ŒÌ-àrw_lockÁ<ô»internal-test-strategiesÁüÉ$àtest_strategiesÁ|ê»ì ü¬$Ü$š.»Ü„ƒ. ArcSwapWeakÁ\©å»Üåinternal_strategiesÁœñõ»ì üªõ$ù,Æ÷$»÷
tests_defaultÁlÿô £æÀaccessÁ 
AccessÁ¥GuardÁ¬¥¡° ¬¥° ¬¥° ¬!¥!° !¬%¥%¤%° %¬*¥*¤*å*´/¥/¤/° /¬4¥4¤4å4´9¥9¤9° 9¬DynGuardÁ>
>¥>ˆ B¥BåB´ DynAccessÁF¥F¬
I¥II¬
AccessConvertÁM
MMˆ Q¥QQ° Q¬ V˜VV¥V£VåV´
]]¥]]æ a£ccc¥c£c° c¬j¥jåj´n¥n° n¬as_rawÁrrrrsealedÁvSealedÁrrAsRawÁy¥yÁr|¥r~¥~Ár¥rƒ¥ƒÁr¥rˆ¥ˆÁr¥r¥Ár¥r ¥ÁcacheÁœ ¥¬žž¥ž¤žæ žarc_swapÁž¬žload_no_revalidateÁž
revalidateÁžØ§§¦ªª¥ª¤ª¬¯¯¥¯¤¯÷´´¥´¤´´¦´¬compile_fail_testsÁdebtÁ¼¼¼¼¼¼¼fastÁÃÃÃÃÃ
DEBT_SLOT_CNTÁÃÉget_debtÁÃË'aÁËËIntoIterÁËê¼helpingÁÐÐÐÐÐÐÐÐÐREPLACEMENT_TAGÁÐGEN_TAGÁÐTAG_MASKÁÐIDLEÁÐSlotsÁÝcontrolÁÝslotÁÝ active_addrÁÝhandoverÁÝ space_offerÁÐã>Ðå½åéåhelpÁè£è¥åinitÁåconfirmÁ¼listÁíííííííííí í
í í í
ííí NODE_UNUSEDÁí NODE_USEDÁí
NODE_COOLDOWNÁí LIST_HEADÁíNodeReservationÁ
þˆíãíNodeÁˆ¯ˆ¨ˆin_useÁˆó ˆactive_writersÁíŽ>ítraverseÁ£start_cooldownÁcheck_cooldownÁreserve_writerÁgetÁ  
fast_slotsÁ helping_slotÁí LocalNodeÁœnodeÁœ¯œ¨í withÁ¡£¡¡ ¡  new_fastÁ  new_helpingÁ confirm_helpingÁ¨ ¨   «£«¥í®ã¼°NONEÁ¼²>¼´payÁµ¥´pay_allÁ·¥·£· º docsÁ¼å¼ limitationsÁ¼patternsÁ¼ performanceÁref_cntÁÁÁÁÁÁÁRefCntÁÇBaseÁÇinto_ptrÁÇas_ptrÁÇfrom_ptrÁÇincÁÇdecÁÁÎ¥ÎÉ ÎÕ Îå Îó ÁÔ¥ÔÉ ÔÕ Ôå Ôó ÁÚ¥ÚÉ ÚÕ Úå Úó strategyÁààààhybridÁääääääääää ä
ä ä ä
äääHybridProtectionÁõ¥õõµ äù¥ùæ ùattemptÁù¸ùå äÿ¥ÿãä¥
from_innerÁ
into_innerÁä¥borrowÁäConfigÁUSE_FASTÁäï$ä¥CfgÁ ProtectedÁ¬  wait_for_readersÁ 䥙%compare_and_swapÁààààDefaultStrategyÁàIndependentStrategyÁàÚ   ¤%£¥£´$£¢$ 
InnerStrategyÁ§¥§¤%§¬§Ç% CaSÁ¬¥¬ù%®àStrategyÁ°¥à²¥²¤àÁ'µ¥à·¥·¤importsÁ 
  
° ٥٤ÙinnerÁݥݤݴ$Ý¢$â¥â¤âåâ´ç¥ç¤ç÷ë¥ë¤ë>ï¥ï¤ï×ó¥ó¤ó×ptr_eqÁ÷É ÷÷
ArcSwapAnyÁû¥û¤ûµ û _phantom_arcÁûŸ"¥¤÷¥¤ã¥¤× ¥¤×
¥¤> ¥¤æ 
with_strategyÁ´$ load_fullÁ¬ÈswapÁù%ŸrcuÁ¡£¡Ø¤š¤£¤ArcSwapÁ¨¥ ª¥ª¤ª from_pointeeÁ
ArcSwapOption稴
°¥°¤°ç.³§°emptyÁ¥ const_emptyÁIndependentArcSwapÁ¹¥¿¤ DirectDerefÁ½
½¥½¤½ˆÂ¥Â¤Â×MapGuardÁÆ˜ÆÆ¥Æ£Æ£Æ
projectionÁÆýΘÎΥΣӘÓÓ¥Ó£ÓƒÙ˜Ù٥٣Ù×MapÁßߥßßã ߘ1ßýææ¥æêê¥êêƒïï¥ïï×
ConstantDerefÁô
ô¥ôˆø¥ú¥úƒý¥ý×¥Öƒ¥¥ˆ¥ˆ¥ï
 ޥާùConstantÁ
¥ˆ!¥"˜¥˜ƒ#¥×$ž¥žÖ%¡¥&£¥£'¦¥¦(©¥©ï
)¬¥¬§®ùCacheÁ°°¥°°cachedÁµµ¥µƒ¹¹¥¹×MapCacheÁ½½¥½½Ó)½˜1ÃÃ¥ÃÃÈÈ¥ÈÈ×ÃLocalÁÍž
ÃÏ>áÑ
ÑˆÓ ÃÕ>Ðà8×
generationÁÐÙ>ÐHandoverÁÛ
ÛˆÐÞ>íßà__rust_std_internal_init_fnÁà â ã__RUST_STD_INTERNAL_VALÁâ å«:¼DebtÁç
爼ê×ÁÁí¥íÉ íÕ íå íó Áó¥óÉ óÕ óå óó ä
DefaultConfigÁù
äûƒäý>äHybridStrategyÁÿ™%ÿ_configÁä ™%ƒä
™%>ºººº





!
$
)
.
3
8
=
E
H
L
U
V
\
a
c
i
m
q
{
|
~


ƒ

Š



£
¤
¥
¦
§
®
´
º
Ê
Ê
æ
ç
ç
è
è
è
ë
ì





š

¡
¦
§
¨
«
«
«
¯
µ
Ê
Ì
Ò
Ø
Þ
ü
ü
ý
ý
þ

ˆ






ª
ª
«
«
®
®
æ
ò
ò
ò
ö
ö
ö
ˆ
Œ
Œ
Œ




œ

ž
Ÿ
¡
¡
¤
¤
Å
Å
Å
Æ
Ø
Þ
Þ
Þ
î
ó
ó
ó
ü
ÿ
ÿ
ÿ



Š
Š




š



 
¥
¥
¨
¨
«
«
®
®
¸
¼
¼
¼
Ç
Ì
Ì
Ì
ë
ë
ë
ñ
÷
ü

Fwy›Ç£§¬°µ¡¥F¥8ØDFØDÌì8ØDFØD Ìì8ØDûû»+þµ ÿå+Ÿ"¾µÆî¸U1rÄD¤ÄD¿c½½¾•0Áˆ —êG¸Ç!ZÄDòEé!½½¾•0Áˆ —êG¸Ç!Z†J†JK‰Jµ 7ŠJphantomÁ7J¤7·0ØQdèÄDçEçEèEGlobalÁ ¿±‡§í#òEûû»+þµ ÿå+Ÿ"¾µÆî¸U1rñFòEÄDé!½½¾•0Áˆ —êG¸Ç!ZòHòHÆõHµ Ñ,öHFÑ,÷H¤Ñ,+átLaû§ÄDÀGòEûû»+þµ ÿå+Ÿ"¾µÆî¸U1rùHòEÄDé!>>?ÕAˆ Æ_å€×-ÄDFÄDMMNÆPˆ Qу‘ßÄDŠ ÆÆà0ˣ̘1Íýwv>ÔAH˜¥£Ø¡K¿c¡Ké!¡KŠ ßß­2ãã ä˜1åýº±‘äyG‚ØDØ¡L¿c¡Lßß­2ãã ä˜1åýº±‘äyG‚äLðKêKöKŠ ôôõË3÷ˆ ub°W–üE.ÄDØãM¿cãMãMÐìãMµßãMãMºãMíßãMãMšeãMé!ãMŠ  5ˆ ÖÏŠ„Ý1<ÄDØO¿cOOÐìOµßOOºOíßOOšeOOÄDw 8ØDyžPØDÈw 8ÙÙ° ÜÓ)±†3ƒ*s/ÁØDÿÿ<­<;ÍñïþøùùúÜ; ²ýË”FZDyÀP°PwÙÙ° ÜÓ)±†3ƒ*s/ÁÄDõPyÛQÄDÈw ÄDy§RÄDw ÄDy¾RÄDذ°ñ6³´–7*­PË€ ¨:äLØD¿cÖRÖRØDê!éÖRäLؽ½Þ7ÁÓ)˜1Ô45_â¤ÿäLØDíL¿cÈS½½Þ7ÁÓ)˜1Ô45_â¤ÿäLØD¦³ÍÍà8Ξ
Ãå0žéh©j³ÑÑҡӈà Žc­pËÒ[LÇL þ¤U³××à8د9ÐÍÄd‡7O³ÛÛÜÍ9݈Р–Ã@XÓ©³ÝݡޮÐß½ÐàÉÐáÜÐâìИ"ÁóróûŒ"ƒýˆí "=ð¡#Z•78³ˆˆ¯íЍíÒíŒó íèí¹ 5nâg&Œ"œœ¬½íž¯íŸ¨ízfñØsÊûo¿cççè×:éˆ ]ìÆë³³YÇñFÇùHÇÛ¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙÄDÇ„¾„¾PinÁ†¾ ˜X$]È=„kt•ñFÇ„¾„¾äY†¾ ˜X$]È=„kt•ùHŒ"õõœ#÷äøµ äóphK˜ÄD£Ñ[ÄD Ñ[ÄDØ¢Q³¢Q¢QØÿÿ<­<;Íñïþø™%³Í\§ÿÿ<­<;Íñïþø™%ÄD¬‘]ÄD°òEÄDµòEÄDé!ÙÙ° ÜÓ)±†3ƒ*s/ÁÄDòEéõ]ÄD³õ]¿cõ]Äcõ]é¬EÄDŒ"¬E¿c¬EÄc¬E³¬EFF!F%û/û9ûQMcßnÂ½ÙÆïßýô¹°È½êçïÙû*½4½B>VÆjôâÙIÎÆæßøôÓÆêßúô˜µ°Ã½ûùÿôžƒô¡ô£ˆô¦ô©Žô¬|

Ù  ~
ƒ
ˆÙ  ª°´½¯°çÙûÏÍÕÑÙ×ÞÛãÝŽˆ²çýùÿëÙûË
®œÿõûΆJÔòHÚۼ턾ó„¾õõùÿÿ²·óÙû
ê¿c
4é!FF$Š Ø8Ðìµßºíßšewyé³ ÇLMŒ"Ç£& §¬°µÄcd™%,ž%
ë!¾D$™%<ž%œ™%$¦%
×JÄDH4¦%²%üñ$A×JÄD\ƒ% ¾D,ù$ ×JB’e²¾e\¯&$´&
HFØDØD$¯&4´&À&ü‡&9>>?ÕAˆ Æ_å€×-ØD\™& Ûf,& \Öf«\Ä'$É'
HFØDÌìØD$Ä'4É'Õ' üœ'9™g\®' “h,¤' /Žh\à($å(
HFØD ÌìØD$à(4å(ñ($ü¸(9™g\Ê( ¤i,À( /Ÿi\*$†*
œÄDòE$*4†**)üÙ)9õ]\ë) ¬E,á) /µjv(Ÿ*  Xè*õ]  ¿cSX
‡din\{¤*ÅÖ¿Ù¿Ú¿«Û¿ˆÜ¿Ý¿Þ¿ˆ‚†f|Â
ŸÈŸÈ ÈErrorÁ O˜éBL F$  c cˆ¢cµ
 `£cbufÁ `àB¤GS
kºksìkd  õ]rªnz±©´¨nìk©†lÆ4ð+ÙÙ° ÜÓ)±†3ƒ*s/ÁñFòEtð+,÷+
ë!Šo_<÷+´ð+,ÿ+
ë!ñFD<ÿ+Œ,.üÐ+< ÄDã+ ÀF,Ù+ ñFŒ ŠoÛFÍo²÷o\´-$¹-
œñFòE$´-4¹-Ĩ- ½ñFòEÆ-3ü€-FÀF\- õG,ˆ-Šo}6q4Á.ÙÙ° ÜÓ)±†3ƒ*s/ÁùHòEtÁ.,È.
ë!·r_<È.´Á.,Ð.
ë!ùHD<Ð.Ý.8ü¡.<­p´. ÈH,ª. ùH ·rØCúr¯¤sŠ\0$‡0
œùHòE$‚04‡0Äö/ ½ùHòE”0=üÎ/FÈH\à/ ÎI,Ö/·r}6»t<Å1žBoxÁ¡ˆˆ¢ˆl }.xÏé!ê!ÄDÀGgs UniqueÁ ž_markerÁ8Åá™-Ýñ¢v§ ïíe¼îËè¿*¢v ¢v
ë!¢v(1Ò1Eü¥1-­p¸1 ¡J,®1 ¢vm áuxáuÌwˆ1Uíw¥”ô8dô8¾e$9äë8Dë8
ªöe?#'áuüâ8& >ÄDŽ9Lüº8T¡J\Ì8”f,Â8áužït¡ˆˆ¢ˆl }.xÏöeÀGÉöeôa¾e·yò­záuù4…FKl…F
ë!K- &$ŒF
HKê!ÄD\4ŒF˜FUüÝE;¡J\ïE æJ,åE ø{Œ ‘K«CÍ{²ó{·@ïFäK
ÙäK,4hýFêK
ÙêK,5èG PhantomDataÁFu\»Ÿ ðK öK_d
Ù…~u~(ºF ÆäKêKðKöK…~¿F¾F]Øk¡Kv ¡KäKz äKêKU êK`…~/ …~:ÂÌ£}ÈÛ}Ý~cêK­äK² (ÁF ºk@ïF ºkäK&ìkhýF 
ºk êK& ìkèG
 ºk
…~& 
2  ìkÅÊ
ýcÛàÐÕ¤©
x }ÆFÞÂl*ð2Ñm:ºkBºk5ìk=‚€Fºkìk •€)ºkûìk ¨€¨€¢±°»‚€ìk³•€ìkõƒìkY½‚áŒÒHêK\äHäK
ë!äK+3ôÒH `
"êK ðKy4<öH\ü²HD öKÅHð,»H•€¿È…}Ê…¼‚€Ä+OŒ…á¿…°HèJäL
ÙäL,4h÷JíL
ÙíL,5ЊK“}Fu\»ŸØDBG
Ùá‡Yb(»J ßäLØDíL½á‡ÀJ¿J]îk¡Lv ¡LäL^ äLiíL9 íLDᇠᇠÄÎÿ†¯·‡~œˆLíL²äL· (ÂJ ºkHèJ ºkäL&ìkh÷J 
ºk íL& ìkЊK
 ºk
á‡' 
3  ìkÆË½‚ØÝÍÒ¡¦
u zÇJóÂl'°‰0Ñm8ºk@ºk3ìk;‰DºkìkÕ‰'ºkùìk é‰ é‰ ±®¹‰ìk±Õ‰ìk¸ìkW½‚ßü›QX ßäLØDíL¤á‡ùQaü²PÇ¡L$ÝPäL4ÀPíLTËPã ˜1D\ÆSäL”ÆS$ÒS
äLðK14ÒS,ùS|˜TêK¼˜T,¨TÛ})<¨TüâSu ÆäLðKêKðKöKÅ…~ÝT ÖTü’SËiüºS£ÆÆà0ˣ̘1Íýwv>ÔAHÃêKðKöK\¤S M,šSÃ,¾S‰mÃ7êK•€;8£;ÌÑÛ}UÃõÐUÄD
ÙÄD,4(ÿT ôÄD„Uü-ãM8 ãMBÄD­pˆYc–“¥(†U 
ºkÐUÄD ìkGL†lX]MjUÿÂlŒê“Ñmºk¢ìk ­pž­p¥Ã±ÐÚÓ•ìkцlëUUmê“%/ÐUÄDÄD',
·ßÄDÄDAFNšUHU
ê“ê“­p­p4¹
AKž—º ÐUÄDÄD',
»ÄD=BJ ŸUŠ œU¿ßÀßÁßLessÁÂßÃßÄß~Å߯ßÇßGreaterÁÈßåºÝÈnûê7nê“vê“~­pæ­pí¹
¢¬ã˜!ÐUÄDÄD',
ïßÄDÄDAFN!«UP!¡UÛ¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙž™Tê“\ê“d­pЭp×{¹
ˆ†›"ÐUÄD
›eÄDù2 "­UB"±U"m-ê“5 @­p~Pº]g¨<³VÄDÀVmü“V-­p¦Vê“,œV -($¢ZÄD–“'/($ÖY ÄD$ÛYš-O8 OBÄD|­pƒYc–“ (%ÝY ºk(%¢ZÄD ìkGL†lX]Mj%âYÂlŒäŸÑmºk¢ìkÓ•œ­p£Á±ÎØÓ•ìkφlé&æY &äYmäŸ%/('¢ZÄDÄD',ž—8=E'ñY¥H'èY
äŸäŸ­p­p4¹
AKž—±((¢ZÄDÄD',ã˜8=E(öY¨(óYž™äŸäŸ­p­p6¹
CM㘳()¢ZÄDÄD',†›8=E)Z«P)øYÅ›äŸäŸ­p­p6¹
CM†›³(*¢ZÄD' *„Z7*ˆZ®"m-äŸ5Ò=­ppMºZdš4³[ÄDt³[,º[–“*<º[ì¥[ ôÄDÈ[qüýZKãM\[äŸ,…[ÄDn­pŠ;–“
ÊØD+#Ä ü„ @ °Pd˜   ØDÕª
<һ

ë!ÅP&.

“ªJã
ü£
@Ȫ
  ÅP,­
Õª¬C¨«µ“ª 
ë!ÛQ   
ÊÄDA# ŠüÀ @ —R  ÛQ ­p8⬡‹­ ó üà 0§R  §R  /

§Rô
üº
:§R
 ¾R
¾RS6X+¸äLÿ†'/H+ÉØD
ÙØD,5(+Œ °äLØD++@¸NÖRY ÖRcäLÖ‰ÞØD²ÕªºŠÿ†
®°ÞäL}(,“  ºkX,¸ 
ºkäL&ìkH,É  ºk
ØD& 
2 ìk
ûc¥ªšŸnsÆ¼Ý Âl褱ðÑm÷ºkþºkðìk÷‰ÿºkÐìk×ÓªßÕªç;±IT‰ìkLÓªìk–³qD÷#¤÷#
ë!äL(!'L€$
ØD¤U\€$Dœ$Ì•$ °äLØD´$ ³$üÀ#t¢üê#JÖR$Û#äLDË#ØD4î# ûû»+þµ ÿå+Ÿ"¾µÆî¸U1rØDŵ)‰BäLæw–7{º•µc¼µjäLãt®%äL•µ&.Â%£üÿ$Cå¶T™%¤±,%‰g6•µŒü(T)
¦äLØDŵ$ü(d)$—)Ì—)”œ)
¥äLØDŵ2¤œ)¶)¤üÕ(aÕªï( ÖRLá(m§¤±~?£¹Ìå¹d÷)ØD‰*¥üÊ)?Õªê)¤±,à) .
dà*ØDäÑ*tÑ*“ª*l“-äLŒ“-•µ(¤]¤]V¦]Á‚]üß3ø¤”&ȪŒª- ¼Àü“-)$¥-
Ü]°P6¼¥-ÄÉ-   lþ- äLÌþ-•µ ( !LŒ.¼µ I
\Œ.\ð-ØDØD
üÆ-\ 1ØD
ü*‹¨.¦üÀ*èü‚-¦
mµ*­ºL«*ȪTÄ*ÕªȪT†- ̼Îå¶×‰õ¼À½À¾ÀË¿ÀÀÀÌÁÀÂÀGÃÀÄÀFÅÀÆÀ×`šÁ¬S øBö¹ØD嶉²Û
cached_ptrÁè
shared_ptrÁêT“ªô•µÅ¢½X•µû¼µØDÄüî=H ½äLØDÜT¼>§üˆ=´œTŒ¨=ÖR$™=ÜT Ÿ=±C\™@$ž@
¤äLØDŵ$™@4ž@œ™@,¥@
ë!ØDM<¥@²@®üî?D °PT„@­ºLö?Õª8¢Ã¯ÕÜÛALÛA
¢äLØDŵDåA,ôA³ü´A@ÖR$ÌAäLD¼A -åÄy-•DÖR
ÙÖR,4h-­DíL·‡'0(-ãC ½äLØDíL-èC-çCCÇQÈS\ ÈSfÖRÙ¤±áíL°Õ‰¸úÅ
·‡ÜÖR}(.êC  ºk.•D 
ºkÖR&ìkh.­D 
ºk
íL& 
2 ìk–³¡¦joÂ.ïCÌÙ Âlä¦ÇìÑmóºkúºkììkó¤±ûºkÌìkÓ Õ‰ÞÕ‰æ:±HS¤±ìkK Êìk–³pŒ†FÜTT˜FÖRŒ˜F$£F¢Ã+4£Fü†F$ d
•"ÜTÕª{3;°FºüãEM âTùE œTLëE ÜTÇìËÕª­­ºË-T¢ÃÒã˵˜/£

´á.á.aã.»Ì-IÜžB2®I8/ Í/–Ð*ïT5°ÍŠDªÍ
DEBT_SLOT_CNTÁ¨0„ 
´³Y*80â
 Ñ
Ö*¤U5øÎkDòÎ|d„°Í”„
/0,øÎ 
³Y0É
£ É0„É 
ÊL££¹ƒ£¹„£þ-'ºˆÉ¬g
Z^  ø„ÀŽx
 Œ
ûM¦Ñ
ž ¦ª È Ä Û  Û¼ ³YáO”æ"  2
$ .
øÎ¤]¤]V¦]Á‚]üß3ø¤”& ¼À¤Ô
–Än3 üÔ"± „Õ ¼ÀĘ
˜ÄB¤:
ŒŸ13ß
 Ê 93ç
‰3Þ
 A3ÿ
 ”×I3‰ !”×I3® # Q3» $!É3­ "#$"ù3è ! % ǽá3Ì  ' Û¼äÈäÈ ArgumentsÁæÈtemplateÁ `çÈÀ `üöMõô]Tdù3Œ]  ù3Œ 
òW%!3­  Q3³ !Y3¿ '§&E)°Í,†+ Š$ +'J*+¼õ
ƒ/)*z(T-$ -.,øÎ„¥ Û¼²Ó,LVÊ
üª · ü÷êü ÁBIüÞðü® üŽù3þ
Œ ù3Ý Ÿ .Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙ²Ó  ¤U È  ïT  °Í¤ËÐî øÎú¦Ñ¦Ñ֦ѭۼݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙú ¦Ñ£H âBMö²ÓÆî! „Õƒ„ÀLðßð„Àå”×”×”×´”ס”×”×{NvnǽȽɽ}ʽ˽NeÁ̽ͽMatchÁBÙe±æµé!3á Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙÓØÔm»ÿÝ3'¾ß0²Ói¸
uµ z®|ž
xù  ´>´ú½âoldÁ½left_valÁ right_valÁ!> %á±±Ð%
Ús³Yá  Ñ¨ £Ò¯ ØÕ~ÚÖ½Ù­ïÚüU]±ÿÊ;”×+:©±0b01Á0b10Á0b11Á¸4Œ8 ªÍ84Å7 ×4Ì7 Ú*îU5°ÍXDªÍiX59 
´„Õ85æ8 Û5í8 ß*£V5„Õ^D®ço&ù=[W X
1?ß
 è£ØD”×d¤X „Õ<¶X
¼ÀÔ¤X $±X ØÕ ?
0l±X 9?ç
‰?Þ
 A?ÿ
 ”×I?‰  ”×I?®  Q?»  É?­ 

ù?è !  ǽá?Ì  Û¼ÓØù?Œ] ù?Œ ½Ù!?­  Q?³  Y?¿ R=\Y „Õ4¬Y  ¼ÀÄ›Y $§Y ØÕ?0d§Y <ÖY ”ÖY  DàY ÛÄÐY  ×} Rùˆž"#Q R#WQ”×5:
ÐbWNTV<«Z |«Z $¶Z Ü $ï\ õ\ ”ç\ <ç\ 
ûÝV8/'-
éFã8l¹Fã8l
¡Gºkü“]) 'ºk /|Â` „Õ4×`  ¼ÀäÂ` $Ò` ØÕ? 0 dÒ` Ü÷` !! \…b #„Õ4b $ ¼ÀÄ…b $b ØÕ#?$0"
db <Éb &´ºb %"&% ¬Þe "Â8li X
\i 
"Çèmÿ8m='EdÍi *'¼Ãi LÃi “ª*&)#üÃi ()|l ,¤]¤]V¦]Á‚]üß3ø¤”& £V4l - ¼Àäl $l 
Ü]£V,r-5+#dl „›m /ƒò4±m 0 ¼Àì›m $¬m Ùò/?00.#d¬m l‰o Y. m Z Y [)„Õ9K \ Z[Z ]\fz ]„ÕZ$
Œ­p 7.ä­p 6 7DÁp Û1Gß
 569Gç
 8 èÇèØD”׉GÞ
 4 58AGÿ
 94”×IG‰  :4”×IG® 
<9QG» 
=:ÉG­ 
;<=
;œôp B.üôp% A
B|Šq Ùü²t$ D„Õ<u E4u F ¼À4žu G ¼Àü²ts „ðt 
šÄDeEUATŠu FTGEC#üðt5 ùGè ! 
> ǽáGÌ  @ Û¼ÓØùGŒ]  ùGŒ ½Ù>!G­ 9QG³ :YG¿ @R?#>´ HCü¬ty HÕ \z NC¬¾|
N •} '„­w Jƒò4Ñw K ¼Àü­w+ ,¾w 
Ý]£VJE+\Äw K=I#Ô¾w \Öx X
 M'ÄÊx \Êx 
ÉØDM<L#$¸XÀë= ÔXÜü½Y»$ cS ‚È‚ÈArgumentÁ„È´ÀbökÏ®ÝWj´T¬Uµ CÕVSäê
«cCUVP'ùN@#áN#
ÜWPùOž"#O(þ} üúV„' '!X!" ^.Ùó! _ ^0 `_=P a `]h baw b % 2.„Õ4«o 3 ¼Àü‰o) ,—o 
—Ä2Ç(do 3<1#Ü—o èù?þ
Œ ù?Ý Ÿ ü‰Yõ$ ü°`æ üóa× üûh› ü°iæ üïk§ üŒmŠ ùGþ
Œ  ùGÝ Ÿ 
üãp³  ü‰zå  ü 
cmËW ÝV,“W ယW d¦W Çè\»W  àÚ ”×h ”×ü , ðß_ „ÀT ”×û ”×ð à ë ã éà!?á  Ëáµ \Y ðßj „À_  1 
§
W
 ÝV
Ȃz
4
\´` ðß
„À
Ñ \÷a ðß „À· s ˆ ØD\ÿh d´i Ȫ Õª °ò\ók  ƒòð„À·°òDm ܃„À{mðßM„À¾ àh”×¢ÆÞ”׫”× ”×t Gogéà!Gá 
\ËáTçp aÖ¿Ù¿Ú¿«Û¿ˆÜ¿Ý¿Þ¿ˆ‚†f|Â
Aðß„À„Àz,Ôu m<܃o„ÀdȪØD)Å éÓØÖ”×+
”×D
·ûK
·ûd
Ο]
„‡i
”×r
 Ùó




Ùó)
1
8
?
F
µwhoÁ¼ storage_addrÁÍ replacementÁÙÏ⤠ãâ ®ŠÉ; new_controlÁ0"Ó‡' replace_addrÁ"( their_spaceÁ+my_spaceÁ .Ïâ=
9ãâ6
:® >
space_addrÁ© Aªˆº
NÀQÀSÀ$žX ÜlÛßÜ ÛF
ÙØÕ:½ÙWØÕóûìúíé»î³ØÕ]ØÕñ
ˆñ
һ9
Ùò´ Ùòc ‰ÿÊ÷Y
½Ùî ØDf ƒú4 Úúä¼üëŒýÄØDˆ  Ëp 
É Ø èy”×õ P =Fܦè7”×ÃÓÜ
 ¤]¤]V¦]Á‚]üß3ø¤”& €X ¼À´è
Ü]€Xz5 üè4ÿ
Ï€XM DÿT Û €X Í 
%
•"êKÊ <
2 ; „å
£TÇè +  , 4 õ
 €X”Ä
è€X2
 ü±'
 â  Û¼ÇèŠ
öC ³
üÜš ä$üÍ©ü²±üÀ£Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙÇèêKÛ¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙÊžõïŽ^„À¥Êœ„” êKƒ‘I „”eܔ컕’±ËcurrentÁ½
 qš
È¥ù|ú¼‘ÆêKƒª’e„”1êK„”>êK¤<¶A Û¼êK”¬AL¬A
‚/Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙêK|h\ÈA
¡ÇèêK ®®£°Ó)¨it§ÅLS¶æXüêAÐ ¤ÇèêK æXÇè á.á.aã.»Ì-IÜžB2®Ø—üÈAóDáA
ÂæX¤ÇèêK¥™¼™Çè¸üáAÚü÷F‰  ¥ÇèêKåHåHæH AccessErrorÁ –úrì$šÙ0Çè¼™ üÈA¹tèF
„\Çèóš¥ÇèêKîš¼™õ«üèF™ †J‡JüÝ@ª ¡ü¤Aã
Çè ˜AêK AÀ™ ¨AØ—ÎÖ¿Ù¿Ú¿«Û¿ˆÜ¿Ý¿Þ¿ˆ‚†f|Â
ÇèóšØʘª‘šd¾™mÒ›­¾™±§±ªíòà̘Ò—qˆšCÄ›ŽÀ™DÀ™K-6à̘DS¡Kʘp̘yà̘ L†Bá.á.aã.»Ì-IÜžB2®Ü”|†BB
‹/Ü”^,B)̆B<B
¦TÊRLB+L¶BÚŸ\ÉBLÉB

ŒÄB Û¼Ê
ü¶B ÀB
ƒ/Ü”m >´ÀB C¾™DC$„C
•/Ø—/ 4„CŒ‚C4C
±TêK E DC<¥C
 ¥C
™"êK æX 
6>ºC¤:üúB@ÇèðA‘šZŒ£$ëA¥ Ü”èÜ”ñ ÚŸ@mDƒ¤žÜ”sÊšêK þBØ—.У侙ÒheadÁ~±¾™±I › Ò T¡¡ ݡ؟¢œÊ¢x£W_ref__fÁ \ÑGLÑG¡¡ŒÌG Û¼ÊäÂGLÂG
‚/Ü”9$¤úG”úG
´ïT¼­H¬­H
´îUüœG» œ ñH
¾™DñH$óHŸ¢
)
 4óHŒñH4úHÊ¢
;  DúHLI d”I   ”I£  ) 2 ÿI€J
 ¥/üüéH—ÇèúFÒ›Zóš øFæXD‘GÚŸ±Ü”×ÊüïT¡îUêK íHØ—EŠ£öŒ£ ¾™Ä±«¾™tmp_nodeÁ}±T ü ¡¡{›¦IĦ&ç¦
Ÿ¢¾Ê¢Ÿ£tæXBæXHŤLœPÚŸ|œP¦P› +,¦Pü³P# !ºküœP;4¬P
°TÊV8ü¬P+ü›P<\òP „Õ<ƒQ ¼ÀÌòP$þPØÕ K 0
lþP1Zß
 
9Zç

 ¦”׉ZÞ
  
AZÿ
”×IZ‰ ”×IZ® QZ» ÉZ­ ùZè !  ǽáZÌ  Û¼ÓØùZŒ] ùZŒ ½Ù!Z­ QZ³ YZ¿ R=L¡Q¤UT¹QïTü¡Q#D«Q
ÊL´Q9Ì«QÊQ¦üÃO‡üùZþ
Œ ùZÝ Ÿ †Ý¬ðOŒ£,ÚOáO Ê$”Pʎܔу¤ðºk¿ àê”×Mðߌ„Àu”×0”× ”×Óûóéà!Zá  ËáÅÕÝqêÝ[ʹÊÁൠä½äÏâãâ~cLQÿ› çó«´ØÕF½ÙIá¯Û;Cÿ<K¦Í”×hƒwÿL—_ÚŸ|—_¡_› +,¡_ü®_#  !ºkü—_;4§_ó«P 2ü§_+ü–_<\í_
„Õ<þ_ ¼ÀÌí_$ù_ØÕ
K0 lù_1cß
  9cç
 «ÇèØD”׉cÞ

 Acÿ

”×Ic‰ 
”×Ic® Qc» Éc­ ùcè !  ǽácÌ  Û¼ÓØùcŒ] ùcŒ ½Ù!c­ Qc³ Yc¿ R=dœ`ÝVd®`ÝVüœ`:$©`
èÇèØDS9d¼`\Ê`ü©`-Ü`«üø]äü‹_Ñùcþ
Œ ùcÝ Ÿ mÉ^Œ£,‘^ʘ^d¤^\¹^á°$_ʮܔñƒ¤ºkß à ”×Csðß²„À”×V”×*”×òéà!cá ¿Ëáäá€á€zʹÊÁñ¨‡õ¹‡úÓ‡þ½ÏâÖãâÏœLˆ`ÿ› %ó«òØÕнÙî¸;Cÿ«û”׬ƒ»ÿùj·e

éj·e
¾æXùjÕúeâÛ¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙ Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙæX æXŸ¾²àùifaà̘ái¢fa+ï⟾Ÿ¾$îc Û¼Ê|äcLäc›¦0¤ƒd”ƒdĦ¼ªd¬ªdç¦üÊc~ œeáùjÔDeæXL¾cÚŸ©Ü”ËïTîU}7›¦ÐĦ²ç¦šùjðe
éjðe
ÐæX/5ùj¦®e  㤾·¿m1Ÿ¾ j¿eùjíÔeùj‚!­e  åÿÂm$Ÿ¾ j!eO jÀ$eùjÛôe⟾ ãÿÂmìåÿÂm¤V¹jäeäùjäZeYjüe
ÇiæXm
á9Ájˆ eÙj¢ e®Å ùjüBejÔ eã·¿e ¿Ä­Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙ ï¾Áj§e ¾i¾iStorageÁÁi»¬iÂiº¬i7·O|5‡æXm5__rust_std_internal_initÁu}¢Å\(k€ ºk°kŸ„Õ!ìkHM†lY^Nkk…ëÂl²ÓÑmœºk£ìk ðß ðߨƱÓÝ¥ÉìkÔ†lî0b11Á„Õ ¼À ¼Àüáù„ Ê÷eVT¿±
[Lü :EüáŽ
Ð[rõµü–ß ²Ó —Rº ¨…¨…Êðß „À
„ÀLµ N{ò±Ê÷"¸ËÖü㌠( ºÄD£ª™m …Ì”× ÁÍüÓ 
¡mºÄDÁÍÊÍØÍ¢> õ%ö%ü¼º
·m…ÌØÁÍ\‚Î ÚÍ)”×2ãÍ;µ C¹‡HÓ‡L‡Î ÁÍÌÁÍÒ˜ ÚÍ „Œ
ËÄD;#$d„4„
ÌÄD+$ü·ä  ”× 
ãÍ0ÚÍ@
L »ÄDÁ̓‘Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙm Œ£”×ãÍÚÍ­p

üŸý¼Ÿ
m»ÄDÁÍùÑÊÒ? î%ï%WºfüùömêÎŒ£ÄDý…ÌÀ­Æ­pÞÿÑÕŠÓ·ÌÒÀ­pÈÚÍÞ”×çãÍðÚÍù®uµ Ú͹‡”×Ó‡!ã͹±QÆÐ®ýÐ~ÓƒÄDDÄDJ _ref__ptrÁ_ref__storage_addrÁ_ref__replacementÁ¬±
„¶ÌÒ”×ãÍüÙ,
«ÁÍÄDr_Eüß&ü¨ &
šœû d€!
 t€!üê %„ê 
ØJ²Ó F%ü¨ h
NÄlÄlIterÁÇlµ ™lÈl
end_or_lenÁ™lÉlöu™lŒœjSž³Yâ±â±OnceÁä±Ó)ÔJ¹s§JE²Ó*Ûüä ,®! 
ÊLð¬ð¬ChainÁó¬¬Ü6ô¬­Ü6r_­koiÖ“ÙìÙL®!
mq 
øŠ¢!Õ
 šŸ
ûMÔÚ
±  º¾ Ê
Ü$¦! Û²ÓÞ#ÚÍ”Ð#Õ#
µÄD$Ð#C
lÕ#$‰% Û¼m š%[$É$­pdÂ$4Â$ýÐ*%bH»üžýü˜ ƒÿѽ ŠÓÕʃýˆí "=ð¡#Z•7mû7ÔÚ“ÙÔìÙˆ²Ó»ÔÚ­Ôچݿ ÔÚËU²ÓúÈ…ÌòÀ­]ÌÒ¨Œ£±”׺ãÍÃÚÍÌ­pÔ
½®kÌÒ¹‡ ”×Ó‡ ã͵ 2 Ú͹°­p _reservationÁA all_slotsÁ<ùÐ ½ú ÐÖîË×{Ø@·ØâØùÙÕÎÚäÛ!êÜ
úÞÊýОúÞØ _ref__localÁ•ÕªÕ‰Õ _ref__valÁ
Ùü'üá
ÉÆãJ%Ìü²T ÆãÈ Æã¹ÆãmeÁEÀã·î㜰
ËÆã¿&Ì«
ÝÆãG#ËÍüûPm  ¥äm\Æãµ ?Šå®µåˆŒµ
ß8ÄDÃ%ܵ§RÖÑü‰M§RñF¾RkÐã5ËæŠ”(lŠ(LŠ(
ÝñF*"üó''ló'ËæÄ(!l®(§R¨)¾R”š)lš)
Þ8ÄD-#ü…)*\…)
¼ñFì‘)%Ã)ÒüÛè üé'Úü¤(Ÿ§RÅpå¾Rí'ñFÒ ñF*mŠñFv¾RÓÐã<µ @µ ¨(ŠïçgËæFßèˆéä”þ)lþ)ßèŒ* –*ÓüÈ)NñF4í)¾RÛ)µ  -ßèm„þ*dþ*
ÿ-ÄD‹+%Ôþ*§Rž+×üÓ*K§R4í*ùHß*¾RkÐã5óëŠÚ3lÐ3LÐ3
ÝùH*"üº3&dº3óëÄÇ3!lô3§Rí4¾RŒà4dà4
þ-ÄD-#üË4)\Ë4
¼ùHä×4%ˆ5Øü£+å ü°3Øüê3ž§R4¼+ïs­+¾R´3ùHÒ ùH*mŠùHv¾RÓÐã<µ @µ î3Š—ígóëF‡î°îäŒÂ5dÂ5‡îÏ5 Ù5Ùü5LùH,²5¾R 5µ  -‡îmœÝ6à6
·TÄDÀ­
ÉÄDÝ6\ä6§ñ „à6üÝ61tñ6
³TÀ­
²—Rll€7ìñ
ìñ6”7Ýü¨6lÀ­dÆ6‰Z´6Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙÀ­Ðã[}šñ âñà\Í74Ð7
©TÄDÍ7DÐ7ÔÍ7Ù7
·T­pÀ­‹­NLÝ7‹­ tÙ7üÍ78tè7âñVl÷7ìñ
ìè7‹8Þü™7rÀ­d¶7 ‰Z£7Ãò¨Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙ­p ÐãbÎó@úóâñâlÒ8<Ö8
Ú—RÒ8LÖ8,$î8 Û¼ÄDüÏ8a„•9\•9ÆÐ¡9 ´9 Û¼ÄDL¶9ßü‰ZL»8…Ì£8ÙÄDµ <©öþÆÐ¥ì„<Ì„<
ÿXñFž<%üí;7lí;Ëæüû;("üí;A§R´<ðüâ:Ò§R4‚;ØZî:¾RjñFZÐã=»ø»ËæãElÙELÙE
ÝØZ*"ü¿E(Ì¿E»ø?ü¨EBl¨EËæü¶E3"dþE§R÷F¾R”éFléFßè(üÔF*\ÔFˆéìàF ’Gñüº<Ø
üŸEóüôEž §R4Ù< ØZÄ<¾R£EñFÌØZ7 ØZQmñF¾RÔÐãDÐãIµ øE–ú»ønËæPßèˆéò”ÁHlÁHßèÏH ü®H&”®H
öXñFB$ÜHòü˜GÄØZ$½G¾R«GñFµ 5ßèŸöýì§ĶK
ÿXùHÁK%ü‘K6d‘KóëüžK("ü‘K@§R×Köü‡JЧR4¦J[“J¾RjùHZÐã=ÿ»óë„UlúTLúT
Ý[*"üàT(ÌàTÿ?üÊTAdÊTóëü×T3"dŸU§R—V¾RŒŠVdŠV‡î(üõU)\õU°îäV ²V÷üÝKÕ
üÁTñü•U §R4ûK [çK¾RÅTùHÌ[7 [QmùH¾RÔÐãDÐãIµ ™UÜ€ÿnóëP‡î°îòŒáWdáW‡îîW üÎW%”ÎW
öXùHB$ûWøü¸VÖ[$ÝV¾RËVùHµ 5‡îŸ¼„„å

ÆÐñ
 üÓ
#
ŒÓ

¼ÄDB$ü©
X
õÄD
ûüÌ »
Ñ[
…Ìå
†Ý
ÃÛÃÛ ManuallyDropÁÅÛ»¬µÜÀ,%*ÄDÁÄDîµ adÆÐî…ú
 ¼À¤È


Ü]—R
7

Ü«


¦
0´°
à‹«
 
ž$†ÝI#'3Eä«
 l²Ó
 ¼À¤Ù

‡ˆ
 2

¤ŒÆ

¡$Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙÑ[Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙˆê)?ÈXM´­?芽n
 
 


…Ì
 Û¼²Ó ô­
L­

ûÄDI=
 (üŸ/
 Û¼Ñ[
ü÷ˆ
ï
…Ì”á
æ
êÜ 
0 
-
$
 Û¼Ñ[üÞ¡
è
…Ì
 Û¼²Ó¤Þ

¹ŒA5#üÐ%
 Û¼Ñ[z
üüÈ ½
ü¾
Ç
ü å
÷ü˺
 Šd†
Σ
¤]¤]V¦]Á‚]üß3ø¤”&À­
À­Â
„À7•¢˜¢™¢lš¢ˆ›¢œ¢[¢ˆe0<#˜èŠ²Ó †ÝC]|²ÓãÀ­
„ÀßÕÑ[ü¤)
…ÌdžݿB…Ì^Ñ[üÕ
…Ìÿ†Ý÷½7storageÁµ 
 Ž .?芹Ÿ È¿
xȈ>öˆ‡ˆ¦šŠ%¹ŒjêÜ
¹Œ

äó
üâ.


§
1üç)

 ¼À¤Ï
$×
‡ˆ
2d×
”Ì
 ü²-


¨
Ç
 8ü·(
5
ü¬3

V
²Ó²Ó
½•L
…Ìüø

êÜ
1 œ„

 «²Ó
…ÌT
 Û¼²Ó üí

¹ŒE9
$üí-


¥Ñ[ÄD
H 
üÓJ
„Ó

¦Ñ[ÄD üä8
 *ú

…ÌŒ·


ÍÄD. #¬"
À­…Ì$¦"
 Û¼²Óü…"&
L…"
¹ŒQ6 $Ë"
ýüÕö
üØó
ü¿Œ
üî½
ü¸ƒ
Ñ[$”
Σ
Ò
Ü
O Ôœó
À­
„À.Ö¿Ù¿Ú¿«Û¿ˆÜ¿Ý¿Þ¿ˆ‚†f|Â
²Ó½•7Q
²Ó{ÄDÆÑ[E…Ì|†Ýt²Ó á…Ìým×…Ìó…ÌÂÀ­Ë†Ý´½*/53 candidateÁ*2 unused_debtÁÃÓ‡°Õ Ý“À‡ˆƒÝ”NêÜ«¹Œ@£—Ò—ö¢˜¬¹ŒRD–#
߆„–#
,Ÿ#

ë!߆1<Ÿ#
܌#
LŒ#
‹­A"…Ì­#
þüß"N
…Ìtó"
Ñ[,é"
À­h­pš ߆»%Jö­ L•$
†Ý„•$
$Ÿ$

äT²Ó24Ÿ$
)´$
I$Ó&
Û²ÓL'
߆ö'/¤ø&
Lø&
‹­K¯'

…Ì”¡'
¦'
êÜ$¡'

0 l¦'
- lì)
߆üÙ)!
”Ù)

ÁÄD 3 $ƒ*
üò#
üÎ&Ê
üî&ª

m„$
Ñ[Lú#
†Ý †Ý¹$¶%
²ÓeÀ­ò&
­p_†Ÿh…Ì!mÄ ߆æo¹µ W¿àŸ&öÆ‹­˜êÜj…¢$+
 Û¼²Ó´¨+
ά+
î…º+
 üø*Q
õÄDÏ+
üÐ*
Ñ[$é*
ÄDÞ*
†Ý߆}µ =î…ü²-§
 L¸-
†Ý„¸-
$Â-
àŸ+4Â-
$´²-
D$£.
Û²ÓLÏ.
߆ö&/ŒÈ.
4È.
ýÐKý.

…Ì”ï.
ô.
êÜ$ï.

0 lô.
. ¨/
 …Ì\¡/
4¡/
¢˜ ) D«1
߆„«1
,´1
ö* <´1
$ܡ1
L¡1

ÝÄDL

#$Ô1

ŒÈ1
\È1

¼Ñ[;  #,ã1

î1
 í1

üã+

.
0<üž.±
ü¾.
üŒ1b
ÄD þ+
Ñ[Dñ+
†Ýí¢$×-
²ÓhÀ­Â.
­pb†Ÿk…Ì#mÉ…ÌåÄD,1
¾R«­p³†ŸÑmJÑ[s¤ôµ Ó)_
=
àŸhö
ýÐßêܰ¢˜hö7²© ú©ËÄDÑ[LÙ2
߆ö'/è2
ˆü¸20
­pÌ2
ëž,Â2
†Ÿg5öuá3
ü(uÜ3
¢Q ¢Q!+vê3
þ8vã3
¢QtrueÁ¸w5
ú\
Ùú\,4(wÕ4
ÿú\wÚ4
-Í\8 Í\Bú\ ú\\f‘°¨¸x‹5

´ú\8xÜ4
ÿú\xã4
-Í\8ú\_F³±pü”7ü
 ÄD¾]ª™Ñ[ Òü„7
|„7

¡Ñ[ÄD¾]DzÕ²w<—9
ü³6ä
Ñ[|ê6
],Â6
Ò<É6
þ²ÄײÌ%)Xõ²´l·7
о]<÷7
ײü×7(
Ì×7

üÄD$ñ7
C+$¥8
 Û¼Ñ[ü´7ƒ
$Å8
üÙ8,
 ײ ÄD¾]mÑ[ÌÒײ üÅ8A
tÊ8

³TÑ[ÄD¾]öµüÊ8<
9
Jü©7ç

Ñ[š7
þ²jŒ£$•7
 Š$­7
 Šô«¶ïÌÒ÷ײŸÒ¨ײ±½Iײ¯_ä劾]ñ´¾¢¶
_ref__storageÁ$÷8
ÌÒ<ý8
ײüÜ8)
ÔÜ8

ýÄDZA)…9
þÑ[Û8
«¶ÌÒŒ£&ײ/Ò8½pÌÒ<ײe¹±
_ref__nodeÁ°·üÏ<"
 ÄD¾]mÄD ˳ײ<=
 ä–=
 üû<E
¬û<

·ÄDÄD¾]þº‰»‘=
L\´=
IÇ=
üœ9«
ü½<Š

mð9
˳,·9
…̾9
Ò<Ó9
Õ»\Á<
‹»ײ"m»Ôšœ–=
SÀâW[Ó‡_¨Ì»$Ò<
‹»<Ü<
ײ”Ò<
$×<

ª]ÄD]Cl×<
üÒ<
Tå<
£—Hdå<
ñ<
4ÄDÑ<
 Õ»MÑ[‹»]˳fײoÒx$¸9
‹»ײ§§¾棗º
_ref__selfÁ°·üÇ?
 *üä?/
üä?
§¾$…@
<@
*ï@
dï@
4ó@

þÄD*Dó@
<ÿ@
 „ÿ@
4‡A

{—R /
D‡A
. 
…Ìüï@
 ©A
?$œB

|B
LB
­
& <áB
„áB
4éB
ÙÁ%DéB
4üB
 ¼À<„C
 ¼Àü²BZ
¬ËB

á]—R<²B
p <óB
XI üËBA
Cü²Bs
,žC

Ð[À­À­q
<žC
1 ªD

„žD
\žD
§ñ7 óD
dóD
4÷D
 Á%
D÷D
üÀDI
üÀD,

«]ÄD$íD
M<E
7 F
d F
4¤F
 Á%D¤F
¤™F
4™F
¢˜<ÆF
? áF
 çF
èF
=;ü
WgwBüÚ?ˆ
ü„BÞ
Ñ[|­?
˳,Ó>
Ò<â>
ÞÁ<ˆ?
ÄDœ?
Ñ[Þ?
w…Ìöëž…ÌÏÀ­Ø ÞÁôÀ­<ˆB
­p¥ Ö¿Ù¿Ú¿«Û¿ˆÜ¿Ý¿Þ¿ˆ‚†f|Â
À­À­TÏÉ]À­´¨ÉÍ„À¢„ÀÀ­ÙÄDm…Ì¿ëžØm9…ÌhëžX]¬•bæ gÀâmnew_rawÁ? §¾· ÁÙÁN‹­ÏÙÁ£áÃ\²Ä§ñ¹ ÁíÅn Á*¢˜ Ñ[ÕÞÁÊÑ[âÞÁ×ÄDÝÄDã\;òEÄD©Ä;Tœ;
¥˜ÍÄD;dœ;®;àüâ:LÄD „;õ],ô:˜Í|leaseÁ:µÍü¨@Ĩ@
¦˜ÍÄD,Á@*ü@E ÙÄDòEØ@áüß?yõ]$þ?ÄD,ñ?˜Í~Ó)5ÆÎœTÛA˜ÍœÛA4æA
¢˜ÍÄD4DæAôAæü»A9­pÎAªn,ÄA ˜Íx7мÚB„ÚB
áÄDòE,ëB(÷Bêü¶BAõ]$ËBÄD,¾BÓ) -ŽÑudíCTíC
´ÄDÄâCTâC
ëõ]ÄDB&€DîüÃC=õ]$ÓCÄDwÒˆ´ÒjdˆE,E
ë!õ]$ˆE<E܈E•E
ÀcÄDFL™Et•E©EòüÈDaÂlLôDªn,ÏDÑmLÖD­p formatterÁ(RªÓÉÖÓ£dµF,ºFªÓ$µF<ºFܵFÂF
ÅcÄDALÆFtÂFÖFöüõEaÂlL¡Fªn,üEÑmLƒF­pÆÓ JªÓ¼­Õ  “IT“I4•I
{×JÉ /D•I «IT«I4­I
{ëÖ0D­I ÃI ëÖ ÆIÏ×l»I<»I
ûëÖA3) ÉIÊI+;ü­H÷ü‹I?ü£I' $ÒH×J ÃH¦× ÉH ëÖ I”fs©Ù §I ¦×KÏ×Ï× ¬R­U¬V­OãÖÍ¡×ö×H¦× ×J&¦×-×J3Â_
&dÇ_TÇ_
´òEü®_& œ®_
ÄDòE[A Ó_
Ú_üŒ_N+;1¬E$Ÿ_ÄD”_ÄD òEÞ|¹!p˜ÛÐÛæÄD¦DÆ`Ô”Æ`<Ï`
Ö]—R1LÏ`œÅ`l aòE¿a…ÌLÄaÔü a.„®a
«òEÄDXJ>ü®a ¡b
…Ì\šb4šb¢˜
) ¶bˆüž`˜ü»`û m°` ¬EL¦`À­¿` À­* ÔMmÎ òE…ÌÒm¨…ÌÃ`µ cšÇݸÞ)¢˜ædóc

ºküÐc0\çc
…dLÐc7Ìçc/\•d$šdµj$•d 4šdd”d ìküÐcQ,Žd
ð`žAœŽdüÐcg4¯d
÷`ND¯d ¼d ½d üŒ
ÂlL¼cùj,—cÑmLžc ã`ã`
DebugTupleÁæ`×µ`ç` µ`è`˵`é`
empty_nameÁµ`ø/wŒ4@<),»ã·½ãÀºkÞìknªnvõ]¢¸ÆÓ½ö‰á µjÔªnìk¸‹âŸ½âtõ]Mõ]S\Ûe$àeµj$Ûe4àe$ÔÛeçe
Åcõ]LLëetçe úeûeü›e`ÂlLÇeùj,¢eÑmL©eªnÆõ]Í"ÆÓ'_µj÷üåËõ]žõ]£dÿfTÿfÒ¼õfLõf
˜ÄDòE=&güÖf<¬E$æfÄDrÒƒþçj|¶hT¶h
ë¬EÄDÁh(Ëh˜üïg\¬E$…hÄDúg¹ -õèu„Ëk\Ëk§ñ×k!œýktýk
Ò]—RŒl&DÅlüåks ûÄDòE?“}Fu\»ŸÄDÞl ÝlüüÁk¬E$ÊiÄD²iòEDºiÀ­ÅkÔòòEϹ.Ÿ"2µ 5§ñVžê6òE©¶m 
 D½mÔ”½m<ÆmÇÝ+LÆmœ¼ml‚nòE¡n…ÌL¦nÔü‚n.n¸ÞNA5ün $Èn 

Œ¼n\¼n
¼¬E
; #ìn …Ì„àn\ànÆÐ )ønü‡mñ ÷n š4ü²mÆ
ÄD ¦m¬ED™mÀ­¼Üßèߨm0ûßq…ÌhÒ`m¬E+…Ìì¤gµ &ÏÇÝý¸ÞšÛîPÆÐ¬Eè\úq$ÿqµj$úq4ÿqôèqŒèq
àÄDòED&ŒrüÁqKÄD Üqùj,Òqõ]3µjžìñ~l§ƒòELºƒÔ짃$µƒ
ªòEÄDJ;|µƒÔЃ ÙÄDòEðƒœü₎üŽƒbõ]\ø‚ùj,ÍL’ƒûßÈÒ¼' protectedÁ2i¡óÖt²…$·…
žÄDòE$²…¼…L·…¤­…$­…
ÝÄDW$È…ü‡…Am¢…ùj,”…ÄD›…mhÄDª$¹'T„õÔ¿õŸ„´†\´†§ñÀ†#DœˆÔ„¯ˆ ¼Àüœˆ$$¥ˆ
Þ]—RIªˆAÜ¥ˆl߈òEþˆ …ÌLƒ‰
Ôü߈.„툸ÞU F
9üíˆ §‰ …Ì„›‰\›‰ÆÐ , »‰žü€†»üª†ü’ˆ© ÄD ž†ùj,Œ†ÄD“†À­®†À­–ˆÒz„Ànméûß.…Ì#Ò…ÌÚhæ kæ mÀânƧñ¿÷ʸÞ[ÆÐlÊ‘òELé‘ÔüÊ‘7„Ø‘
®òEÄDÞÁO@<ô‘ý‘üØ‘)Ô ÙÄDòE­’Ÿü¦ü±‘|õ]ùjÞÁÄDÔ˜ÍLµ‘ûßóÒç<¬•?æ BÊóEÎû<³² \½²$²µj$½²4² ï²$ñ² ªÓ "+<ï² V
•"ÜT­pl2;tï²$÷²
è£ÄDc4÷² ü² ®³ $­³ªÓ % ³³ 
ü–³!„›³
ŸÄDòE­p$–³ ,¬³
U
䛳 ¶³ ܳ$Û³ªÓ%$ã³
,⳪Ó%¬Ó³4Ó³
÷—R­p­p,Ú³4á³ 6<ù³
$¬´ 
¼š´Œš´ìñ: ! ú´  €µ$Þ´ 
Ø´
xŠüÒ²©N á´šµ´Äü®±Ó

,=ä¡aü¯²Òüå²ü‹³ðüųÄD Ó±ùj,¿±ÜT,Ʊõ]rÄDé²Åÿô»Ì<“ÿ­p=ªnEõ]$³­pªn¨ÄD~<ɳ­pªn­pâªnûõ]õ] JQ¼±¿curÁ7æ ÉprevÁ£
swappedÁ°µjMªÓŠÿó¿ÿ¹ªÓhÛ€,ªÓʪӟ˜‚ƒìñõ]Óõ]¦ÜTßõ]åÜTëõ]ÄD ŒÚÄDÚÄ
aùjšöK$ãÄ éÄ>ñĤüÓÞßß­2ãã ä˜1åýº±‘äyG‚ùjã‰é‰„÷Ãùj,çÃé‰ îñۉòlÔÈDÔÈ
“8ÄDÝÈ(ÌÉÈTÉÈ
ëõGñFN(èÈ­üùÇoõG$˜ÈÄDÈñF¹7Ú‹®ˆŒTšÔ$žÔ
觉ZšÔ4žÔÄšÔ¥Ô
·TÄDñFÚ‹YD©ÔÚ‹ l¥ÔüÔ#LÔ
˜Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙñFòE©n¹Ô³ü¬Óûû»+þµ ÿå+Ÿ"¾µÆî¸U1r›ŽòE$ßÓ ÔÓ›Ž5‰Zs¹ŠšÐc•Ž'$„Ö Û¼ñF|úÕLúÕ•Ž2 Öµü·ÕX$ÉÕ›Žl"•Žc|çÜlçÜ
²ÄDüØÜtØÜ
Ò]ÄDC&üÀÜÇ û›ŽõP?“}Fu\»Ÿ›Ž?õPÞ¸ü“Üúûû»+þµ ÿå+Ÿ"¾µÆî¸U1r›ŽõP$±Ü¤]¤]V¦]Á‚]üß3ø¤”&§R%§RRžБd÷‘FQ}
ŒŠБ¢
Š÷‘ç öÜ\“Ý  ›Žü¶ÝFlàÝ  ù$ ÿ¢Q ûÝí û›ŽõP †Þ ˸ɉ“Ú“v§R£¶’ÒõP»¢Q¸ü¶*1 ½ÄDòE¾,F7õ]>Eô§0 >ÄD?&¡J1áu8?ܸD MN)MMNÆPˆ Qу‘ß¾˜`¾˜hoÜ´U ôÄDõ(ãM3ÄD:A´‹Z ÄD(O3ÄD:A¼ì
 ÑÒ%¤U0øÎ8?|9 ÛÜ%£V0„Õ8?ô— ƒ'úÞ3Ê;B´ˆ çè%³Y0„Õ8?r•»¼¼ÁàºÙ÷û¨®¹ÀY4ê0 »p,1¿c½pÂc½t<‰1Äc¾ˆL1 c¿ FmtResultÁL§1ébÀ“}\Å1Á“}ÁíÜ1ëÂr,ð1é!õ 2Ä AtomicPtrÁLŸ2¯]Æ®Dª2¼ÀÇKÊ2†JÈœ 4ä2Ê­2ì2ßËø,‰3yÌñ6,¦3°Í» 4Å3ÇÎÜ;lë3ùÐÜ;úÐ<tú3ÿѤ%L¨4£ÒÁ'É4µÔä'DÎ4°Õ¨&|ó4ž×¿&œ„5ŸØ¤,Ö,¼ü¾‹ü€  Making [`Arc`] itself atomicÁ¡úü¥b_ The [`ArcSwap`] type is a container for an `Arc` that can be changed atomically. Semantically,ÁüˆSP it is similar to something like `Atomic<Arc<T>>` (if there was such a thing) orÁüÜ\Y `RwLock<Arc<T>>` (but without the need for the locking). It is optimized for read-mostlyÁü¹;8 scenarios, with consistent performance characteristics.Áõú„ù
# MotivationÁŠúüŽ_\ There are many situations in which one might want to have some data structure that is oftenÁüîa^ read and seldom updated. Some examples might be a configuration of a service, routing tables,ÁüÐA> snapshot of some data that is renewed every few minutes, etc.Áúü–! In all these cases one needs:Áü¸c` * Being able to read the current value of the data structure, fast, often and concurrently fromÁœœ many threads.Áü°c` * Using the same version of the data structure over longer period of time ‒ a query should beÁü” b_ answered by a consistent version of data, a packet should be routed either by an old or by aÁü÷ EB new version of the routing table but not by a combination, etc.Áü½
:7 * Perform an update without disrupting the processing.Áø
úüü
c` The first idea would be to use [`RwLock<T>`][RwLock] and keep a read-lock for the whole time ofÁüà GD processing. Update would, however, pause all processing until done.Á¨ úü¬ c` Better option would be to have [`RwLock<Arc<T>>`][RwLock]. Then one would lock, clone the [Arc]Áü
a^ and unlock. This suffers from CPU-level contention (on the lock and on the reference count ofÁüò
`] the [Arc]) which makes it relatively slow. Depending on the implementation, an update may beÁüÓB? blocked for arbitrary long time by a steady inflow of readers.Áú ```rustÁü¦# # use std::sync::{Arc, RwLock};ÁüÊ  # use once_cell::sync::Lazy;Áüë]Z # struct RoutingTable; struct Packet; impl RoutingTable { fn route(&self, _: Packet) {} }ÁüÉJG static ROUTING_TABLE: Lazy<RwLock<Arc<RoutingTable>>> = Lazy::new(|| {Áü”+( RwLock::new(Arc::new(RoutingTable))Á });ÁÈúüÌ'$ fn process_packet(packet: Packet) {Áüô?< let table = Arc::clone(&ROUTING_TABLE.read().unwrap());Áä´ table.route(packet);Áü×+( # fn main() { process_packet(Packet); }Á ```Áúüa^ The [ArcSwap] can be used instead, which solves the above problems and has better performanceÁüñUR characteristics than the [RwLock], both in contended and non-contended scenarios.ÁÇú„°ä× # use arc_swap::ArcSwap;Áüô ưü•]ð°üóFC static ROUTING_TABLE: Lazy<ArcSwap<RoutingTable>> = Lazy::new(|| {Áüº+( ArcSwap::from_pointee(RoutingTable)Áß²îúüò'ü²üš)& let table = ROUTING_TABLE.load();ÁäÄõ³š´üç+©´<“Ý´ú¤Ÿ # Crate contentsÁ´úü¸b_ At the heart of the crate there are [`ArcSwap`] and [`ArcSwapOption`] types, containers for anÁü›(% [`Arc`] and [`Option<Arc>`][Option].ÁÄúüÈb_ Technically, these are type aliases for partial instantiations of the [`ArcSwapAny`] type. TheÁü«c` [`ArcSwapAny`] is more flexible and allows tweaking of many things (can store other things thanÁü^[ [`Arc`]s, can configure the locking [`Strategy`]). For details about the tweaking, see theÁüîFC documentation of the [`strategy`] module and the [`RefCnt`] trait.Áµúü¹`] The [`cache`] module provides means for speeding up read access of the contained data at theÁüš  cost of delayed reclamation.Á»úü¿a^ The [`access`] module can be used to do projections into the contained data to separate partsÁü¡YV of application from each other (eg. giving a component access to only its own part ofÁüû=: configuration while still having it reloaded as a whole).Á¹ú”½ # Before usingÁÐúüÔEB The data structure is a bit niche. Before using, please check theÁüš MJ [limitations and common pitfalls][docs::limitations] and the [performanceÁüè KH characteristics][docs::performance], including choosing the right [readÁü´!2/ operation][docs::performance#read-operations].Áç!úüë!b_ You can also get an inspiration about what's possible in the [common patterns][docs::patterns]ÁdÎ" section.ÁÛ"úŒß" # Release 1.9Áñ"úüõ"^[ Unfortunately, several orderings were too weak in the original code (proofs based on wrongÁüÔ#_\ assumptions / wrong reading of the standard). The 1.9 version should fix them, but probablyÁü´$,) introduces some performance degradation.Áá$úüå$_\ I hope to re-design and rewrite from scratch eventually, with less amount of SeqCst needed.ÁÅ%útÉ% # ExamplesÁØ%ú\Ü%„°¼è% use std::sync::Arc;Á€&úÔ„& use arc_swap::ArcSwap;ÁüŸ&  use crossbeam_utils::thread;ÁÀ&úüÄ&<9 let config = ArcSwap::from(Arc::new(String::default()));ÁÜ' thread::scope
úüº
b_ For some cases, it is possible to use [`ArcSwapAny::map`]. If that is not flexible enough, theÁü )& [`Map`] type can be created directly.ÁÇ úüË _\ Note that the [`Access`] trait is also implemented for [`ArcSwapAny`] itself. Additionally,Áü« ^[ there's the [`Constant`] helper type, which is useful mostly for testing (it doesn't allowÁ
reloading).Áš
úŒž
 # PerformanceÁ°
úü´
_\ In general, these utilities use [`ArcSwapAny::load`] internally and then apply the providedÁü”2/ transformation. This has several consequences:ÁÇúüËa^ * Limitations of the [`load`][ArcSwapAny::load] apply ‒ including the recommendation to notÁü­VS hold the returned guard object for too long, but long enough to get consistency.Áü„YV * The transformation should be cheap ‒ optimally just borrowing into the structure.ÁÞú“Éñú„°¼ÃÉü™(% use std::thread::{self, JoinHandle};Áä use std::time::Duration;ÁßúÔãïÉüþ2/ use arc_swap::access::{Access, Constant, Map};Á±úüµSP fn work_with_usize<A: Access<usize> + Send + 'static>(a: A) -> JoinHandle<()> {Áü‰ thread::spawn(move || {Áô© let mut value = 0;ÁüÈ while value != 42 {Áüè%" let guard = a.load();ÁüŽ value = *guard;Áü®&# println!("{}", value);ÁüÕ_\ // Not strictly necessary, but dropping the guard can free some resources, likeÁüµa^ // slots for tracking what values are still in use. We do it before the sleeping,Áü—/, // not at the end of the scope.ÁäÇ drop(guard);Áüä96 thread::sleep(Duration::from_millis(50));Á
 })Áš´½úüÁ'$ // Passing the whole thing directlyÁüéRO // (If we kept another Arc to it, we could change the value behind the scenes)Áü¼IF work_with_usize(Arc::new(ArcSwap::from_pointee(42))).join().unwrap();ÁúüŠ&# // Passing a subset of a structureÁ„±
struct Cfg {Á¬Â value: usize,Áš´Þúüâ@= let cfg = Arc::new(ArcSwap::from_pointee(Cfg { value: 0 }));Áü£UR let thread = work_with_usize(Map::new(Arc::clone(&cfg), |cfg: &Cfg| &cfg.value));Áüù+( cfg.store(Arc::new(Cfg { value: 42 }));ÁÜ¥ thread.join().unwrap();ÁÁúüÅPM // Passing a constant that can't change. Useful mostly for testing purposes.Áü–2/ work_with_usize(Constant(42)).join().unwrap();ÁÝ´4æ,>?FMNß½¾Æôõ“}\ã“}r,ÿé!Kœ†Jït¡Æ¦òH Š» 4ÀÇ
ä'Dݰ »+Tóû
° ,ÿÙÌÕÉ„ôªt‹ž xz´°iÌÌ\,ëOQ@BœòüˆC@ Abstracts over ways code can get access to a value of type `T`.ÁÌúüÐZW This is the trait that parts of code will use when accessing a subpart of the big dataÁü«FC structure. See the [module documentation](index.html) for details.Á¥ÎìÆãüòÍìØD ƒ çü)çü/ÍìÆãØDô¤"é!²ýŒ°"²ýê!ØDT¶"ªý*Äý Ôýwyì¤"üŒ =: A guard object containing the value and keeping it alive.ÁÎ úüÖ [X For technical reasons, the library doesn't allow direct access into the stored value. AÁü¶!\Y temporary guard object must be loaded, that keeps the actual value alive for the time ofÁD—" use.Á,©"ôé#¼È" The loading method.Áä"úüì"_\ This returns the guard that holds the actual value. Should be called anew each time a freshÁ¤Ð# value is needed.Á$ì#Œ ŒÆã²ý ñ#
ÆãØD$ò#ü‹$D¥¡¾Dê!×JT³$Îì×J “$Íì¾D ª$×JÄDL$é!¾DŒ­$ÍìÄD $¾Dac^`TÖ$,Û$öeìñ$$ô$ ¾D¾DÄD ù$
ÄD×J¾D$ú$ü¶%+8Ž¥Žúü »%ÐDTè%,í%™gì‡&$Š& ÐDÐDØD &
8ØD$&üÄ&28¥úü É&ëD  Tý&,'™gìœ'$Ÿ' ëDëDØD ¤'
8ØD$¥'üÙ'98¥""úü Þ'‰E#$$T™(,ž(!!™gì¸($»( ‰E‰EØD! À(!
$8ØD$Á(üõ(>¥&¤''&რú(ÍìòE …)ÇÄD4ý(°òEÄD\ˆ)¬E())EGBDTº),¿)%%õ]ìÙ)$Ü) ¬E¬EÄD% á)%
)ÄDòE$â)ü÷*=¥+¤,,+რü*¦Š ÿ*°òEñF„‚+ÀF-.ê!ë!.0257\»+4À+**ÄD¬Ð+,Ó+ ÀF ÄD* Ù+*
.ÄDòE$Ú+ü,@¥0¤110რ•,¦Š ˜,±Œ„›,õG233$&)+T×,,Ü,//ÀFì€-$ƒ- õGõGÄD/ ˆ-/
3ÄDòE$‰-üÊ-;¥5¤656რÏ-¦Š Ò-°òEùH|Õ-ÈH78ê!ë!80257\Œ.4.44ÄD¬¡.,¤. ÈH ÄD4 ª.4
8ÄDòE$«.üá.>¥:¤;:;რæ.¦Š é.|ì.ÎI<==$&)+T¦/,«/99ÈHìÎ/$Ñ/˜ ˜ÎIÎIÄD9 Ö/9
=ÄDòE$×/·=4ž0D²0¥@@ÎìÄD »0¡JÆ_å€×-?Ažït¡ˆˆ¢ˆl }.xÏé!ê!ÄDÀG¡Jv>¢€”¡J>>
?ÄD²´ÔÆ0>>€”üä0%¥CCÕ“ é0¡JDEê!ë!E\14•1BBÄD¬¥1,¨1 ¡J ÄDB ®1B
EÄD$¯1´ü6üÖ130 An object-safe version of the [`Access`] trait.ÁŠ2úüŽ2`] This can be used instead of the [`Access`] trait in case a type erasure is desired. This hasÁüï2`] the effect of performance hit (due to boxing of the result and due to dynamic dispatch), butÁüÐ3IF makes certain code simpler and possi

ª ªÀPȪƒ ­
ƒ
8ØD
üç
#¥áƒ ì
¶Š
ÛQüŽ +¥áƒ ¶Š4– ÛQŠ{ŠüÀ  « «ÛQÀ­ˆ Ê ˆ
ŠÄD Ì„ ¥ŒŒáƒ §R Ü¡ ¥ŽŽáƒ ¦ §R{Ôà  ¬ ¬§R§R Í 
ÄD Ü÷ ¥áƒ ü ¾R ì–
¥áƒ
¾R”{Ôº

­ ­¾R§R Ä

ÄD
lú,ü)& Caching handle into the [ArcSwapAny].ÁAúüEEB The [Cache] keeps a copy of the internal [Arc] for faster access.ÁúÌ [Arc]: std::sync::ArcÁ,-°½r,¹é!®¼À» 4÷ǘä'D”°»+T©ûš„®käÄ\´çL̃=Œ¢.œóü¶52 Generalization of caches providing access to `T`.Áìúüðb_ This abstracts over all kinds of caches that can provide a cheap access to values of type `T`.ÁüÓb_ This is useful in cases where some code doesn't care if the `T` is the whole structure or justÁŒ¶ a part of it.ÁÈúüÌ&# See the example at [`Cache::map`].Á¥œœçüüóÀúü çü"çü(*,̘ü Loads the value from cache.Á±úü¹ZW This revalidates the value in the cache, then provides the access to the cached value.Á$® ®Æã ®ØD  
ÆãØDü×kŸ¥ ¤¡Ÿ ¡äLê!ç¶Ì„úü ßÍìŵ âé!äLüþ õµ ܷϰŵØDÖR¢£¤¥¦§46jlfhüÀ#üÉ! Creates a new caching handle.Áïúü÷^[ The parameter is something dereferencing into an [`ArcSwapAny`] (eg. either to [`ArcSwap`]ÁüÚ ]Z or [`ArcSwapOption`]). That can be [`ArcSwapAny`] itself, but that's not very useful. ButÁü¼!SP it also can be a reference to it or `Arc`, which makes it possible to share theÁü”"KH [`ArcSwapAny`] with multiple caches or access it in non-cached way too.Áä"úüì"+( [`ArcSwapOption`]: crate::ArcSwapOptionÁüœ# [`ArcSwap`]: crate::ArcSwapÁÇ#äLÖRžžåÄÖZüÿ$$üº$@= Gives access to the (possibly shared) cached [`ArcSwapAny`].ÁD†%¯ ¯ÖR ¯äLê!ž %ž
£äLØDŵ$%äÕ(üÈ%# Loads the currently held value.Áð%úüø%RO This first checks if the cached value is up to date. This check is very cheap.ÁÏ&úü×&_\ If it is up to date, the cached value is simply returned without additional costs. If it isÁü»']Z outdated, a load is done on the underlying shared storage. The newly loaded value is thenÁü(%" stored in the cache and returned.Á$Ü(° °ÖR °ØDž á(ž¢Ã$æ(üÊ)"”Í)± ±ÖR ±ØDž à)žå¹$á)Ä*T *² ²ÖRmž «*ž£¹$°*üˆ=Wü®.LI Turns this cache into a cache with a projection inside the cached value.Áÿ.úü‡/^[ You'd use this in case when some part of code needs access to fresh values of `U`, howeverÁüê/^[ a bigger structure containing `U` is provided by this cache. The possibility of giving theÁüÍ0\Y whole structure to the part of the code falls short in terms of reusability (the part ofÁü®1[X the code could be used within multiple contexts, each with a bigger different structureÁüŽ2WT containing `U`) and code separation (the code shouldn't needs to know about the bigÁ|ê2 structure).Áþ2úl†3
# WarningÁ˜3úü 3YV As the provided `f` is called inside every [`load`][Access::load], this one should beÁüþ3_\ cheap. Most often it is expected to be just a closure taking reference of some inner field.Áâ4úüê4\Y For the same reasons, it should not have side effects and should never panic (these willÁüË5QN not break Rust's safety rules, but might produce behaviour you don't expect).Á¡6út©6“ɼ6ú\Ä6„°ÔÔ6ïÉüó6)& use arc_swap::cache::{Access, Cache};Á¡7ú¬©7 struct InnerCfg {Á´Ã7 answer: usize,Á,Þ7š´è7ú¤ð7 struct FullCfg {Áĉ8 inner: InnerCfg,Á,¦8š´°8úü¸863 fn use_inner<A: Access<InnerCfg>>(cache: &mut A) {Áüó8! let value = cache.load();Áü™941 println!("The answer is: {}", value.answer);Á,Ò9š´Ü9úüä92/ let full_cfg = ArcSwap::from_pointee(FullCfg {ÁÌ›: inner: InnerCfg {Á¼¹: answer: 42,ÁLÕ:óÏ<ã:ß²üï:&# let cache = Cache::new(&full_cfg);Áüš;2/ use_inner(&mut cache.map(|full| &full.inner));ÁÑ;úüÙ;C@ let inner_cfg = ArcSwap::from_pointee(InnerCfg { answer: 24 });Áü¡<1. let mut inner_cache = Cache::new(&inner_cfg);Áü×<  use_inner(&mut inner_cache);Á<ü<Ý´=ÖRÜTœTž¨¦©¨©žÍìÜT “=ÍìâT =³“"ÜT ³ØD|Ï=³ÜT×þ˜" ³âTÜ=
§äLØDŵÜTâTØ`±á`}z|üÀ>§«¥¬¤­«¬­ ìà̃?ØDê!°Pä¬?†á Ë>—áüý> õµ Å>é!ØDü¦?#úü È>·Ï4Ì?·á\Û?ÖR®®:</1egüî? $ñ?´ ´ÖR ´ªSª ö?ª
®äLØDŵ$û?ü¶@w°¥±¤²±²°ìàÌï@úü ¾@†á Á@—áüé@ õµ »@·Ï4’A·á\¡AÖR³ë³"$HJMOä´A$·AäLÖR¯¯
³äLØDŵ/bü¿Dµ¥¤·¸¦¹¸¹·µ ìà̆EµÜT µØD˜" µâTÙE†á ÊD¨þ ÍD¸þ ÐD—áü€E õµ ÄD·Ï4©E·á\¸Eµ“"ÜTæ„|ÌEúü ÇDœTººBD!}ÄãE$æE œT âT´ ëE´
ºäLØDŵÜTâT$ðE´‰--D¡-$¥-ÃÐíçè AtomicUsizeÁ\—„ャœÀˆÁ» 4ƒÇ¼ÂÎË=Û ½À¼¾Ë¾À¼¾Ì=榿À¼¾ÌÀÀ¼¾G=í¬ÁÀ¼¾GÂÀ¼¾F5ç²ÃÀ¼¾FÄÀ¼¾×5Õ¶ÅÀ¼¾×ÆÀ¼¾üƒ;ä¨03"%$¼ÈÍÑÒa$áá.ÃÄØÄlÃÅ×:$¯çÃÇ×:èÃÇËn½ÀÃÆËƒ¾ÀÃÆÌl¿ÀÃÆÌÀÀÃÆGjÁÀÃÆG~ÂÀÃÆFhÃÀÃÆF|ÄÀÃÆ×fÅÀÃÆ×{ÆÀÃÆ„Õ.Œëä‚Ô¶ÃT ¤UÊüª I ¼·¸ ·¤U ¸ïTÛ¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙ ·³YÉ Á Éᯠµ dn®pnüå#þÌÌÝUÍÎÏÈLÉLÊLÏêL$”ËË þ³YËËÄlÄlØÇlµ ™lÈl¶Ø™lÉlöu™lŒœjSžþ³YüÏ$ÝUÝUÉLËË
Ïþ\–¼ÙÚÛÜÝ×ÛÜa$ò4 á.Ðѵ ‚5 ÐÒ‹žLÅ5 ¯]ÐÕĆ\Ð5 „ÄÐÖ×:$ê5 çÐ××:èÐ×» 4û5 ÇÐØÎ˽ÀÐÓË)¾ÀÐÓ
á.íîµ Õ
íïØ
Älíð‹ž ¯]íóĆ „Äíôït¦ íõ FastLocalÁLÇ Íí÷ FastSlotsÁLÛ Ñíø HelpingLocalÁd…
×íú HelpingSlotsÁdœ
Ýíû×:$¶
çíü×:èíü» 4Ç
ÇíýÎËù ½ÀíñË ¾ÀíñÌ÷ ¿ÀíñÌ ÀÀíñGõ ÁÀíñG ÂÀíñFó ÃÀíñF ÄÀíñ×ñ ÅÀíñ× ÆÀíñ„¹
 
ŒÞ
äõ
”š øûè뜖 Ü  Å ®  ˜,“
~
p
MÄÐ

í´î

íÔŠlíüÑ!íñŽÃãƒþƒýˆí "=ð¡#Z•7þ"=ð¡#Z•7ƒ þ€Xç£h„ƒíº¤ç£
ƒþ²íº¤üÂ!8ÁÁÂW‡"”ê ÂÂWm ò
8´ø€X¹ 5nâg&ŠŒ|•$•툈¤U¬ªíˆˆÝVœÅ툈„ÕŒ‚$‚툈•’Ü™t™íˆˆ„Õ¬¹€X´¤Õ€XŽŽ
€X‘šüÜVêK„”£¨š óê³ ö“"êK €Xüù!êKש˜"„”L
ÇèêK±  NPSUÄ® íà ÀXm À 
ÄÇ#tÊ#íÄ Ä€Xm Ù#
$Ú#üû*3t+ŠŀXƒýˆí "=ð¡#Z•7Å ‘+ÐÖ$’+Ìž-¡-íÙ©¡¡4‘.<closure_kind>Á˜<closure_signature>Á˜<upvars>Á˜˜˜ƒ‘Ü”m¢2®¬Ǭå¬mü†;1T”;Æ Æ€XÄlÄlØÇlµ ™lÈl¶Ø™lÉlöu™lŒœjSžÆ³Y Ÿ;Ø$ ;ü„<*d<Ç Ç€X dzY Ÿ<·Ø$ <ܤ=L¶=æXzfñØsÊûožŸ¯ü×>!$×>휜á.á.aã.»Ì-IÜžB2®Û¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙÙ©|­?$­?휜ïT¬÷?<÷?휜îUt‘@æX¡¦§¨«üÝ@<»ºü°@%ü¯@'ü¦@2$ë@êKÇè £¢££¢ ¨š ð@ê³ ó@È"êK ÈæX¼ö@ÈêK§´˜"Çè ŒA
¡ÇèêK±á]_bd4êA¡®¬¤Ǭ¤å¬¤¤¡‘š÷F¡®¬¥Ǭ¥å¬¥¥¡Ò›üÃOBDÑOÉ ÉæXÛ¼ݼÞ¼©ß¼à¼ÛἈcSñŸ«‡zÙ ³Y  ÚO Ȉ$ÛOµ Û—ü³R5\ÁRÊ ÊæX  ÍR Ý“$ÎRµ ÔRüØXŒ|æXË ËæXÖ¿Ù¿Ú¿«Û¿ˆÜ¿Ý¿Þ¿ˆ‚†f|Â
š·š·  ÿX Ý”$€Y5ŽYµ ¢Y$å[¨®¬©Ǭ©å¬©©¨©m²Ó ²Ó4…\¨®¬ªǬªå¬ªª¨ª½•ºüø]„$†^¼ÌÍÎ ÌæX Í€X ÎÇèm £¬¥­¬­ ‘^ ¨š ‹^úü Ž^·Ï4ß^ÉšLò^Üš ú^
«ÇèØD$’^¨‡¹‡€œÓ‡ŠœOQTV¼à`æX¯"¯”þ`$aÏ ÏæXm® †a®
¯$‹a³Y±ä  °°¬¸ ³Y³´³¤Ô  ³Y²²
³ ³Yµ·ü–@¤Ð гY…Ì´¥ ³´áƒ ¨¶Šêܵ Š¥ü¼ˆ…ÌÁÍm´¥¸£¹¸¹´áƒ ÒÍìÁÍ Õ¶Š"ÁÍmÁÍm˜"ÄD Â
·ÄDÁ͵  §¹‡§Ó‡§hj
any time.Áÿ úüƒb _ The `experimental-thread-local` feature can be used to build arc-swap for `no_std` targets, byÁüæ] Z replacing occurences of [`std::thread_local!`] with the `#[thread_local]` directive. ThisÁüÄ H E requires a nightly Rust compiler as it makes use of the experimentalÁü
a ^ [`thread_local`](https://doc.rust-lang.org/unstable-book/language-features/thread-local.html)Áüï
a ^ feature. Using this features, thread-local variables are compiled using LLVM built-ins, whichÁüÑ % " have [several underlying modes ofÁü÷ c ` operation](https://doc.rust-lang.org/beta/unstable-book/compiler-flags/tls-model.html). To addÁüÛ a ^ support for thread-local variables on a platform that does not have OS or linker support, theÁü½
a ^ easiest way is to use `-Ztls-model=emulated` and to implement `__emutls_get_address` by hand,Á as in [thisÁü¯ | example](https://opensource.apple.com/source/clang/clang-800.0.38/src/projects/compiler-rt/lib/builtins/emutls.c.auto.html)Á from Clang.Á¿ úôà  # Minimal compiler versionÁâ úüæ^ [ The `1` versions will compile on all compilers supporting the 2018 edition. Note that thisÁüÅ^ [ applies only if no additional feature flags are enabled and does not apply to compiling orÁ”¤  running tests.Á· úü»% " [`ArcSwapAny`]: crate::ArcSwapAnyÁüá' $ [`ArcSwapWeak`]: crate::ArcSwapWeakÁü‰% " [`load`]: crate::ArcSwapAny::loadÁü¯1 . [`into_inner`]: crate::ArcSwapAny::into_innerÁüá/ , [`DefaultStrategy`]: crate::DefaultStrategyÁü‘3 0 [`SeqCst`]: std::sync::atomic::Ordering::SeqCstÁìÅ  [`Weak`]: std::sync::WeakÁ$³-½¾¿À„ä ¬  Internal details.Á úüb _ While the other parts of documentation are useful to users of the crate, this part is probablyÁü}` ] helpful only if you want to look into the code or are curious about how it works internally.ÁÞ úüâ] Z Also note that any of these details may change in future versions and are not part of theÁüÀ6 3 stability guarantees. Don't rely on anything here.Á÷ úÔû  # Storing the [`Arc`].Á úüš_ \ The [`Arc`] can be turned into a raw pointer and back. This is abstracted by the [`RefCnt`]ÁüúZ W trait and it is technically possible to implement it for custom types (this crate alsoÁüÕY V implements it for [`Rc`] and [`Weak`], though the actual usefulness of these is a bitÁ”¯  questionable).Á úüÆ6 3 The raw pointer is stored inside an [`AtomicPtr`].Áý úü$ ! # Protection of reference countsÁ¦ úüªb _ The first idea would be to just use [`AtomicPtr`] with whatever the [`Arc::into_raw`] returns.Áü] Z Then replacing it would be fine (there's no need to update ref counts). The load needs toÁüëc ` increment the reference count ‒ one still stays inside and another is returned to the caller.ÁüÏ^ [ This is done by re-creating the Arc from the raw pointer and then cloning it, throwing oneÁü® * ' instance away (without destroying it).ÁÙ úüÝ c ` This approach has a problem. There's a short time between we read the raw pointer and incrementÁüÁ
c ` the count. If some other thread replaces the stored Arc and throws it away, the ref count couldÁü¥ a ^ drop to 0, get destroyed and we would be trying to bump ref counts in a ghost, which would beÁœ‡  totally broken.Á úüŸ G D To prevent this, we actually use two approaches in a hybrid manner.Áç úüë [ X The first one is based on hazard pointers idea, but slightly modified. There's a globalÁüÇ
a ^ repository of pointers that owe a reference. When someone swaps a pointer, it walks this listÁü©B ? and pays all the debts (and takes them out of the repository).Áì úüð` ] For simplicity and performance, storing into the repository is fallible. If storing into theÁüÑ^ [ repository fails (because the thread used up all its own slots, or because the pointer gotÁü°\ Y replaced in just the wrong moment and it can't confirm the reservation), unlike the fullÁüT Q hazard-pointers approach, we don't retry, but fall back onto secondary strategy.Áâ úüæb _ The secondary strategy is similar, but a bit more complex (and therefore slower, that's why itÁüÉb _ is only a fallback). We first publish an intent to read a pointer (and where we are reading itÁü¬H E from). Then we actually do so and publish the debt, like previously.Áõ úüùc ` The writer pays the debts as usual. But also, if it sees the intent to read the value, it helpsÁüÝ^ [ along, reads it, bumps the reference and passes it to the reader. Therefore, if the readerÁü¼Y V fails to do the protection itself, because it got interrupted by a writer, it finds aÁü–\ Y ready-made replacement value it can just use and doesn't have to retry. Also, the writerÁüób _ doesn't have to wait for the reader in any way, because it can just solve its problem and moveÁ  on.ÁÞ ú # UnsafetyÁñ úüõa ^ All the uses of the unsafe keyword is just to turn the raw pointer back to Arc. It originatedÁü×d a from an Arc in the first place, so the only thing to ensure is it is still valid. That means itsÁü¼!  ref count never dropped to 0.ÁÞ úüâ] Z At the beginning, there's ref count of 1 stored in the raw pointer (and maybe some othersÁüÀ` ] elsewhere, but we can't rely on these). This 1 stays there for the whole time the pointer isÁü¡` ] stored there. When the arc is replaced, this 1 is returned to the caller, so we just have toÁü‚5 2 make sure no more readers access it by that time.Á¸ ú´¼  # Leases and debtsÁÓ úü×d a Instead of incrementing the reference count, the pointer reference can be owed. In such case, itÁü¼` ] is recorded into a global storage. As each thread has its own storage (the global storage isÁüc ` composed of multiple thread storages), the readers don't contend. When the pointer is no longerÁü  in use, the debt is erased.Á¡ úü¥d a The writer pays all the existing debts, therefore the reader have the full Arc with ref count atÁüŠ ] Z that time. The reader is made aware the debt was paid and decrements the reference count.Áè úœì  # Memory ordersÁ€! úü„!8 5 ## Synchronizing the data pointed to by the pointer.Á½! úüÁ!d a We have AcqRel (well, SeqCst, but that's included) on the swap and Acquire on the loads. In caseÁü¦"^ [ of the double read around the debt allocation, we do that on the *second*, because of ABA.Áü…#O L That's also why that SeqCst on the allocation of debt itself is not enough.ÁüÕ#c ` the *latest* decrement. By making both the increment and decrement AcqRel, we effectively chainÁ¼¹$  the edges together.ÁÑ$ úüÕ$  # Memory orders around debtsÁö$ úüú$[ X The linked list of debt nodes only grows. The shape of the list (existence of nodes) isÁüÖ%U R synchronized through Release on creation and Acquire on load on the head pointer.Á¬& ú
úüÉ

ŽåÜé
 [`Guard`]: crate::GuardÁü… /
×µ
úü¹ 
 # No `Clone` implementationÁÙ
úüÝ c
` Previous version implemented [`Clone`], but it turned out to be very confusing to people, sinceÁüÁ ]
Z it created fully independent [`ArcSwap`]. Users expected the instances to be tied to eachÁüŸ
Q
N other, that store in one would change the result of future load of the other.Áñ
úüõ
F
C To emulate the original behaviour, one can do something like this:Á¼
ú
„°äÌ
ܶüé*
' # let old = ArcSwap::from_pointee(42);Áü”,
) let new = ArcSwap::new(old.load_full());Á”Á
 # let _ = new;Á
Ý´Ü
úüàW
T [`triomphe::ThinArc`]: https://docs.rs/triomphe/latest/triomphe/struct.ThinArc.htmlÁ „‹ ¼ Common use patternsÁúüc` Here are some common patterns one can use for inspiration. These are mostly covered by examplesÁü€JG at the right type in the crate, but this lists them at a single place.ÁËúüÏ# # Sharing of configuration dataÁóúü÷^[ We want to share configuration from some source with rare updates to some high performanceÁüÖRO worker threads. It can be configuration in its true sense, or a routing table.Á©úü­a^ The idea here is, each new version is a newly allocated in its own [`Arc`]. It is then storedÁü'$ into a *shared* `ArcSwap` instance.Á·úü»_\ Each worker then loads the current version before each work chunk. In case a new version isÁü›_\ stored, the worker keeps using the loaded one until it ends the work chunk and, if it's theÁüûXU last one to have the version, deallocates it automatically by dropping the [`Guard`]ÁÔúüØ^[ Note that the configuration needs to be passed through a *single shared* [`ArcSwap`]. ThatÁü·`] means we need to share that instance and we do so through an [`Arc`] (one could use a globalÁ´˜ variable instead).Á¯úü³63 Therefore, what we have is `Arc<ArcSwap<Config>>`.Áêú„°Ìú # use std::sync::Arc;Áü” 41 # use std::sync::atomic::{AtomicBool, Ordering};Á´É  # use std::thread;Áôà  # use std::time::Duration;Á,ÿ ä…
ܶ”¢
 # struct Work;Áüµ
PM # impl Work { fn fetch() -> Self { Work } fn perform(&self, _: &Config) {} }Á,† ñ¬ìŒ  #[derive(Debug, Default)]Áœª  struct Config {Áü¾  // ... Stuff in here ...Á š´å úüé KH // We wrap the ArcSwap into an Arc, so we can share it between threads.Áüµ DA let config = Arc::new(ArcSwap::from_pointee(Config::default()));Áú úüþ 52 let terminate = Arc::new(AtomicBool::new(false));Áü´
! let mut threads = Vec::new();ÁÖ
úüÚ
 // The configuration threadÁüú
 threads.push(thread::spawn({Áü›)& let config = Arc::clone(&config);ÁüÅ/, let terminate = Arc::clone(&terminate);ÁŒõ move || {Áü‡63 while !terminate.load(Ordering::Relaxed) {Áü¾63 thread::sleep(Duration::from_secs(6));Áüõ30 // Actually, load it from somewhereÁü©=: let new_config = Arc::new(Config::default());Áüç)& config.store(new_config);Ál¿ðóÏܪ²úĶ // The worker threadÁ¤Ï for _ in 0..10 {Áüä$! threads.push(thread::spawn({Áü‰-* let config = Arc::clone(&config);Áü·30 let terminate = Arc::clone(&terminate);Á¬ë move || {Áü:7 while !terminate.load(Ordering::Relaxed) {Áü¼-* let work = Work::fetch();Áüê/, let config = config.load();Áüš*' work.perform(&config);ÁŒÅÁÏ¿ð }));Áš´øúÜü // Terminate gracefullyÁü˜-* terminate.store(true, Ordering::Relaxed);ÁÜÆ for thread in threads {Áüâ thread.join().unwrap();Á,š´Ý´úÔ” # Consistent snapshotsÁ¯úü³ZW While one probably wants to get a fresh instance every time a work chunk is available,ÁüŽb_ therefore there would be one [`load`] for each work chunk, it is often also important that theÁüñ[X configuration doesn't change in the *middle* of processing of one chunk. Therefore, oneÁüÍc` commonly wants *exactly* one [`load`] for the work chunk, not *at least* one. If the processingÁü±;8 had multiple phases, one would use something like this:Áíú„°ÌýË«,—ñ¬äܶ¤º # struct Config;Á”ÏŒ­Œâ # impl Work {Áüô%" # fn fetch() -> Self { Work }Áüš*' # fn phase_1(&self, _: &Config) {}ÁüÅ*' # fn phase_2(&self, _: &Config) {}Á # }Áüø;8 # let config = Arc::new(ArcSwap::from_pointee(Config));Áì´ let work = Work::fetch();ÁüÒ let config = config.load();ÁÔò work.phase_1(&config);Áü)& // We keep the same config value hereÁÔ· work.phase_2(&config);ÁÝ´Úú Over this:Áíú„°ÌýË«,—ñ¬äܶ¤ºÍÀ”ÏŒ­Œâ÷Àüô%’Áüš*ÁÁüÅ*õÁ¨Âüø;¹Âì´ ýÂüÒ ! work.phase_1(&config.load());Áüô _\ // WARNING!! This is broken, because in between phase_1 and phase_2, the other thread couldÁüÔ!a^ // have replaced the config. Then each phase would be performed with a different one and thatÁü¶" // could lead to surprises.ÁüÖ"! work.phase_2(&config.load());Á<ø"Ý´€#úü„#" # Caching of the configurationÁ§#úü«#b_ Let's say that the work chunks are really small, but there's *a lot* of them to work on. MaybeÁüŽ$`] we are routing packets and the configuration is the routing table that can sometimes change,Á¼ï$ but mostly doesn't.Á‡%úü‹%c` There's an overhead to [`load`]. If the work chunks are small enough, that could be measurable.Áüï%[X We can reach for [`Cache`]. It makes loads much faster (in the order of accessing localÁüË&
## SpeedsÁÈúüÌZW The base line speed of read operations is similar to using an *uncontended* [`Mutex`].Áü§ZW However, [`load`] suffers no contention from any other read operations and only slightÁü‚VS ones during updates. The [`load_full`] operation is additionally contended only onÁüÙYV the reference count of the [`Arc`] inside ‒ so, in general, while [`Mutex`] rapidlyÁü³ RO loses its performance when being in active use by multiple threads at once andÁü†
`] [`RwLock`] is slow to start with, [`ArcSwap`] mostly keeps its performance even when read byÁìç
 many threads in parallel.Á úü‰ a^ Write operations are considered expensive. A write operation is more expensive than access toÁüë UR an *uncontended* [`Mutex`] and on some architectures even slower than uncontendedÁüÁ C@ [`RwLock`]. However, it is faster than either under contention.Á
úü‰
b_ There are some (very unscientific) [benchmarks] within the source code of the library, and theÁüì
YV [`DefaultStrategy`][crate::DefaultStrategy] has some numbers measured on my computer.ÁÆúüÊb_ The exact numbers are highly dependent on the machine used (both absolute numbers and relativeÁü­c` between different data structures). Not only architectures have a huge impact (eg. x86 vs ARM),Áü‘`] but even AMD vs. Intel or two different Intel processors. Therefore, if what matters is moreÁüòXU the speed than the wait-free guarantees, you're advised to do your own measurements.ÁËúüÏIF Further speed improvements may be gained by the use of the [`Cache`].Áú ## ConsistencyÁ°úü´]Z The combination of [wait-free] guarantees of readers and no contention between concurrentÁü’a^ [`load`]s provides *consistent* performance characteristics of the synchronization mechanism.Áüô`] This might be important for soft-realtime applications (the CPU-level contention caused by aÁüÕ]Z recent update/write operation might be problematic for some hard-realtime cases, though).Á³úü·+( ## Choosing the right reading operationÁãúüçVS There are several load operations available. While the general go-to one should beÁü¾MJ [`load`], there may be situations in which the others are a better match.ÁŒúüZW The [`load`] usually only borrows the instance from the shared [`ArcSwap`]. This makesÁüë\Y it faster, because different threads don't contend on the reference count. There are twoÁüÈYV situations when this borrow isn't possible. If the content gets changed, all existingÁü¢VS [`Guard`]s are promoted to contain an owned instance. The promotion is done by theÁüùa^ writer, but the readers still need to decrement the reference counts of the old instance whenÁüÛ30 they no longer use it, contending on the count.Áúü“c` The other situation derives from internal implementation. The number of borrows each thread canÁü÷]Z have at each time (across all [`Guard`]s) is limited. If this limit is exceeded, an ownedÁüÕ  instance is created instead.Áöúüúa^ Therefore, if you intend to hold onto the loaded value for extended time span, you may preferÁüÜVS [`load_full`]. It loads the pointer instance ([`Arc`]) without borrowing, which isÁü³b_ slower (because of the possible contention on the reference count), but doesn't consume one ofÁü–[X the borrow slots, which will make it more likely for following [`load`]s to have a slotÁüò`] available. Similarly, if some API needs an owned `Arc`, [`load_full`] is more convenient andÁüÓ LI potentially faster then first [`load`]ing and then cloning that [`Arc`].Á !úü¤![X Additionally, it is possible to use a [`Cache`] to get further speed improvement at theÁü€"\Y cost of less comfortable API and possibly keeping the older values alive for longer thanÁtÝ" necessary.Áì"úüð"Žåü#"êöܳ#àšüÏ#%È×üõ#/, [`load_full`]: crate::ArcSwapAny::load_fullÁÜ¥$ÌŒüÁ$ [`Mutex`]: std::sync::MutexÁüá$! [`RwLock`]: std::sync::RwLockÁüƒ%HE [benchmarks]: https://github.com/vorner/arc-swap/tree/master/benchesÁüÌ%RO [lock-free]: https://en.wikipedia.org/wiki/Non-blocking_algorithm#Lock-freedomÁüŸ&RO [wait-free]: https://en.wikipedia.org/wiki/Non-blocking_algorithm#Wait-freedomÁ \¹-<½-Çí
ëÁµ IÁÃKd†JÁÅÆiòHÁÆŠäY:„¾ÁìLlLC]tSOQ;=ô¤üo85 A trait describing smart reference counted pointers.Á¨úü¬a^ Note that in a way [`Option<Arc<T>>`][Option] is also a smart reference counted pointer, justÁÜŽ one that can hold NULL.Áªúü®SP The trait is unsafe, because a wrong implementation will break the [ArcSwapAny]Áü‚" implementation and lead to UB.Á¥úü©`] This is not actually expected for downstream crate to implement, this is just means to reuseÁüŠb_ code for [Arc] and [`Option<Arc>`][Option] variants. However, it is theoretically possible (ifÁüí,) you have your own [Arc] implementation).ÁšúüžXU It is also implemented for [Rc], but that is not considered very useful (because theÁü÷^[ [ArcSwapAny] is not `Send` or `Sync`, therefore there's very little advantage for it to beÁ atomic).Áãú # SafetyÁôúüø`] Aside from the obvious properties (like that incrementing and decrementing a reference countÁüÙb_ cancel each out and that having less references tracked than how many things actually point toÁü¼_\ the value is fine as long as the count doesn't drop to 0), it also must satisfy that if twoÁüœ b_ pointers have the same value, they point to the same object. This is specifically not true forÁüÿ b_ ZSTs, but it is true for `Arc`s of ZSTs, because they have the reference counts just after theÁüâ
`] value. It would be fine to point to a type-erased version of the same object, though (if oneÁüà @= could use this trait with unsized types in the first place).Á úüˆ 41 Methods in this trait must not panic nor unwind.Á½ úüÁ \Y Furthermore, the type should be Pin (eg. if the type is cloned or moved, it should stillÁüž
-* point/deref to the same place in memory).ÁÌ
úÌÐ
Я
 [Rc]: std::rc::RcÁü€# [ArcSwapAny]: crate::ArcSwapAnyÁÇÇçüü¤©ØÆãÇçü*‰¶çü6‰¶ÉÊËÌÍÈÉÊËÌÍÍì¥äÚ¶ÍËÉÌÊüÉ(% The base type the pointer points to.Á$ûÇÇü‡)ü†YV Converts the smart pointer into a raw pointer, without affecting the reference count.Áäúüì\Y This can be seen as kind of freezing the pointer ‒ it'll be later converted back usingÁüÍ# [`from_ptr`](#method.from_ptr).Áõúüý^[ The pointer must point to the value stored (and the value must be the same as one returnedÁüà" by [`as_ptr`](#method.as_ptr).ÁDŠÆã¤äÇÇîãÐãüÒ(ü¶<9 Provides a view into the smart pointer as a raw pointer.Á÷úüÿNK This must not affect the reference count ‒ the pointer is only borrowed.Á4ÕÑ ÑÆã¤äÇ àÇ
ÊÆãÐãÜü‚3ü€^[ Converts a raw pointer back into the smart pointer, without affecting the reference count.ÁãúüëXU This is only called on values previously returned by [`into_ptr`](#method.into_ptr).ÁüÈa^ However, it is not guaranteed to be 1:1 relation ‒ `from_ptr` may be called more times thanÁü®\Y `into_ptr` temporarily provided the reference count never drops under 1 during that timeÁüXU (the implementation sometimes owes a reference). These extra pointers will either beÁüì1. converted back using `into_ptr` or forgotten.Á¢ú¨¬»úüÃ:7 This must not be called by code outside of this crate.ÁDŒôåÆãÇÇŠåµ ü²$ü»*' Increments the reference count by one.Áêúüò;8 Return the pointer to the inner thing as a side effect.ÁµÒ ÒÆã¤äÇ ½Ç
ÌÆãÐã¾±üû%üŒ*' Decrements the reference count by one.Á»úüÃDA Note this is called on a raw pointer (one previously returned byÁüŒ]Z [`into_ptr`](#method.into_ptr). This may lead to dropping of the reference count to 0 andÁüî(% destruction of the internal pointer.Áú¨¬´úü¼:·ÁôåmÇÇ
ÍÆãµ z²üÏ ¥ÏÏრÛñFÐÑÒÓÈÉÊËÒÑÓ/1ÎÎÄDü‰!ñF§RÎÎ
ÑÄDÐã³üÛ Ó ÓñF§RÎ éÎ
ÒÄDÐã`´üÈ)+DÒ)¾RñFÎÎ
ÓÄDµ 7µüš*¥ÕÕრ¦*ùHÖרÙÈÉÊËÙØ×/1LÀ*$Å*ÔÔÄDüÓ* DÖ*ùH§RÔÔ
×ÄDÐãƵü£+4¦+Ô ÔùH§RÔ ±+Ô
ØÄDÐã·ü5*D—5¾RùHÔÔ
ÙÄDµ ß·üÝ5+¥ÛÛრé5¶Š4ì5‰ZÜÝÞßÈÉÊËÞÝß79L6$”6ÚÚ—Rü¨6*D«6‰ZÀ­ÚÚ
ÝÄDÐ㽸ü™7)4œ7Õ Õ‰ZÀ­Ú §7Ú
ÞÄDÐã
ºü84Dš8…̉ZÚÚ
ßÄDµ l»„ë-ü30 Strategies for protecting the reference counts.Á4úü8a^ There are multiple algorithms how to protect the reference counts while they're being updatedÁüšc` by multiple threads, each with its own set of pros and cons. The [`DefaultStrategy`] is used byÁüþc` default and should generally be the least surprising option. It is possible to pick a differentÁ
strategy.Áðúüôb_ For now, the traits in here are sealed and don't expose any methods to the users of the crate.Áü×\Y This is because we are not confident about the details just yet. In the future it may beÁü´]Z possible for downstream users to implement their own, but for now it is only so users canÁü’ choose one of the provided.Á²úü¶a^ It is expected that future strategies would come with different capabilities and limitations.Áü˜b_ In particular, some that are not "tight" in the cleanup (delay the cleanup) or not support theÁüû  compare and swap operations.Áœúü (% Currently, we have these strategies:ÁÉúüÍ74 * [`DefaultStrategy`] (this one is used implicitly)Áü…'$ * [`RwLock<()>`][std::sync::RwLock]Á­ú
# TestingÁ¿úüÃb_ Formally, the [`RwLock<()>`][std::sync::RwLock] may be used as a strategy too. It doesn't haveÁü¦ a^ the performance characteristics or lock-free guarantees of the others, but it is much simplerÁüˆ
c` and contains less `unsafe` code (actually, less code altogether). Therefore, it can be used forÁüì
(% testing purposes and cross-checking.Á úü™ [X Note that generally, using [`RwLock<Arc<T>>`][std::sync::RwLock] is likely to be betterÁüõ [X performance wise. So if the goal is to not use third-party unsafe code, only the one inÁüÑ `] [`std`], that is the better option. This is provided mostly for investigation and testing ofÁü²
@= [`ArcSwap`] itself or algorithms written to use [`ArcSwap`].Áó
úü÷
63 *This is not meant to be used in production code*.Á®úü²ŽåüÒ%È×Dó-䞟 °µY4‹ àዞ¯]àâ» 4ËÇàãÜ;lùàœÜ;úàœ<tžÿà¤ý€ì—p´»a¬ÔõùúÿY4«
 äåí
ëäçë…
ÃÛäèr,ç
é!äéµ ø
äꋞL•
¯]äëÁ'Ú
¬äîŒ'lß
§äï¤%Lî
£äð×:$Œ
çäò×:èäò¬L’
œäóÀ» 4²
Çäô˽Àäì˾ÀäìÌ¿ÀäìÌÀÀäìGÁÀäìGÂÀäìFÃÀäìFÄÀäì×ÅÀäìׯÀäì¤
ð
â½
ÓÖ„Ü
È
ºì
«ä¤

¡¤ƒ
x{TW´¢
Eü»&
„Æ
¥ööრ×
¶Š
Ñ[óphK˜÷ø*,Üè

äõõÕ¶¤‰

äõõ߆ü¢ #
¥úúრ§
¶Š
Ñ[ûüýþüÌ R
á
à…ÌÕ¶Ñ[ùù¹Œµ ÏÂÙÂüÈ J
äÖ× ÖæX ×Ô Šù Ù
ùñ´½†ÇüÕC

äØÙ ØæX ÙÔÑ[ù ç
ù¹½yÌüß""
4â"
äÚ ÚÑ[…Ìù é"
ù Á$ê"
ü±#,
¥áƒ ¶#
¶Š4¹#
Ñ["”ò#
$õ#
Û ÛÑ[mÿ ú#
ÿ
ÄD$ÿ#
ü‡*4
¥ƒƒáƒ Œ*
¶Š4*
Ñ[„¦¥%'ìÐ*
TÓ*
ÄDÑ[
ÄDµ %Òäã+
Tæ+
Ñ[ÄD
ÄD$õ+
üò11
¥áƒ ÷1
¶Š4ú1
Ñ[ˆ¢ˆ´¸2
4»2
Ü ÜÑ[ ÜÄD Â2

ˆÄD$Ã2
„ì2
4ö2
çüüì2e
çüçüŠŠ¤º3
DÀ3
ìˆ4
¢QŒŠ¤¬4
D²4
ü§5[
¥Ž™%Žáƒ ¬5
Íì¾]¯5
¶Š4ê5
¾]4û5
‘]©ª«KMHJt‰6
LŽ6
Ñ[ü³6F
$½6
ÝÞ Ý‘] ÞÔ‘]ÄD© Â6

ÄD¾]$Ã6
[Ù4”7
®¬Ǭå¬þ²Ù8
®¬Ǭ嬫¶üœ9T
„¦9
ßà ß‘]…Ì àÔm ·9

ÄD¾]ÀâÈÝÒÝÏ<
®¬Ǭå¬Õ»üË=;
¥™%˜˜áƒ Ð=
ŽòÛ=
¶Š4Ó=
¦ò4à=
‘]™®*,/1ü
„—>
áâ á‘] âÔÞÁÄDËóšš Ó>
ÍìÞÁ ¨>
yÞÁ—Rì«>
ÄD¾]ÞÁ$Ô>
Û㬕åãæ îãCEd€ª ­   Ĩ%̰ The default strategy.ÁÊúüÎB? It is used by the type aliases [`ArcSwap`][crate::ArcSwap] andÁü‘b_ [`ArcSwapOption`][crate::ArcSwapOption]. Only the other strategies need to be used explicitly.Áôúüø! # Performance characteristicsÁšúüža^ * It is optimized for read-heavy situations, with possibly many concurrent read accesses fromÁü€@= multiple threads. Readers don't contend each other at all.ÁüÁc` * Readers are wait-free (with the exception of at most once in `usize::MAX / 4` accesses, whichÁÌ¥ is only lock-free).Áä¿ * Writers are lock-free.ÁüÜa^ * Reclamation is exact ‒ the resource is released as soon as possible (works like RAII, notÁü¾LI like a traditional garbage collector; can contain non-`'static` data).Áúü\Y Each thread has a limited number of fast slots (currently 8, but the exact number is notÁüì_\ guaranteed). If it holds at most that many [`Guard`]s at once, acquiring them is fast. OnceÁüÌa^ these slots are used up (by holding to these many [`Guard`]s), acquiring more of them will beÁü®)& slightly slower, but still wait-free.ÁØúüÜa^ If you expect to hold a lot of "handles" to the data around, or hold onto it for a long time,Áü¾RO you may want to prefer the [`load_full`][crate::ArcSwapAny::load_full] method.Áúü•c` The speed of the fast slots is in the ballpark of locking an *uncontented* mutex. The advantageÁüùc` over the mutex is the stability of speed in the face of contention from other threads ‒ whileÁüÝb_ the performance of mutex goes rapidly down, the slowdown of running out of held slots or heavyÁüÀC@ concurrent writer thread in the area of single-digit multiples.Áúüˆ b_ The ballpark benchmark figures (my older computer) are around these, but you're welcome to runÁüë ;8 the benchmarks in the git repository or write your own.Á§!úü«!A> * Load (both uncontented and contented by other loads): ~30nsÁüí!b_ * `load_full`: ~50ns uncontented, goes up a bit with other `load_full` in other threads on theÁüÐ"# same `Arc` value (~80-100ns).Áüô"UR * Loads after running out of the slots ‒ about 10-20ns slower than `load_full`.ÁüÊ#MJ * Stores: Dependent on number of threads, but generally low microseconds.Áü˜$IF * Loads with heavy concurrent writer (to the same `ArcSwap`): ~250ns.Áâ$úüæ$%È×ÜŒ%àš|±%õPäÃ,üã%%" Strategy for isolating instances.Á‰&úü&b_ It is similar to [`DefaultStrategy`], however the spin lock is not sharded (therefore multipleÁüð&c` concurrent threads might get bigger hit when multiple threads have to fall back). Nevertheless,ÁüÔ'_\ each instance has a private spin lock, not influencing the other instances. That also makesÁÔ´( them bigger in memory.ÁÏ(úüÓ(?< The hazard pointers are still shared between all instances.Á“)úü—)ZW The purpose of this strategy is meant for cases where a single instance is going to beÁüò)C@ "tortured" a lot, so it should not overflow to other instances.Á¶*úüº*_\ This too may be changed for something else (but with at least as good guarantees, primarilyÁüš+@= that other instances won't get influenced by the "torture").Á4º,œÌ,õP¬¿-4Î-£§¬ø,€.y ¢Yë  ¡á‹žî¯] ¡â» ñÇ ¡ã¾" ä ¡¨&3ž ¡¿&¨Ÿ ¡Ú¦  ¡ä'DŒ8° ¡Ü;Wù ¡œÜ;oú ¡œ<_ÿ ¡,ß-¤ñ-üŒ.!L–.£¥¤¤£çüüŒ.r ÆãØDL¤.úü  .£çü4÷— &çü@÷— ¦¥¦¥¦?A̸.T».ÆãØD££
¥
# ExampleÁ=ú\‰=„°ü™=63 # use arc_swap::{ArcSwap, DefaultStrategy, Guard};ÁÌÔ=Ë«üò=(% # let p = ArcSwap::from_pointee(42);ÁüŸ>41 // Create two guards pointing to the same objectÁ´Ø> let g1 = p.load();Áüó>GD let g2 = Guard::<_, DefaultStrategy>::from_inner(Arc::clone(&*g1));Á|¿? # drop(g2);Á<Ó?Ý´Tæ?ÄDõ]ÝÝŽÑÓ)*çüÜ@5¥ã¤ääãრá@¦Š ì@¶Š4ä@ÅŠ\ï@õ]åæê!ë!æ1368\˜A4AââÄD¬»A,¾Aé éõ] éÄDâ ÄAâ
æÄDòE$ÅAüøA7¥è¤éèéრýA¦Š ˆB¶Š4€BÅŠ\‹Bõ]êëê*,/1̶B$¹BÄDõ]çç
êÄDòEÓ)TèüûBA¥ì¤íìíრ€C¦Š •C³ÄD<ƒC¶Š4CÅŠ\˜Cõ]î´î9;>@¤ÃC<ÆCõ]ëë
îÄDòEü„D=¥ð¤ñðñრ‰D¦Š œD¿cÄD,ŒD¶Š4”DÅŠ\ŸDõ]òÀcò9;>@üÈD5ËDêëì êõ] ë c cˆ¢cµ
 `£còl `àB¤GS
ìÂlï ÏDï
òÄDòE$ÐDÆÓ©éü­EA¥ô¤õôõრ²E¦Š ÇEÄcÄD<µE¶Š4¿EÅŠ\ÊEõ]öÅcö9;>@üõE5øEíîï íõ] î c cˆ¢cµ
 `£còl `àB¤GS
ïÂló üEó
öÄDòE$ýEÆÓ€êü­HW4°H×J¦×É øùúøúùÍìëÖ$·HΟ ½HÍì¦× ÀHy×JëÖ\äHy¦×ëÖ\øH
÷ëÖ×J¦×¬ì­`begacü¹[BüÌIZW An atomic storage for a reference counted smart pointer like [`Arc`] or `Option<Arc>`.Á§Júü«J`] This is a storage where a smart pointer may live. It can be read and written atomically fromÁüŒK;8 several threads, but doesn't act like a pointer itself.ÁÈKúüÌKLI One can be created [`from`] an [`Arc`]. To get the pointer back, use theÁÜ™L [`load`](#method.load).ÁµLúT¹L # NoteÁÄLúüÈL\Y This is the common generic implementation. This allows sharing the same code for storingÁü¥MDA both `Arc` and `Option<Arc>` (and possibly other similar types).ÁêMúüîMHE In your code, you most probably want to interact with it through theÁü·Nc` [`ArcSwap`](type.ArcSwap.html) and [`ArcSwapOption`](type.ArcSwapOption.html) aliases. However,Áü›O`] the methods they share are described here and are applicable to both of them. That's why theÁüüO]Z examples here use `ArcSwap` ‒ but they could as well be written with `ArcSwapOption` orÁŒÚP `ArcSwapAny`.ÁìPú¬ðP # Type parametersÁ†QúüŠQc` * `T`: The smart pointer to be kept inside. This crate provides implementation for `Arc<_>` andÁüîQ`] `Option<Arc<_>>` (`Rc` too, but that one is not practically useful). But third party couldÁüÏRIF provide implementations of the [`RefCnt`] trait and plug in others.Áü™SYV * `S`: Chooses the [strategy] used to protect the data inside. They come with variousÁüóS`] performance trade offs, the default [`DefaultStrategy`] is good rule of thumb for most useÁdÔT cases.ÁáTútåT“ÉôTú\øT„°Ì„UË«äžUܶÜ»U let arc = Arc::new(42);Áü×U&# let arc_swap = ArcSwap::from(arc);ÁüþU&# assert_eq!(42, **arc_swap.load());Áü¥V$! // It can be read multiple timesÁüÊV&ñÓ ñVúìõV // Put a new one in thereÁô“W let new_arc = Arc::new(0);Áü²W,) assert_eq!(42, *arc_swap.swap(new_arc));ÁüßW%" assert_eq!(0, **arc_swap.load());Á<…XÝ´Xú„‘X
# Known bugsÁ¢Xúü¦X`] Currently, things like `ArcSwapAny<Option<Option<Arc<_>>>>` (notice the double Option) don'tÁü‡Y96 work properly. A proper solution is being looked intoÁüÁY74 ([#81](https://github.com/vorner/arc-swap/issues)).ÁùYúüýY?< [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.htmlÁü½ZYV [`from`]: https://doc.rust-lang.org/nightly/std/convert/trait.From.html#tymethod.fromÁü—[! [`RefCnt`]: trait.RefCnt.htmlÁTÄ[¥ü¤ýüýრÏ[¦ŠüÚ[ ¶Š4Ò[ÅŠ\Ý[¬E¾µÆî¸U1rþÿˆ=?B Ú[õP¼Ú\Ú\ûûÔäæ]dæ]ûûêê\¯^D¯^ûûòEü¿^F¥¤ƒƒáƒ Ä^¦Š Ï^¶Š4Ç^³òE<Ò^ÅŠ\Ü^¬E„ë9;>@¼Œ_$_ÄD¬E
ÄDòE¹ÖíüÞ_9¥¤áƒ ã_¦Š î_¶Š4æ_ÅŠ\ñ_¬Eˆ"ˆ*,/1”ž`$¡`ð ð¬Em ¦`
ˆÄDòE$«`üºbO¥Š¤Šáƒ ¿b¦Š ÂbÅŠ\Åb”À ,úb¶Š4‚c¬EŒÀcŒ2479üc5“cñòó ñ¬E ò c cˆ¢cµ
 `£còl `àB¤GS
óÂl —c
ŒÄDòE$˜cÆÓ5ñüÁdS¥Ž¤Žáƒ Æd¦Š ÉdÅŠ\ÌdÑ <ƒe¶Š4e¬EÅc2479ü›e5žeôõö ô¬E õ c cˆ¢cµ
 `£còl `àB¤GS
öÂl ¢e
ÄDòE$£eÆÓùòüÿeP¥¤áƒ „f¦Š ™f¶Š4‡fÒ¾ <fÃÝ <œfÅŠ\¦f¬E”´:<?A¤Öf<Ùf¬E
ÄDòEü–g0¥¤áƒ ›g¦Š ¦g¶Š4žgÅŠ\©g¬E˜šœžŸ¡¤=?BDüïg8ìÍg Constructs a new storage.ÁögÄD¬EÃÝ <Ÿhþç¹;ôüi1üÑhGD Constructs a new storage while customizing the protection strategy.Ál¤iÄDòE¬EÐÛ¹Ÿ"mõü‡m ôäl Extracts the value inside.ÁTŽm¬EÄD
šÄDòE$mäÁq¤þn Loads the value.Á—oúüŸoQN This makes another copy of the held pointer and returns it, atomically (it isÁüõoPM safe even when other thread stores into the same instance at the same time).ÁÊpúüÒpJG The method is lock-free and wait-free, but usually more expensive thanÁÜ¡qÕÈ LÈq÷ ÷¬EÄD Òq
ÄDòE$Óqüâ‚!ü’r52 Provides a temporary borrow of the object inside.ÁÌrúüÔrZW This returns a proxy object allowing access to the thing held inside. However, there'sÁü³s^[ only limited amount of possible cheap proxies in existence for each thread ‒ if more areÁü–tXU created, it falls back to equivalent of [`load_full`](#method.load_full) internally.Áótúüût]Z This is therefore a good choice to use for eg. searching a data structure or juggling theÁüÝu]Z pointers around a bit, but not as something to store in larger amounts. The rule of thumbÁü¿v[X is this is suited for local variables on stack, but not in long-living data structures.ÁŸwúŒ§w # ConsistencyÁ½wúüÅw[X In case multiple related operations are to be done on the loaded value, it is generallyÁü¥x\Y recommended to call `load` just once and keep the result over calling it multiple times.Áü†y_\ First, keeping it is usually faster. But more importantly, the value can change between theÁüêyZW calls to load, returning different objects, which could lead to logical inconsistency.ÁüÉz:7 Keeping the result makes sure the same object is used.Áˆ{ú\{„°ä {ܶ”Á{ struct Point {ÁŒØ{ x: usize,ÁŒî{ y: usize,Á,„|š´Ž|úü–|)& fn print_broken(p: &ArcSwap<Point>) {ÁüÄ|NK // This is broken, because the x and y may come from different points,Áü—}>; // combining into an invalid point that never existed.ÁüÚ}&# println!("X: {}", p.load().x);Áü…~JG // If someone changes the content now, between these two loads, weÁÌÔ~ // have a problemÁüò~&# println!("Y: {}", p.load().y);Á,š´§úü¯*' fn print_correct(p: &ArcSwap<Point>) {ÁüÞMJ // Here we take a snapshot of one specific point so both x and y comeÁì°€ // from the same one.ÁìÒ€ let point = p.load();Áüô€# println!("X: {}", point.x);Áüœ# println!("Y: {}", point.y);Áš´üÎ<9 # let p = ArcSwap::from_pointee(Point { x: 10, y: 20 });ÁÄ # print_correct(&p);Á¼¬‚ # print_broken(&p);Á<Ȃݴ$邸 ø¬Eõ] j$ï‚܇…üöƒ,) Replaces the value inside this instance.Á§„úü¯„SP Further loads will yield the new value. Uses [`swap`](#method.swap) internally.Á,Ž…ù ù¬EÄDm ”…
ÄDòE$•…¹úü€†üÎ…-* Exchanges the value inside this instance.Á$‡†ú ú¬EÄDÄD Œ†„õ$æ [üü¦|üÁ‰30 Swaps the stored Arc if it equals to `current`.Áù‰ú
,ÓŸñ¬üÝŸ'ó“
܉ ŽËÄ© ãÌüÆ :7 scope.spawn(|_| cnt.rcu(|inner| **inner + 1));ÁL…¡óÏ„“¡…Ðü¨¡%" assert_eq!(10, *cnt.load_full());Á<Ò¡Ý´Þ¡úüæ¡[X Due to the retries, you might want to perform all the expensive operations *before* theÁüÆ¢^[ rcu. As an example, if there's a cache of some computations as a map, and the map is cheapÁü©£LI to clone but the computations are not, you could do something like this:Áú£ú\‚¤„°ü’¤$! # use std::collections::HashMap;Á,»¤ñ¬äŤܶüæ¤ ư,‹¥ñ¬ü•¥1. fn expensive_computation(x: usize) -> usize {ÁüË¥MJ x * 2 // Let's pretend multiplication is *really expensive expensive*Á,¦š´§¦úü¯¦'$ type Cache = HashMap<usize, usize>;ÁÛ¦úüã¦JG static CACHE: Lazy<ArcSwap<Cache>> = Lazy::new(|| ArcSwap::default());Á²§úüº§.+ fn cached_computation(x: usize) -> usize {Áüí§! let cache = CACHE.load();Áü“¨-* if let Some(result) = cache.get(&x) {ÁÜŨ return *result;ÁLå¨óÏüó¨+( // Not in cache. Compute and store.Áü£©HE // The expensive computation goes outside, so it is not retried.Áüð©.+ let result = expensive_computation(x);ÁÜ£ª CACHE.rcu(|cache| {ÁüêHE // The cheaper clone of the cache can be retried if need be.Áü«30 let mut cache = HashMap::clone(&cache);ÁüÈ«$! cache.insert(x, result);ÁŒñ« cacheÁ\‡¬ÏÌt—¬ resultÁ,ª¬š´´¬úü¼¬+( assert_eq!(42, cached_computation(21));Áüì¬+±¦
<œ­Ý´¨­ṵ́­ # The cost of cloningÁέúüÖ­\Y Depending on the size of cache above, the cloning might not be as cheap. You can howeverÁü·®]Z use persistent data structures ‒ each modification creates a new data structure, but itÁü™¯[X shares most of the data with the old one (which is usually accomplished by using `Arc`sÁüù¯96 inside to share the unchanged values). Something likeÁü·°[X [`rpds`](https://crates.io/crates/rpds) or [`im`](https://crates.io/crates/im) might doÁ”—± what you need.Áµ±ý ý¬EÜTÄD£¢£¢£ ¿±ÍìÅÿ ¹±¨þ ¼±ü“"ÜT üÄDtê±üÜTí
˜"Åÿ ÷±æÅÿÄD<…²„Œ
4™²
¡ÄDòEÅÿÜT$À±± ʱŽüÓÃxü‡µGD Provides an access to an up to date projection of the carried data.ÁÓµú„Ûµ¤¤ðµúüøµ^[ Sometimes, an application consists of components. Each component has its own configurationÁüÛ¶MJ structure. The whole configuration contains all the smaller config parts.Á­·úüµ·UR For the sake of separation and abstraction, it is not desirable to pass the wholeÁü¸]Z configuration to each of the components. This allows the component to take only access toÁŒñ¸ its own part.Á‡¹úì¹ # Lifetimes & flexibilityÁ±¹úü¹¹^[ This method is not the most flexible way, as the returned type borrows into the `ArcSwap`.Áüœº_\ To provide access into eg. `Arc<ArcSwap<T>>`, you can create the [`Map`] type directly. SeeÁÔ€» the [`access`] module.ÁŸ»úŒ§»ðä½»úüÅ»VS As the provided function is called on each load from the shared storage, it shouldÁü ¼^[ generally be cheap. It is expected this will usually be just referencing of a field insideÁ”ƒ½ the structure.Áš½út¢½“ɵ½ú\½½„°¼Í½ÃÉé½úÔñ½ïÉü¾! use arc_swap::access::Access;Á¶¾ú„¾¾ó¬Ó¾¶ó,í¾š´÷¾úüÿ¾52 fn print_many_times<V: Access<usize>>(value: V) {ÁĹ¿ for _ in 0..25 {ÁüÖ¿%" let value = value.load();Áü€À# println!("{}", *value);ÁL¨ÀóÏ,¶Àš´ÀÀúüÈÀ96 let shared = ArcSwap::from_pointee(Cfg { value: 0 });Áü†Á0- let mapped = shared.map(|c: &Cfg| &c.value);Áü»Á(% crossbeam_utils::thread::scope(|s| {ÁüèÁ/, // Will print some zeroes and some twosÁüœÂ.+ s.spawn(|_| print_many_times(mapped));ÁüÏÂ>; s.spawn(|_| shared.store(Arc::new(Cfg { value: 2 })));Áü’Ã0- }).expect("Something panicked in a thread");Á<ÇÃÝ´ÚÃÿ ÿ¬Eé‰ßß­2ãã ä˜1åýº±‘äyG‚ؾ
ã‰é‰š¥£¦§¥¦§ çÃÍì㉠Þã³ áÃÍìé‰ äÃþ"é‰ þã‰dÄþ鉶À
˜" þöK§ÄØé‰,¬Ä¬Eã‰LÁÄ
¤ÄDòEã‰öKé‰$èñ¸º¼µ·œŠÆüõÄ  An atomic storage for `Arc`.Á–ÅúüšÅC@ This is a type alias only. Most of its methods are described onÁüÞÅ+( [`ArcSwapAny`](struct.ArcSwapAny.html).Á<“Æ¥©©áƒ ›Æûû»+þµ ÿå+Ÿ"¾µÆî¸U1rñFõPMOüµÆ2¥«¤¬«¬áƒ ºÆ¦Š ½Æ±Œ„ÀÆõG­!#üùÇAüîÆA> A convenience constructor directly from the pointed-to value.Á´Çúü¼Ç85 Direct equivalent for `ArcSwap::new(Arc::new(val))`.Ád€ÈÄDõGªªÃÝ <²È
­ÄDòE¹Ï̹ÎüìÈ(% An atomic storage for `Option<Arc>`.Á•Éúü™Éa^ This is very similar to [`ArcSwap`](type.ArcSwap.html), but allows storing NULL values, whichÁüûÉ! is useful in some situations.ÁÊúü¡ÊC@ This is a type alias only. Most of the methods are described onÁüåÊ_\ [`ArcSwapAny`](struct.ArcSwapAny.html). Even though the examples there often use `ArcSwap`,ÁüÅËDA they are applicable to `ArcSwapOption` with appropriate changes.ÁŠÌútŽÌ“ÉÌú<¡ÌÝ´¼©ÌÃÉüÁÌ ÇÆâÌúüæÌ+( let shared = ArcSwapOption::from(None);Áü’Í*' assert!(shared.load_full().is_none());Áü½Í74 assert!(shared.swap(Some(Arc::new(42))).is_none());ÁüõÍ;8 assert_eq!(42, **shared.load_full().as_ref().unwrap());Á<±ÎÝ´lÂÎ¥¯¯áƒ ÐΉ“
üòÎB¥±¤²±²áƒ ÷Î¦Š úΰòE›ŽÄýγµ,.02ü¬ÓUü»Ï?< A convenience constructor directly from a pointed-to value.ÁÿÏúü‡Ð1. This just allocates the `Arc` under the hood.Á½ÐútÅÐ“ÉØÐú\àЄ°üðÐ ÇÆ•ÑúüÑHE let empty: ArcSwapOption<usize> = ArcSwapOption::from_pointee(None);ÁüêÑ$! assert!(empty.load().is_none());Áü“ÒJG let non_empty: ArcSwapOption<usize> = ArcSwapOption::from_pointee(42);ÁüâÒ96 assert_eq!(42, **non_empty.load().as_ref().unwrap());Á< ÓÝ´d³Ó °§´´°Íì  ÀÓæ ‰Z|ÃÓÃÝ <ùÓ
³ÄDòE ¹j9;ü·Õ4ü¿Ô1. A convenience constructor for an empty value.ÁõÔúüýÔ52 This is equivalent to `ArcSwapOption::new(None)`.Á,¾Õ°°ÃÝ <ãÕ
µÄDòEē֥··áƒ ˜Ö‰“¸ ü“Ü"ü²Ö%" A const-fn equivalent of [empty].ÁÜÖúüäÖ_\ Just like [empty], this creates an `None`-holding `ArcSwapOption`. The [empty] is, however,ÁüÈ×^[ more general ‒ this is available only for the default strategy, while [empty] is for anyÁü«Ø=: [Default]-constructible strategy (current or future one).ÁíØúôõØ [empty]: ArcSwapAny::emptyÁ˜Ùút Ù“ɳÙú\»Ù„°ÌËÙË«üéÙ" # use arc_swap::ArcSwapOption;ÁüÚLI static GLOBAL_DATA: ArcSwapOption<usize> = ArcSwapOption::const_empty();ÁáÚúüéÚ*' assert!(GLOBAL_DATA.load().is_none());Áü˜Û*' GLOBAL_DATA.store(Some(Arc::new(42)));ÁüÇÛ;8 assert_eq!(42, **GLOBAL_DATA.load().as_ref().unwrap());Á<‡ÜÝ´\ Ü‰“
¸ÄDôËáü‘ÞSP An atomic storage that doesn't share the internal generation locks with others.ÁåÞúüéÞ`] This makes it bigger and it also might suffer contention (on the HW level) if used from manyÁüÊßQN threads at once. On the other hand, it can't block writes in other instances.Áœàúü à85 See the [`IndependentStrategy`] for further details.Á4Âá”Ô᥺ºáƒ çáÉÃ

tÝå êå ìå ùô òå Žæ , óå8Ð $ôå& øå8¼,úå$ ÿå, æ8Ÿ"D‚æ& Šæ8´Œæ*æ “æ öô+ æ žæ ¨æ8âŸæ ¢æ §æ8$£æ8²æ, ¶æ8Ð $·æ ¼æ ðôà8#Êæ8¤,Îæ'Óæ8Ó$4Õæ'Ûæ8ToOwnedÁ<Ýæ% äæ8#òæ8¤,öæ'ûæ8stringÁ4ýæ'ƒç8ß4…ç% ‹ç8#™ç8¤,ç'¢ç8Á¤ç'§ç8ö©ç% ¬ç8#ºç8í$¾ç'Âç8ç$Äç'Èç8atomicÁ4Êç'Ðç Òç äç8$Óç$ ×ç8Ć\Ùç% åç8#ôç8adaptive_barrierÁ„øç'ˆè Šè è8BarrierÁ<‹è$ ’è8 PanicModeÁL”è% žè8#¬è8crossbeam_utilsÁ|°è'¿è8Š4Áè% Çè8#Öè8,Úè'ßè
áè% âè8,ñè8
ITERATIONSÁT÷è& é8¬,ƒé ‰é710Á‹é% é+ œé é ¯é8«,žé £é ®é8±T¤é8!$ðé8AsÁõé ÷é8¥ øé ùé ûé8»+Týé ‡ê8Kˆê ‹ê8¥ Œê ê$ Žê, ê8Ÿ"D‘ê ™ê% šê+ ¨ê ©ê »ê8«,ªê ¯ê ºê8±T°ê8!$üê8AsoÁë „ë8¥ …ë †ë ˆë8»+TŠë ”ë8¬4•ë ›ë8Kœë Ÿë8¥  ë¡ë$ £ë, ¥ë8Ÿ"D¦ë ®ë% ¯ë<R Similar to the one in doc tests of the lib, but more times and more intensive (weÁü¾ëU< want to torture it a bit).Áô ì+ Ëì Ìì Ñì8$Íì+ ßì àì ÷ì8äDáì éì öì8µ $êì$ îì8Á4ðì8 ·í8publishÁ<ºí Áí Âí Äí ó÷8,Öí8READERSÁ<Üí& ãí8¬,åí ëí7Š íí% îí8
€î8 „î8†î7ˆ ‰î!Šî8Çæ
TŒî —î å÷08­î8configÁ4±î ¸î8Ùç
ºî'¼î ¾î8ß4¿î Åî'Æî8><Èî Ïî Ðî% Ñî8çî8endedÁ,ëî ñî8Ć\óî'þî8æ €ï ƒï …ï7ˆ „ï% †ï8Š4œï'¢ï8scopeÁ,¤ï ©ï Äõ ªï8Àð
,«ï °ï ²ï Ãõ 8
Ìï8 Ðï8Òï7ˆ Õï!Öï8­í
<Øï àï Þó8Àð
,þï ƒð8spawnÁ,„ð ‰ð Ãó Šð8 ‹ð Œð8$Žð “ð Âó8µð8â¹ð ½ð8Îî
4¿ð Åð8Å-LÆð Ïð Ðð% Ñð8óð öð8â÷ð úð8is_emptyÁDûð ƒñ „ñ †ñ êò 8ÔL¬ñ µñ ¶ñ Ðñ
·ñ8â¸ñ$ »ñ7New configurationÁœ½ñ% Ññ8Îï
,÷ñ üñ8 fetch_addÁLýñ †ò ›ò7 ‡ò$ ˆò8®DŠò'’ò8Ë<”ò% œò84Âò% Èò8…ä
4Œó'’ó8spin_loop_hintÁt”ó ¢ó £ó% ¤ó% Äó8Àð
,øó ýó8óñ
,þó ƒô ¬õ „ô8 …ô †ô ˆô «õ
8¦ô8new_confÁDªô ³ô8Kµô'¸ô8æ ºô ½ô Üô7¸ô
œ¾ô Ñô8to_ownedÁDÒô Úô Ûô% Ýô8Îî
4ûô õ8È,‚õ ‡õ õ8š÷
Dˆõ% ‘õ% ­õ Úõ8¢4Ûõ áõ âõ% ãõ8ÔLùõ ‚ö ƒö ªö8­í
<„ö$ ‹ö8Îï
,ö ’ö8¬$“ö —ö ©ö8®D˜ö' ö8Ë<¢ö% «ö8Áö8arcÁÅö Éö8Îî
4Ëö Ñö8Å-LÒö Ûö Üö% Ýö8ÔLóö üö ýö ˜÷7Š þö$ ÿö8K÷'„÷8 strong_countÁd†÷ ’÷ —÷ “÷8¸ú
”÷% ™÷8ÔL¯÷ ¸÷ ¹÷ Ò÷7ˆ º÷$ »÷8K½÷'À÷8
weak_countÁTÂ÷ Ì÷ Ñ÷ Í÷8¸ú
Î÷% Ó÷<= Similar to the doc tests of ArcSwap, but happens more times.Áü‚ø@+ Ïø Ðø Õø8$Ñø8 ãø8 swap_loadÁLæø ïø ðø òø Ø€8
„ù8 ˆù8Šù7ˆ ù!Žù7100Áù ”ù Ê€@8ªù8¸ú
®ù ²ù8K´ù'·ù8æ ¹ù ¼ù ¿ù742Á½ù% Àù8Öù8DÚù ãù8Ùç
åù'çù8÷$éù íù þù8Kîù'ñù8ƒ,óù øù ýù ùù8¸ú
úù% ÿù8ÔL•ú žú Ÿú µú7óÿ
 ú$ ¢ú
¤ú
¥ú8D¦ú ®ú8¬$¯ú ³ú ´ú% ¶ú8ÔLû Šû ‹û ¡û7óÿ
Œû$ Žû
û
‘û8D’û šû8¬$›û Ÿû  û% ¢û8çû8new_arcÁ<ëû óû8Kõû'øû8æ úû ýû ÿû7ˆ þû% €ü8ÔL–ü Ÿü  ü Éü7óÿ
¡ü$ £ü
¥ü8D¦ü ®ü8æ-$¯ü ³ü Èü8K´ü'·ü8ƒ,¹ü ¾ü Çü ¿ü8®ƒ <Àü% Êü8ÔLàü éü êü ÿü7ˆ ëü$ ìü
îü
ïü8Dðü øü8¬$ùü ýü þü% €ý8âý8loadedÁ4æý íý8Dïý ÷ý8Å-Løý þ ‚þ% ƒþ8ÔL™þ ¢þ £þ Áþ7 ¤þ$ ¥þ8K§þ'ªþ8Òû
d¬þ ¸þ Àþ ¹þ8ц 4ºþ% Âþ8ÔLØþ áþ âþ þþ7ˆ ãþ$ äþ8Kæþ'éþ8áü
Tëþ õþ ýþ öþ8ц 4÷þ% ÿþ8ÔLØÿ áÿ âÿ ýÿ7 ãÿ$ äÿ8Kæÿ'éÿ8Òû
dëÿ ÷ÿ üÿ øÿ8¸ú
ùÿ% þÿ8ÔL”€  ž€ ·€7ˆ Ÿ€$  €8K¢€'¥€8áü
T§€ ±€ ¶€ ²€8¸ú
³€% ¸€<Q Two different writers publish two series of values. The readers check that it isÁüç€T<" always increasing in each series.ÁüÈ%<úú<3 For performance, we try to reuse the threads here.ÁüŠ‚6+ Í‚ ΂ Ó‚8$Ï‚8 á‚8
multi_writersÁlä‚ ñ‚ ò‚ ô‚ G8†ƒ8 first_valueÁ\Šƒ –ƒ8K˜ƒ'›ƒ8æ ƒ  ƒ §ƒ ¡ƒ ¦ƒ7ˆ ¢ƒ$ £ƒ7ˆ ¥ƒ% ¨ƒ8ºƒ8sharedÁ4¾ƒ Ń8Ùç
ǃ'Ƀ8÷$˃ σ èƒ8KЃ'Óƒ8ƒ,Õƒ Úƒ çƒ Ûƒ8ÿ \܃% éƒ8,ûƒ8
WRITER_CNTÁT& ‹„8¬, “„7Š •„% –„8,¨„8
READER_CNTÁT®„& ¸„8¬,º„ À„7 „% Ä+ Õ„ Ö„ à„8âׄ Ú„ ß„8µ $Û„8,ò„8Çæ
Tø„& ‚…8¬,„… Š…7 Œ…% + Ÿ…  … ¯…8â¡… ¤… ®…8
¥… ¨… ­…8µ $©…8,Á…8Çæ
TÇ…& Ñ…8¬,Ó… Ù…7†ÿ
Û…% Þ…8,ð…8SEQÁö…& ù…8¬,û… 750Áƒ†% …†8—†8barrierÁ<›† £†8”å
<¥†'¬†8æ ®† ±† Æ8¯å
L²†'»†8PoisonÁ4½†% Ć8Š4Ö†'܆8Àð
,Þ† ㆠؘ ä†8Àð
,å† ê† ì† ט8
‚‡8 †‡8ˆ‡7ˆ ‹‡!Œ‡8° Tއ ™‡ ¼8½ˆ8Áˆ8Ë” <ň ͈8Ë” <ψ Öˆ8ƒ,׈ ܈ ݈% Þˆ8øˆ8 4üˆ ƒ‰ …‰8 4†‰% Œ‰8¦‰8ÿ \ª‰ ¶‰ ¸‰8ÿ \¹‰% ĉ8Àð
,Þ‰ ã‰8óñ
,ä‰ é‰ ¥8$ê‰ ï‰8 ð‰ ñ‰ ó‰ ¤8
‘Š8 •Š8—Š7ˆ šŠ!›Š8Çæ
TŠ ¨Š Š8Ë” <ÊŠ ÑŠ8waitÁ$ÒŠ ÖŠ ׊% ØŠ8 4úŠ €‹8È, †‹ Ÿ‹8K‡‹'Š‹8ƒ,Œ‹ ‘‹ ž‹ ’‹8ÿ \“‹%  ‹8Ë” <‹ É‹8žš $Ê‹ ΋ Ï‹% Ћ8
ò‹8´ ö‹8ø‹7ˆ û‹!ü‹8þ“ þ‹ ‚Œ ìŒ8 4¨Œ ®Œ8È,¯Œ ´Œ ÉŒ8KµŒ'¸Œ8æ ºŒ ½Œ ÈŒ ¾Œ ÇŒ8 ¿Œ$ ÀŒ8´ ÂŒ ÄŒ7 ÆŒ% ÊŒ% ¦8
Ò8 Ö8Ø7ˆ Û!Ü8‚‘  é ¡˜8ƒŽ8‡Ž8Ë” <‹Ž “Ž8Ë” <•Ž œŽ8ƒ,Ž ¢Ž £Ž% ¤Ž8¾Ž8 4ÂŽ ÉŽ ËŽ8 4ÌŽ% ÒŽ8ìŽ8ÿ \ðŽ üŽ þŽ8ÿ \ÿŽ% Š8Àð
 ©8óñ
 ¯ Š˜8 µ8  · ¹ ‰˜8
×8 Û8Ý7ˆ à!á8Çæ
 î ï—8Ë” < 8žš  œ % ž8Ë”  Ç8žš  Ì Í% Î8ð8ô8previousÁ  ƒ‘ ‘‘7ˆ „‘% …‘8° T‡‘% ’‘8´‘8¸‘8$¼‘ Á‘8KÑ'Æ‘8ƒ,È‘ Í‘ Ú‘ Α8ÿ \Ï‘% Û‘8$ý‘ ‚’ Ñ—*8¨’8¬’ °’8 4²’ ¸’8¬$¹’ ½’ ¾’% ¿’8å’8Kè’'ë’8–+4í’ ó’ ÿ’ ô’8$õ’$ ù’ û’8ü’  ›”8…ä
4«“'±“8ûõ
t³“ Á“ “% Ó8Dí“% õ“8Á” Å” Ê”8 Ɣ$ Ç”8¾ É” Ì”
Δ
Ï”8Д% Ó”8Ó4ù” ÿ” €• ¯•
8í¢ D ‰• ‹•8Â Š• 8¾ $ 7 {:?} vs {:?}Át’•$  •8í¢ D¢•$ ª•8¬•% °•8í¢ DÖ• Þ• à•8 ߕ â•8¾ ä•% å•8$‹– 8° ,’–'—–8´$T™– £– §–8¤–% ¨–8Ζ8¾ Ñ–Ó–8þ“ Ö– Ú– ¯—8,„—% ‰—% ‹˜8ã$¸˜ ¼˜ Ę8Ë” <½˜% Ř ê˜8¢4ë˜ ñ˜ ò˜% ó˜+  ‘™ –™8$’™8 ¤™8 load_nullÁL§™ °™ ±™ ³™ Á›!8Å™8 4É™ Й8»é
Ò™'Õ™ ×™8¬,Ø™ Ý™'Þ™8><à™ ç™ è™% é™8û™8£,ÿ™ …š8 4‡š š8¬$Žš ’š “š% ”š8Ó4¦š ¬š ­š ½š8£,®š ³š8is_noneÁ<´š »š ¼š% ¾š8 4К Öš8È,ך Üš ïš8Û$Ýš áš îš8Kâš'åš8æ çš êš íš7óÿ
ëš% ðš8ÔL‚› ‹› Œ› ²›7óÿ
$ 
‘›