Files
Flash5/javadoc/2.0.0/dev/relism/flash/ext/limiter/strategy/SlidingWindowStrategy.html
T

230 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE HTML>
<html lang="en">
<head>
<!-- Generated by javadoc (21) on Tue May 12 14:36:52 UTC 2026 -->
<title>SlidingWindowStrategy (flash-parent 2.1.0-SNAPSHOT API)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="dc.created" content="2026-05-12">
<meta name="description" content="declaration: package: dev.relism.flash.ext.limiter.strategy, class: SlidingWindowStrategy">
<meta name="generator" content="javadoc/ClassWriterImpl">
<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../../script-dir/jquery-ui.min.css" title="Style">
<script type="text/javascript" src="../../../../../../script.js"></script>
<script type="text/javascript" src="../../../../../../script-dir/jquery-3.7.1.min.js"></script>
<script type="text/javascript" src="../../../../../../script-dir/jquery-ui.min.js"></script>
</head>
<body class="class-declaration-page">
<script type="text/javascript">var pathtoroot = "../../../../../../";
loadScripts(document, 'script');</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<div class="flex-box">
<header role="banner" class="flex-header">
<nav role="navigation">
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="top-nav" id="navbar-top"><button id="navbar-toggle-button" aria-controls="navbar-top" aria-expanded="false" aria-label="Toggle navigation links"><span class="nav-bar-toggle-icon">&nbsp;</span><span class="nav-bar-toggle-icon">&nbsp;</span><span class="nav-bar-toggle-icon">&nbsp;</span></button>
<div class="skip-nav"><a href="#skip-navbar-top" title="Skip navigation links">Skip navigation links</a></div>
<ul id="navbar-top-firstrow" class="nav-list" title="Navigation">
<li><a href="../../../../../../index.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="nav-bar-cell1-rev">Class</li>
<li><a href="class-use/SlidingWindowStrategy.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../../../index-all.html">Index</a></li>
<li><a href="../../../../../../help-doc.html#class">Help</a></li>
</ul>
<ul class="sub-nav-list-small">
<li>
<p>Summary:</p>
<ul>
<li>Nested</li>
<li>Field</li>
<li><a href="#constructor-summary">Constr</a></li>
<li><a href="#method-summary">Method</a></li>
</ul>
</li>
<li>
<p>Detail:</p>
<ul>
<li>Field</li>
<li><a href="#constructor-detail">Constr</a></li>
<li><a href="#method-detail">Method</a></li>
</ul>
</li>
</ul>
</div>
<div class="sub-nav">
<div id="navbar-sub-list">
<ul class="sub-nav-list">
<li>Summary:&nbsp;</li>
<li>Nested&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#constructor-summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method-summary">Method</a></li>
</ul>
<ul class="sub-nav-list">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#constructor-detail">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method-detail">Method</a></li>
</ul>
</div>
<div class="nav-list-search"><a href="../../../../../../search.html">SEARCH</a>
<input type="text" id="search-input" disabled placeholder="Search">
<input type="reset" id="reset-button" disabled value="reset">
</div>
</div>
<!-- ========= END OF TOP NAVBAR ========= -->
<span class="skip-nav" id="skip-navbar-top"></span></nav>
</header>
<div class="flex-content">
<main role="main">
<!-- ======== START OF CLASS DATA ======== -->
<div class="header">
<div class="sub-title"><span class="package-label-in-type">Package</span>&nbsp;<a href="package-summary.html">dev.relism.flash.ext.limiter.strategy</a></div>
<h1 title="Class SlidingWindowStrategy" class="title">Class SlidingWindowStrategy</h1>
</div>
<div class="inheritance" title="Inheritance Tree"><a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">java.lang.Object</a>
<div class="inheritance">dev.relism.flash.ext.limiter.strategy.SlidingWindowStrategy</div>
</div>
<section class="class-description" id="class-description">
<dl class="notes">
<dt>All Implemented Interfaces:</dt>
<dd><code><a href="../RateLimitStrategy.html" title="interface in dev.relism.flash.ext.limiter">RateLimitStrategy</a></code></dd>
</dl>
<hr>
<div class="type-signature"><span class="modifiers">public final class </span><span class="element-name type-name-label">SlidingWindowStrategy</span>
<span class="extends-implements">extends <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">Object</a>
implements <a href="../RateLimitStrategy.html" title="interface in dev.relism.flash.ext.limiter">RateLimitStrategy</a></span></div>
<div class="block">Sliding-window counter rate limit: approximates a true sliding window by interpolating
between the previous fixed window's count and the current window's count.
<pre>
estimate = prevCount × (1 elapsed / windowMs) + currentCount
</pre>
<p>This is the same approximation used by Redis. It eliminates the boundary burst
problem of <a href="FixedWindowStrategy.html" title="class in dev.relism.flash.ext.limiter.strategy"><code>FixedWindowStrategy</code></a> while staying O(1) memory and lock-free.
The error is bounded: in the worst case the true rate at the boundary can exceed
the limit by at most <code>limit × (1 elapsed/windowMs)</code> — typically a few percent.
<h3 id="slot-layout-heading">Slot layout</h3>
<ul>
<li><a href="../Bucket.html#slot0"><code>Bucket.slot0</code></a> — packed <code>(reducedEpoch &lt;&lt; 32 | currentCount)</code></li>
<li><a href="../Bucket.html#slot1"><code>Bucket.slot1</code></a> — count from the immediately preceding epoch (0 = none)</li>
</ul>
<p>On a window transition the thread that wins the <code>slot0</code> CAS also writes
<code>slot1</code>. A concurrent thread that reads <code>slot0</code> after the transition but
before <code>slot1</code> is written sees a slightly stale previous count — acceptable for
an approximation algorithm.</div>
</section>
<section class="summary">
<ul class="summary-list">
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<li>
<section class="constructor-summary" id="constructor-summary">
<h2>Constructor Summary</h2>
<div class="caption"><span>Constructors</span></div>
<div class="summary-table two-column-summary">
<div class="table-header col-first">Constructor</div>
<div class="table-header col-last">Description</div>
<div class="col-constructor-name even-row-color"><code><a href="#%3Cinit%3E()" class="member-name-link">SlidingWindowStrategy</a>()</code></div>
<div class="col-last even-row-color">&nbsp;</div>
</div>
</section>
</li>
<!-- ========== METHOD SUMMARY =========== -->
<li>
<section class="method-summary" id="method-summary">
<h2>Method Summary</h2>
<div id="method-summary-table">
<div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="method-summary-table-tab0" role="tab" aria-selected="true" aria-controls="method-summary-table.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table', 3)" class="active-table-tab">All Methods</button><button id="method-summary-table-tab2" role="tab" aria-selected="false" aria-controls="method-summary-table.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table-tab2', 3)" class="table-tab">Instance Methods</button><button id="method-summary-table-tab4" role="tab" aria-selected="false" aria-controls="method-summary-table.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table-tab4', 3)" class="table-tab">Concrete Methods</button></div>
<div id="method-summary-table.tabpanel" role="tabpanel" aria-labelledby="method-summary-table-tab0">
<div class="summary-table three-column-summary">
<div class="table-header col-first">Modifier and Type</div>
<div class="table-header col-second">Method</div>
<div class="table-header col-last">Description</div>
<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>boolean</code></div>
<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#check(dev.relism.flash.ext.limiter.Bucket,dev.relism.flash.ext.limiter.LimitConfig,long%5B%5D)" class="member-name-link">check</a><wbr>(<a href="../Bucket.html" title="class in dev.relism.flash.ext.limiter">Bucket</a>&nbsp;bucket,
<a href="../LimitConfig.html" title="class in dev.relism.flash.ext.limiter">LimitConfig</a>&nbsp;cfg,
long[]&nbsp;out)</code></div>
<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Checks whether this request is within the limit and updates the bucket atomically.</div>
</div>
</div>
</div>
</div>
<div class="inherited-list">
<h3 id="methods-inherited-from-class-java.lang.Object">Methods inherited from class&nbsp;java.lang.<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">Object</a></h3>
<code><a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#clone()" title="class or interface in java.lang" class="external-link">clone</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#equals(java.lang.Object)" title="class or interface in java.lang" class="external-link">equals</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#finalize()" title="class or interface in java.lang" class="external-link">finalize</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#getClass()" title="class or interface in java.lang" class="external-link">getClass</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#hashCode()" title="class or interface in java.lang" class="external-link">hashCode</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#notify()" title="class or interface in java.lang" class="external-link">notify</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#notifyAll()" title="class or interface in java.lang" class="external-link">notifyAll</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#toString()" title="class or interface in java.lang" class="external-link">toString</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#wait()" title="class or interface in java.lang" class="external-link">wait</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#wait(long)" title="class or interface in java.lang" class="external-link">wait</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#wait(long,int)" title="class or interface in java.lang" class="external-link">wait</a></code></div>
</section>
</li>
</ul>
</section>
<section class="details">
<ul class="details-list">
<!-- ========= CONSTRUCTOR DETAIL ======== -->
<li>
<section class="constructor-details" id="constructor-detail">
<h2>Constructor Details</h2>
<ul class="member-list">
<li>
<section class="detail" id="&lt;init&gt;()">
<h3>SlidingWindowStrategy</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name">SlidingWindowStrategy</span>()</div>
</section>
</li>
</ul>
</section>
</li>
<!-- ============ METHOD DETAIL ========== -->
<li>
<section class="method-details" id="method-detail">
<h2>Method Details</h2>
<ul class="member-list">
<li>
<section class="detail" id="check(dev.relism.flash.ext.limiter.Bucket,dev.relism.flash.ext.limiter.LimitConfig,long[])">
<h3>check</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name">check</span><wbr><span class="parameters">(<a href="../Bucket.html" title="class in dev.relism.flash.ext.limiter">Bucket</a>&nbsp;bucket,
<a href="../LimitConfig.html" title="class in dev.relism.flash.ext.limiter">LimitConfig</a>&nbsp;cfg,
long[]&nbsp;out)</span></div>
<div class="block"><span class="description-from-type-label">Description copied from interface:&nbsp;<code><a href="../RateLimitStrategy.html#check(dev.relism.flash.ext.limiter.Bucket,dev.relism.flash.ext.limiter.LimitConfig,long%5B%5D)">RateLimitStrategy</a></code></span></div>
<div class="block">Checks whether this request is within the limit and updates the bucket atomically.
<p>On return, <code>out</code> contains:
<ul>
<li><code>out[0]</code> — remaining allowed requests in the current window (≥ 0).</li>
<li><code>out[1]</code> — Unix epoch seconds at which the quota resets (for <code>X-RateLimit-Reset</code>
and <code>Retry-After</code> headers).</li>
</ul></div>
<dl class="notes">
<dt>Specified by:</dt>
<dd><code><a href="../RateLimitStrategy.html#check(dev.relism.flash.ext.limiter.Bucket,dev.relism.flash.ext.limiter.LimitConfig,long%5B%5D)">check</a></code>&nbsp;in interface&nbsp;<code><a href="../RateLimitStrategy.html" title="interface in dev.relism.flash.ext.limiter">RateLimitStrategy</a></code></dd>
<dt>Parameters:</dt>
<dd><code>bucket</code> - per-key state carrier (pre-allocated, never null)</dd>
<dd><code>cfg</code> - immutable rule configuration</dd>
<dd><code>out</code> - caller-supplied two-element array; values are overwritten on every call</dd>
<dt>Returns:</dt>
<dd><code>true</code> if the request is within the limit and should proceed</dd>
</dl>
</section>
</li>
</ul>
</section>
</li>
</ul>
</section>
<!-- ========= END OF CLASS DATA ========= -->
</main>
<footer role="contentinfo">
<hr>
<p class="legal-copy"><small>Copyright &#169; 2026. All rights reserved.</small></p>
</footer>
</div>
</div>
</body>
</html>