[{"data":1,"prerenderedAt":576},["ShallowReactive",2],{"navigation":3,"\u002Fconcepts\u002Fcomparators":151,"\u002Fconcepts\u002Fcomparators-surround":571},[4,29,56,79,94,121,128,144],{"title":5,"path":6,"stem":7,"children":8,"icon":27,"defaultOpen":28},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17,22],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-book-open",{"title":13,"path":14,"stem":15,"icon":16},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Redis setup","\u002Fgetting-started\u002Fredis-setup","1.getting-started\u002F3.redis-setup","i-lucide-database",{"title":23,"path":24,"stem":25,"icon":26},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F4.quickstart","i-lucide-zap","i-lucide-rocket",true,{"title":30,"icon":31,"path":32,"stem":33,"children":34,"page":55},"Concepts","i-lucide-lightbulb","\u002Fconcepts","2.concepts",[35,40,45,50],{"title":36,"path":37,"stem":38,"icon":39},"Keys","\u002Fconcepts\u002Fkeys","2.concepts\u002F1.keys","i-lucide-key-round",{"title":41,"path":42,"stem":43,"icon":44},"Strict vs lax","\u002Fconcepts\u002Fstrict-vs-lax","2.concepts\u002F2.strict-vs-lax","i-lucide-scale",{"title":46,"path":47,"stem":48,"icon":49},"Comparators","\u002Fconcepts\u002Fcomparators","2.concepts\u002F3.comparators","i-lucide-git-compare",{"title":51,"path":52,"stem":53,"icon":54},"Errors","\u002Fconcepts\u002Ferrors","2.concepts\u002F4.errors","i-lucide-triangle-alert",false,{"title":57,"path":58,"stem":59,"children":60,"icon":63},"Counters","\u002Fcounters","3.counters\u002F1.index",[61,64,69,74],{"title":62,"path":58,"stem":59,"icon":63},"Overview","i-lucide-hash",{"title":65,"path":66,"stem":67,"icon":68},"StrictCounter","\u002Fcounters\u002Fstrict-counter","3.counters\u002F2.strict-counter","i-lucide-target",{"title":70,"path":71,"stem":72,"icon":73},"LaxCounter","\u002Fcounters\u002Flax-counter","3.counters\u002F3.lax-counter","i-lucide-wind",{"title":75,"path":76,"stem":77,"icon":78},"Conditional & batch operations","\u002Fcounters\u002Fconditional-and-batch","3.counters\u002F4.conditional-and-batch","i-lucide-layers",{"title":80,"path":81,"stem":82,"children":83,"icon":85},"Instance-aware counters","\u002Finstance-aware-counters","4.instance-aware-counters\u002F1.index",[84,86,90],{"title":62,"path":81,"stem":82,"icon":85},"i-lucide-network",{"title":87,"path":88,"stem":89,"icon":68},"StrictInstanceAwareCounter","\u002Finstance-aware-counters\u002Fstrict","4.instance-aware-counters\u002F2.strict",{"title":91,"path":92,"stem":93,"icon":73},"LaxInstanceAwareCounter","\u002Finstance-aware-counters\u002Flax","4.instance-aware-counters\u002F3.lax",{"title":95,"path":96,"stem":97,"children":98,"icon":100},"Locks","\u002Flocks","5.locks\u002F1.index",[99,101,106,111,116],{"title":62,"path":96,"stem":97,"icon":100},"i-lucide-lock",{"title":102,"path":103,"stem":104,"icon":105},"Mutex","\u002Flocks\u002Fmutex","5.locks\u002F2.mutex","i-lucide-lock-keyhole",{"title":107,"path":108,"stem":109,"icon":110},"RwLock","\u002Flocks\u002Frwlock","5.locks\u002F3.rwlock","i-lucide-book-lock",{"title":112,"path":113,"stem":114,"icon":115},"Lock options","\u002Flocks\u002Foptions","5.locks\u002F4.options","i-lucide-sliders-horizontal",{"title":117,"path":118,"stem":119,"icon":120},"Guard state & errors","\u002Flocks\u002Fguard-state","5.locks\u002F5.guard-state","i-lucide-shield-alert",{"title":122,"path":123,"stem":124,"children":125,"icon":127},"Rate limiting","\u002Frate-limiting","6.rate-limiting\u002F1.index",[126],{"title":122,"path":123,"stem":124,"icon":127},"i-lucide-gauge",{"title":129,"icon":130,"path":131,"stem":132,"children":133,"page":55},"Reference","i-lucide-book-marked","\u002Freference","7.reference",[134,139],{"title":135,"path":136,"stem":137,"icon":138},"Feature flags","\u002Freference\u002Ffeature-flags","7.reference\u002F1.feature-flags","i-lucide-flag",{"title":140,"path":141,"stem":142,"icon":143},"API reference","\u002Freference\u002Fapi","7.reference\u002F2.api","i-lucide-file-code",{"title":145,"path":146,"stem":147,"children":148,"icon":150},"Changelog","\u002Fchangelog","8.changelog\u002F1.index",[149],{"title":145,"path":146,"stem":147,"icon":150},"i-lucide-scroll",{"id":152,"title":46,"badge":153,"body":154,"date":153,"description":565,"extension":566,"links":153,"meta":567,"navigation":568,"path":47,"seo":569,"stem":48,"__hash__":570},"docs\u002F2.concepts\u002F3.comparators.md",null,{"type":155,"value":156,"toc":562},"minimark",[157,170,177,290,296,301,312,339,342,547,558],[158,159,160,161,165,166,169],"p",{},"Conditional operations (",[162,163,164],"code",{},"inc_if",", ",[162,167,168],{},"set_if",", and their batch forms) let you change a counter only when its current value satisfies a condition - atomically, on the Redis side, with no read-modify-write race.",[158,171,172,173,176],{},"The condition is a ",[162,174,175],{},"CounterComparator",":",[178,179,184],"pre",{"className":180,"code":181,"language":182,"meta":183,"style":183},"language-rust shiki shiki-themes material-theme-lighter github-light github-dark","pub enum CounterComparator {\n    Eq(i64), \u002F\u002F current == value\n    Lt(i64), \u002F\u002F current \u003C  value\n    Gt(i64), \u002F\u002F current >  value\n    Ne(i64), \u002F\u002F current != value\n    Nil,     \u002F\u002F always matches\n}\n","rust","",[162,185,186,207,227,242,257,272,284],{"__ignoreMap":183},[187,188,191,195,199,203],"span",{"class":189,"line":190},"line",1,[187,192,194],{"class":193},"sw1J6","pub",[187,196,198],{"class":197},"sbsja"," enum",[187,200,202],{"class":201},"sbgvK"," CounterComparator",[187,204,206],{"class":205},"sP7_E"," {\n",[187,208,210,214,217,220,223],{"class":189,"line":209},2,[187,211,213],{"class":212},"sGLFI","    Eq",[187,215,216],{"class":205},"(",[187,218,219],{"class":201},"i64",[187,221,222],{"class":205},"),",[187,224,226],{"class":225},"sutJx"," \u002F\u002F current == value\n",[187,228,230,233,235,237,239],{"class":189,"line":229},3,[187,231,232],{"class":212},"    Lt",[187,234,216],{"class":205},[187,236,219],{"class":201},[187,238,222],{"class":205},[187,240,241],{"class":225}," \u002F\u002F current \u003C  value\n",[187,243,245,248,250,252,254],{"class":189,"line":244},4,[187,246,247],{"class":212},"    Gt",[187,249,216],{"class":205},[187,251,219],{"class":201},[187,253,222],{"class":205},[187,255,256],{"class":225}," \u002F\u002F current >  value\n",[187,258,260,263,265,267,269],{"class":189,"line":259},5,[187,261,262],{"class":212},"    Ne",[187,264,216],{"class":205},[187,266,219],{"class":201},[187,268,222],{"class":205},[187,270,271],{"class":225}," \u002F\u002F current != value\n",[187,273,275,278,281],{"class":189,"line":274},6,[187,276,277],{"class":201},"    Nil",[187,279,280],{"class":205},",",[187,282,283],{"class":225},"     \u002F\u002F always matches\n",[187,285,287],{"class":189,"line":286},7,[187,288,289],{"class":205},"}\n",[158,291,292,295],{},[162,293,294],{},"Nil"," is the \"no condition\" variant - it always passes, which is handy in batches where some entries are conditional and others are not.",[297,298,300],"h2",{"id":299},"how-conditional-writes-report-back","How conditional writes report back",[158,302,303,305,306,308,309,176],{},[162,304,164],{}," and ",[162,307,168],{}," return ",[162,310,311],{},"(new, old)",[313,314,315,328],"ul",{},[316,317,318,319,323,324,327],"li",{},"If the comparison ",[320,321,322],"strong",{},"passed",", the write happened and ",[162,325,326],{},"new"," is the updated value.",[316,329,330,331,334,335,338],{},"If it ",[320,332,333],{},"failed",", nothing changed and ",[162,336,337],{},"new == old",".",[158,340,341],{},"So you can tell whether the condition held by checking whether the two values differ.",[178,343,345],{"className":180,"code":344,"language":182,"meta":183,"style":183},"use distkit::CounterComparator;\n\nstrict.set(&key, 10).await?;\n\n\u002F\u002F 10 == 10, so this applies: returns (15, 10).\nassert_eq!(strict.inc_if(&key, CounterComparator::Eq(10), 5).await?, (15, 10));\n\n\u002F\u002F 15 is not > 20, so this is a no-op: returns (15, 15).\nassert_eq!(strict.set_if(&key, CounterComparator::Gt(20), 99).await?, (15, 15));\n",[162,346,347,364,369,408,412,417,478,482,488],{"__ignoreMap":183},[187,348,349,352,355,359,361],{"class":189,"line":190},[187,350,351],{"class":193},"use",[187,353,354],{"class":201}," distkit",[187,356,358],{"class":357},"smGrS","::",[187,360,175],{"class":201},[187,362,363],{"class":205},";\n",[187,365,366],{"class":189,"line":209},[187,367,368],{"emptyLinePlaceholder":28},"\n",[187,370,371,375,377,380,382,385,388,390,394,397,399,403,406],{"class":189,"line":229},[187,372,374],{"class":373},"su5hD","strict",[187,376,338],{"class":357},[187,378,379],{"class":212},"set",[187,381,216],{"class":205},[187,383,384],{"class":357},"&",[187,386,387],{"class":373},"key",[187,389,280],{"class":205},[187,391,393],{"class":392},"srdBf"," 10",[187,395,396],{"class":205},")",[187,398,338],{"class":357},[187,400,402],{"class":401},"sVHd0","await",[187,404,405],{"class":357},"?",[187,407,363],{"class":205},[187,409,410],{"class":189,"line":244},[187,411,368],{"emptyLinePlaceholder":28},[187,413,414],{"class":189,"line":259},[187,415,416],{"class":225},"\u002F\u002F 10 == 10, so this applies: returns (15, 10).\n",[187,418,419,422,424,426,428,430,432,434,436,438,440,442,445,447,450,452,455,457,459,461,463,465,468,471,473,475],{"class":189,"line":274},[187,420,421],{"class":212},"assert_eq!",[187,423,216],{"class":205},[187,425,374],{"class":373},[187,427,338],{"class":357},[187,429,164],{"class":212},[187,431,216],{"class":205},[187,433,384],{"class":357},[187,435,387],{"class":373},[187,437,280],{"class":205},[187,439,202],{"class":201},[187,441,358],{"class":357},[187,443,444],{"class":212},"Eq",[187,446,216],{"class":205},[187,448,449],{"class":392},"10",[187,451,222],{"class":205},[187,453,454],{"class":392}," 5",[187,456,396],{"class":205},[187,458,338],{"class":357},[187,460,402],{"class":401},[187,462,405],{"class":357},[187,464,280],{"class":205},[187,466,467],{"class":205}," (",[187,469,470],{"class":392},"15",[187,472,280],{"class":205},[187,474,393],{"class":392},[187,476,477],{"class":205},"));\n",[187,479,480],{"class":189,"line":286},[187,481,368],{"emptyLinePlaceholder":28},[187,483,485],{"class":189,"line":484},8,[187,486,487],{"class":225},"\u002F\u002F 15 is not > 20, so this is a no-op: returns (15, 15).\n",[187,489,491,493,495,497,499,501,503,505,507,509,511,513,516,518,521,523,526,528,530,532,534,536,538,540,542,545],{"class":189,"line":490},9,[187,492,421],{"class":212},[187,494,216],{"class":205},[187,496,374],{"class":373},[187,498,338],{"class":357},[187,500,168],{"class":212},[187,502,216],{"class":205},[187,504,384],{"class":357},[187,506,387],{"class":373},[187,508,280],{"class":205},[187,510,202],{"class":201},[187,512,358],{"class":357},[187,514,515],{"class":212},"Gt",[187,517,216],{"class":205},[187,519,520],{"class":392},"20",[187,522,222],{"class":205},[187,524,525],{"class":392}," 99",[187,527,396],{"class":205},[187,529,338],{"class":357},[187,531,402],{"class":401},[187,533,405],{"class":357},[187,535,280],{"class":205},[187,537,467],{"class":205},[187,539,470],{"class":392},[187,541,280],{"class":205},[187,543,544],{"class":392}," 15",[187,546,477],{"class":205},[158,548,549,550,553,554,557],{},"The same comparator type is used by the instance-aware counters, where the comparison is made against the cumulative total (or, for ",[162,551,552],{},"set_on_instance_if",", the calling instance's slice). See ",[555,556,75],"a",{"href":76}," for the batch forms.",[559,560,561],"style",{},"html pre.shiki code .sw1J6, html code.shiki .sw1J6{--shiki-light:#F76D47;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}",{"title":183,"searchDepth":190,"depth":209,"links":563},[564],{"id":299,"depth":209,"text":300},"CounterComparator drives conditional counter writes.","md",{},{"icon":49},{"title":46,"description":565},"muHzAmZ3wZk3Qe7E1DnWQY6fFJhgbpbaw-9Axo-Bnh0",[572,574],{"title":41,"path":42,"stem":43,"description":573,"icon":44,"children":-1},"The consistency trade-off that runs through distkit's counters.",{"title":51,"path":52,"stem":53,"description":575,"icon":54,"children":-1},"One DistkitError enum, and a no-panic policy.",1781569582557]