Hi Xinqi, Hongyin, Yuan, and all,

Thanks for the detailed write-up on the pushdown decision. Since
Hongyin mentioned following the ordered-input property and the
memory-management approach in particular, I read through the
implementation in PR #18334 against those two points and wanted to
report what I found, in case it is useful to the discussion.

On the ordered-input property.

Xinqi's design derives inputOrderedByTimeAscending from the
OrderingScheme of the finalized physical child, and selects the
Ordered implementation only when the planner can prove ascending
order by the actual time_col. What I wanted to check was what
happens if that proof is ever wrong -- for instance after a future
optimizer change that introduces a plan shape the property does not
correctly describe.

The implementation does not assume the precondition holds. The
Ordered accumulators validate it at runtime: a sample whose
timestamp is less than the previous one raises the ordered-input
violation error, and an equal timestamp raises the duplicate-
timestamp error, rather than being silently folded into the
increment. The naive path does not need that check: it sorts the
buffer first, so out-of-order input is normalised rather than
rejected, and it converges on the same duplicate-timestamp error
after the sort, since sorting cannot remove a duplicate. The two
implementations diverge exactly where they should -- only the
ordered path can be misled by the planner, and only the ordered
path checks. So a planner-side regression would surface as a
clear query error instead of a wrong number, which seems like
the right trade-off for a correctness-critical precondition.

Boundary handling is validated in the same defensive style before
the division: fewer than two samples, first_time >= last_time,
window_start >= window_end, and samples falling outside
[window_start, window_end) are each rejected explicitly. I checked
the zero-width window case specifically, since a caller can produce
one from a degenerate query range, and it is covered.

On memory management.

The naive path buffers every sample per group, which is where I
expected the exposure to be. It is accounted for: the estimated
size includes the sample buffer, the buffer reports the real array
lengths rather than a fixed estimate, and the reservation is
updated cumulatively through MemoryReservationManager on every
mutation, not only at construction. The grouped ordered path does
the same. So the per-group buffering is visible to the engine's
memory accounting rather than growing outside it.

Two smaller observations.

delta() computes from the first and last values directly, while
rate() and increase() accumulate through the counter-reset
correction. Keeping the gauge function out of the counter-reset
path matches Prometheus semantics and is easy to get wrong when
four functions share a base class, so it is worth noting that the
distinction is preserved here.

The grouped accumulators track per-group initialization with an
explicit flag rather than a sentinel initial value. That is the
detail that keeps them clear of #18300, where a sentinel that
looked equivalent turned out not to span the whole value range.

For context on why I was looking: I am working on the ThingsBoard
Table Mode integration for GSoC, which issues date_bin-grouped
aggregation against a real server in its integration tests. Once
these functions are in a release I am happy to exercise them
through that path, particularly grouped evaluation across many tag
combinations, and report anything that shows up.

Best regards,
Zihan Dai
GitHub: PDGGK

On Fri, Jul 31, 2026 01:22 PM, Xinqi Zhao <[email protected]> wrote:

> Hi Hongyin, Yuan, and all,
>
> Sorry for the delayed reply.
>
> Thank you, Hongyin, for following this proposal and offering to
> participate in further discussion and review. I have now completed the
> final technical design, including the ordered-input property, distributed
> intermediate-state handling, and memory-management approach that you
> mentioned.
>
> Yuan, regarding your question about pushing the four functions down to
> TableScan and combining AggregationNode with TableScan into an
> AggregationTableScanNode: I considered this approach, but decided not to
> support the pushdown in the current design.
>
> The main reasons are as follows.
>
> First, all aggregate functions in one AggregationTableScanNode share a
> single underlying scan direction, either ASC or DESC.
>
> For existing functions such as first() and last(), the direction is mainly
> a performance preference: first() prefers ASC but can still process DESC
> input, while last() prefers DESC but can still process ASC input.
>
> The Ordered implementations of rate(), increase(), irate(), and delta(),
> however, require their time_col input to be strictly ascending. This is a
> correctness requirement rather than a performance preference.
>
> For example:
>
> SELECT
> rate(counter, time, window_start, window_end),
> last(value, time)
> FROM table1
> GROUP BY device_id;
>
> rate() requires ASC input, while last() prefers DESC input. The current
> scan-direction selection mechanism cannot represent the mandatory ASC
> requirement of rate(). If DESC is selected, the Ordered rate implementation
> cannot process the input safely.
>
> Second, the ordering semantics of these functions are determined by the
> explicitly supplied time_col argument. This argument may be an INT64 or
> TIMESTAMP column other than the table’s physical TIME column.
>
> The scanAscending property of AggregationTableScanNode only describes the
> scan order of the physical TIME column. It cannot prove that an arbitrary
> time_col argument is ordered.
>
> Therefore, the final design derives a separate inputOrderedByTimeAscending
> property from the OrderingScheme of the finalized physical child. The
> Ordered implementation is selected only when the planner can prove that
> samples are ascending by the actual time_col within each SQL aggregation
> group.
>
> Third, these functions require the original timestamp/value samples for
> sorting, duplicate-timestamp validation, counter-reset detection, and
> boundary extrapolation. They cannot be calculated only from file, chunk, or
> page statistics, so the main statistical benefit of aggregation pushdown
> does not apply.
>
> Finally, the current optimizer makes the pushdown decision for the
> complete AggregationNode. It does not split one node into pushed-down and
> non-pushed-down aggregate functions.
>
> For example:
>
> SELECT
> count(value),
> sum(value),
> rate(counter, time, window_start, window_end)
> FROM table1
> GROUP BY device_id;
>
> If rate() is not eligible for pushdown, pushing down only count() and
> sum() would require splitting the AggregationNode and recombining the
> results. I consider that additional planner change outside the scope of
> this feature.
>
> Based on these considerations, the final design disables aggregation
> pushdown whenever an AggregationNode contains rate(), increase(), irate(),
> or delta(). This is an intentional performance trade-off and does not
> affect query semantics. Existing functions such as count() and sum() remain
> eligible for pushdown when they are used without a rate-family function.
>
> Best regards,
> Xinqi Zhao
>
>
>
>
>          原始邮件
>
>
> 发件人:张洪胤 <[email protected]&gt;
> 发件时间:2026年7月29日 11:04
> 收件人:dev <[email protected]&gt;
> 主题:Re: [DISCUSS] Technical design for rate(), irate(), increase(), and
> delta() aggregate functions
>
>
>
>        Hi&nbsp;Xinqi&nbsp;and&nbsp;Yuan,
>
>
> Thank&nbsp;you&nbsp;for&nbsp;sharing&nbsp;the&nbsp;design&nbsp;and&nbsp;the&nbsp;detailed&nbsp;review&nbsp;comments.&nbsp;I&nbsp;am&nbsp;following&nbsp;this&nbsp;proposal&nbsp;closely,&nbsp;particularly&nbsp;the&nbsp;ordered-input&nbsp;property,&nbsp;distributed&nbsp;intermediate-state&nbsp;handling,&nbsp;and&nbsp;memory-management&nbsp;approach.
>
>
> This&nbsp;is&nbsp;an&nbsp;important&nbsp;addition&nbsp;to&nbsp;the&nbsp;IoTDB&nbsp;table&nbsp;model,&nbsp;and&nbsp;I&nbsp;look&nbsp;forward&nbsp;to&nbsp;the&nbsp;next&nbsp;revision&nbsp;and&nbsp;implementation&nbsp;progress.&nbsp;I&nbsp;would&nbsp;also&nbsp;be&nbsp;happy&nbsp;to&nbsp;participate&nbsp;in&nbsp;further&nbsp;discussion&nbsp;and&nbsp;review.
>
> Best&nbsp;regards,
> Hongyin&nbsp;Zhang
>
>
> &gt;&nbsp;2026年7月24日&nbsp;17:02,Yuan&nbsp;Tian&nbsp;<
> [email protected]&gt;&nbsp;写道:
> &gt;&nbsp;
> &gt;&nbsp;Hi&nbsp;xinqi,
> &gt;&nbsp;
>
> &gt;&nbsp;Do&nbsp;you&nbsp;think&nbsp;about&nbsp;pushing&nbsp;these&nbsp;four&nbsp;functions&nbsp;down&nbsp;to&nbsp;TableScan&nbsp;and
>
> &gt;&nbsp;combining&nbsp;AggNode&nbsp;with&nbsp;TableaScan&nbsp;into&nbsp;an&nbsp;AggTableScanNode.&nbsp;If&nbsp;so,&nbsp;why&nbsp;do
> &gt;&nbsp;you&nbsp;choose&nbsp;to&nbsp;not&nbsp;do&nbsp;that?
> &gt;&nbsp;
> &gt;&nbsp;Best&nbsp;regards,
> &gt;&nbsp;---------------------
> &gt;&nbsp;Yuan&nbsp;Tian
> &gt;&nbsp;
>
> &gt;&nbsp;On&nbsp;Fri,&nbsp;Jul&nbsp;24,&nbsp;2026&nbsp;at&nbsp;10:33 
> AM&nbsp;Xinqi&nbsp;Zhao&nbsp;<
> [email protected]&gt;&nbsp;wrote:
> &gt;&nbsp;
> &gt;&gt;&nbsp;Hi&nbsp;Yuan&nbsp;and&nbsp;all,
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Thank&nbsp;you&nbsp;for&nbsp;the&nbsp;detailed&nbsp;review&nbsp;and&nbsp;suggestions.&nbsp;I&nbsp;have&nbsp;revised&nbsp;the
> &gt;&gt;&nbsp;technical&nbsp;design&nbsp;accordingly.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;Related&nbsp;issue:
> &gt;&gt;&nbsp;https://github.com/apache/iotdb/issues/17976
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;main&nbsp;changes&nbsp;are&nbsp;summarized&nbsp;below.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Separate&nbsp;Ordered&nbsp;and&nbsp;Naive&nbsp;accumulator&nbsp;implementations
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;Ordered&nbsp;and&nbsp;Naive&nbsp;modes&nbsp;have&nbsp;been&nbsp;split&nbsp;into&nbsp;different&nbsp;concrete
>
> &gt;&gt;&nbsp;classes&nbsp;because&nbsp;they&nbsp;maintain&nbsp;different&nbsp;states&nbsp;and&nbsp;have&nbsp;different&nbsp;lifecycle
> &gt;&gt;&nbsp;requirements.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;For&nbsp;each&nbsp;function,&nbsp;an&nbsp;abstract&nbsp;base&nbsp;class&nbsp;now&nbsp;contains&nbsp;the&nbsp;shared
>
> &gt;&gt;&nbsp;validation,&nbsp;window&nbsp;semantics,&nbsp;and&nbsp;final&nbsp;calculation&nbsp;logic,&nbsp;while&nbsp;the
>
> &gt;&gt;&nbsp;concrete&nbsp;subclasses&nbsp;implement&nbsp;the&nbsp;corresponding&nbsp;state&nbsp;management:
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;AbstractRateTableAccumulator
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;OrderedRateAccumulator
> &gt;&gt;&nbsp;NaiveRateAccumulator
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;same&nbsp;structure&nbsp;is&nbsp;used&nbsp;for&nbsp;increase(),&nbsp;irate(),&nbsp;and&nbsp;delta(),&nbsp;as&nbsp;well
> &gt;&gt;&nbsp;as&nbsp;for&nbsp;the&nbsp;GroupedAccumulator&nbsp;path.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;accumulator&nbsp;path&nbsp;and&nbsp;the&nbsp;algorithm&nbsp;are&nbsp;treated&nbsp;as&nbsp;two&nbsp;independent
> &gt;&gt;&nbsp;dimensions:
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;operator&nbsp;selects&nbsp;TableAccumulator&nbsp;or&nbsp;GroupedAccumulator.
>
> &gt;&gt;&nbsp;The&nbsp;aggregation&nbsp;step&nbsp;and&nbsp;ordering&nbsp;property&nbsp;select&nbsp;Ordered&nbsp;or&nbsp;Naive.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Ordered&nbsp;implementations&nbsp;are&nbsp;used&nbsp;only&nbsp;for&nbsp;SINGLE&nbsp;aggregation&nbsp;and&nbsp;keep&nbsp;O(1)
>
> &gt;&gt;&nbsp;state&nbsp;per&nbsp;group.&nbsp;Naive&nbsp;implementations&nbsp;preserve&nbsp;all&nbsp;samples&nbsp;and&nbsp;support
>
> &gt;&gt;&nbsp;SINGLE,&nbsp;PARTIAL,&nbsp;INTERMEDIATE,&nbsp;and&nbsp;FINAL&nbsp;stages.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Explicit&nbsp;derivation&nbsp;of&nbsp;the&nbsp;ordered-input&nbsp;property
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;updated&nbsp;design&nbsp;defines&nbsp;inputOrderedByTimeAscending&nbsp;as&nbsp;a
>
> &gt;&gt;&nbsp;per-aggregation&nbsp;physical&nbsp;property.&nbsp;It&nbsp;is&nbsp;derived&nbsp;in
>
> &gt;&gt;&nbsp;TableDistributedPlanGenerator.visitAggregation()&nbsp;after&nbsp;the&nbsp;final&nbsp;physical
>
> &gt;&gt;&nbsp;child&nbsp;of&nbsp;the&nbsp;AggregationNode&nbsp;has&nbsp;been&nbsp;established.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;proof&nbsp;uses&nbsp;the&nbsp;final&nbsp;child’s&nbsp;OrderingScheme.&nbsp;For&nbsp;a&nbsp;particular
> &gt;&gt;&nbsp;aggregation:
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;second&nbsp;argument&nbsp;must&nbsp;be&nbsp;a&nbsp;directly&nbsp;addressable&nbsp;time_col&nbsp;symbol.
>
> &gt;&gt;&nbsp;Before&nbsp;time_col&nbsp;appears&nbsp;in&nbsp;the&nbsp;ordering&nbsp;prefix,&nbsp;only&nbsp;SQL&nbsp;grouping&nbsp;keys&nbsp;are
> &gt;&gt;&nbsp;allowed.
> &gt;&gt;&nbsp;time_col&nbsp;must&nbsp;use&nbsp;ascending&nbsp;order.
>
> &gt;&gt;&nbsp;Ordering&nbsp;symbols&nbsp;after&nbsp;time_col&nbsp;do&nbsp;not&nbsp;affect&nbsp;the&nbsp;proof.
>
> &gt;&gt;&nbsp;If&nbsp;the&nbsp;ordering&nbsp;is&nbsp;missing,&nbsp;uses&nbsp;descending&nbsp;time,&nbsp;contains&nbsp;a&nbsp;non-grouping
>
> &gt;&gt;&nbsp;symbol&nbsp;before&nbsp;time_col,&nbsp;or&nbsp;otherwise&nbsp;cannot&nbsp;be&nbsp;proven,&nbsp;the&nbsp;property&nbsp;is
> &gt;&gt;&nbsp;false.
>
> &gt;&gt;&nbsp;Arbitrary&nbsp;time&nbsp;expressions&nbsp;conservatively&nbsp;use&nbsp;the&nbsp;Naive&nbsp;implementation.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;This&nbsp;also&nbsp;means&nbsp;that&nbsp;Project,&nbsp;Exchange,&nbsp;Join,&nbsp;Union,&nbsp;HOP/TUMBLE,&nbsp;and&nbsp;other
>
> &gt;&gt;&nbsp;operators&nbsp;are&nbsp;handled&nbsp;through&nbsp;the&nbsp;ordering&nbsp;property&nbsp;of&nbsp;the&nbsp;finalized
>
> &gt;&gt;&nbsp;physical&nbsp;child.&nbsp;If&nbsp;they&nbsp;do&nbsp;not&nbsp;preserve&nbsp;and&nbsp;expose&nbsp;a&nbsp;sufficient
>
> &gt;&gt;&nbsp;OrderingScheme,&nbsp;the&nbsp;Ordered&nbsp;implementation&nbsp;is&nbsp;not&nbsp;selected.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Only&nbsp;the&nbsp;following&nbsp;condition&nbsp;enables&nbsp;the&nbsp;Ordered&nbsp;implementation:
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;step&nbsp;==&nbsp;SINGLE&nbsp;&amp;&amp;&nbsp;inputOrderedByTimeAscending
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;PARTIAL,&nbsp;INTERMEDIATE,&nbsp;and&nbsp;FINAL&nbsp;stages&nbsp;always&nbsp;use&nbsp;the&nbsp;Naive
> &gt;&gt;&nbsp;implementation.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;current&nbsp;version&nbsp;also&nbsp;disables&nbsp;aggregation&nbsp;pushdown&nbsp;to
>
> &gt;&gt;&nbsp;AggregationTableScanNode&nbsp;and&nbsp;ExternalTsFileAggregationScanNode&nbsp;for&nbsp;these
>
> &gt;&gt;&nbsp;functions.&nbsp;The&nbsp;explicit&nbsp;time_col&nbsp;may&nbsp;differ&nbsp;from&nbsp;the&nbsp;physical&nbsp;TIME&nbsp;column,
>
> &gt;&gt;&nbsp;and&nbsp;the&nbsp;functions&nbsp;require&nbsp;raw&nbsp;samples&nbsp;rather&nbsp;than&nbsp;file,&nbsp;chunk,&nbsp;or&nbsp;page
> &gt;&gt;&nbsp;statistics.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;Common&nbsp;runtime&nbsp;validation&nbsp;flow
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;A&nbsp;stateless&nbsp;RateFunctionValidation&nbsp;utility&nbsp;is&nbsp;now&nbsp;shared&nbsp;by&nbsp;Ordered/Naive,
>
> &gt;&gt;&nbsp;Table/Grouped,&nbsp;and&nbsp;the&nbsp;different&nbsp;aggregation&nbsp;stages.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;validation&nbsp;order&nbsp;and&nbsp;behavior&nbsp;are&nbsp;explicitly&nbsp;defined:
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Rows&nbsp;with&nbsp;NULL&nbsp;value_col&nbsp;are&nbsp;ignored.
>
> &gt;&gt;&nbsp;If&nbsp;value_col&nbsp;is&nbsp;non-NULL,&nbsp;the&nbsp;required&nbsp;time&nbsp;and&nbsp;window&nbsp;arguments&nbsp;must&nbsp;be
> &gt;&gt;&nbsp;non-NULL.
> &gt;&gt;&nbsp;NaN&nbsp;and&nbsp;Infinity&nbsp;are&nbsp;rejected.
>
> &gt;&gt;&nbsp;Negative&nbsp;values&nbsp;are&nbsp;rejected&nbsp;for&nbsp;rate(),&nbsp;increase(),&nbsp;and&nbsp;irate(),&nbsp;while
> &gt;&gt;&nbsp;delta()&nbsp;accepts&nbsp;negative&nbsp;values.
>
> &gt;&gt;&nbsp;window_start&nbsp;must&nbsp;be&nbsp;less&nbsp;than&nbsp;window_end.
>
> &gt;&gt;&nbsp;Samples&nbsp;must&nbsp;satisfy&nbsp;window_start&nbsp;<=&nbsp;time_col&nbsp;<&nbsp;window_end.
>
> &gt;&gt;&nbsp;Window&nbsp;boundaries&nbsp;must&nbsp;be&nbsp;consistent&nbsp;within&nbsp;the&nbsp;same&nbsp;SQL&nbsp;group.
> &gt;&gt;&nbsp;Duplicate&nbsp;timestamps&nbsp;are&nbsp;rejected.
>
> &gt;&gt;&nbsp;Ordered&nbsp;implementations&nbsp;also&nbsp;reject&nbsp;an&nbsp;unexpected&nbsp;decrease&nbsp;in&nbsp;timestamps.
>
> &gt;&gt;&nbsp;After&nbsp;filtering,&nbsp;fewer&nbsp;than&nbsp;two&nbsp;valid&nbsp;samples&nbsp;produce&nbsp;NULL.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Regarding&nbsp;NULL&nbsp;handling,&nbsp;I&nbsp;retained&nbsp;the&nbsp;requirement-level&nbsp;contract&nbsp;that
>
> &gt;&gt;&nbsp;only&nbsp;a&nbsp;NULL&nbsp;value_col&nbsp;causes&nbsp;a&nbsp;row&nbsp;to&nbsp;be&nbsp;ignored.&nbsp;A&nbsp;non-NULL&nbsp;value&nbsp;with&nbsp;a
>
> &gt;&gt;&nbsp;NULL&nbsp;time&nbsp;or&nbsp;required&nbsp;window&nbsp;boundary&nbsp;is&nbsp;treated&nbsp;as&nbsp;invalid&nbsp;input.&nbsp;This
>
> &gt;&gt;&nbsp;rule&nbsp;is&nbsp;now&nbsp;applied&nbsp;consistently&nbsp;in&nbsp;every&nbsp;execution&nbsp;path.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;Versioned&nbsp;Intermediate&nbsp;State&nbsp;protocol
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;exact&nbsp;BLOB&nbsp;formats&nbsp;are&nbsp;now&nbsp;specified&nbsp;as&nbsp;follows:
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;rate(),&nbsp;increase(),&nbsp;and&nbsp;delta():
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;version:int32
> &gt;&gt;&nbsp;windowStart:int64
> &gt;&gt;&nbsp;windowEnd:int64
> &gt;&gt;&nbsp;sampleCount:int32
>
> &gt;&gt;&nbsp;repeated&nbsp;{&nbsp;timestamp:int64,&nbsp;value:double&nbsp;}
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;irate():
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;version:int32
> &gt;&gt;&nbsp;sampleCount:int32
>
> &gt;&gt;&nbsp;repeated&nbsp;{&nbsp;timestamp:int64,&nbsp;value:double&nbsp;}
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;The&nbsp;initial&nbsp;protocol&nbsp;version&nbsp;is&nbsp;1.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;The&nbsp;state&nbsp;rules&nbsp;are&nbsp;now&nbsp;explicit:
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;A&nbsp;partial&nbsp;state&nbsp;with&nbsp;no&nbsp;valid&nbsp;samples&nbsp;is&nbsp;represented&nbsp;as&nbsp;NULL.
>
> &gt;&gt;&nbsp;A&nbsp;one-sample&nbsp;state&nbsp;is&nbsp;preserved&nbsp;and&nbsp;encoded&nbsp;normally.
> &gt;&gt;&nbsp;NULL&nbsp;intermediate&nbsp;positions&nbsp;are&nbsp;skipped.
>
> &gt;&gt;&nbsp;Window&nbsp;boundaries&nbsp;are&nbsp;checked&nbsp;for&nbsp;consistency&nbsp;when&nbsp;states&nbsp;are&nbsp;merged.
>
> &gt;&gt;&nbsp;Samples&nbsp;from&nbsp;different&nbsp;states&nbsp;are&nbsp;merged&nbsp;without&nbsp;relying&nbsp;on&nbsp;state&nbsp;arrival
> &gt;&gt;&nbsp;order.
>
> &gt;&gt;&nbsp;Duplicate&nbsp;timestamps&nbsp;are&nbsp;checked&nbsp;after&nbsp;all&nbsp;states&nbsp;have&nbsp;been&nbsp;merged&nbsp;and
> &gt;&gt;&nbsp;sorted.
>
> &gt;&gt;&nbsp;The&nbsp;codec&nbsp;validates&nbsp;the&nbsp;version,&nbsp;header&nbsp;and&nbsp;total&nbsp;length,&nbsp;sample&nbsp;count,
>
> &gt;&gt;&nbsp;window&nbsp;values,&nbsp;timestamps,&nbsp;and&nbsp;sample&nbsp;values&nbsp;before&nbsp;creating&nbsp;the&nbsp;decoded
> &gt;&gt;&nbsp;buffer.
>
> &gt;&gt;&nbsp;Serialized-size&nbsp;calculations&nbsp;use&nbsp;exact&nbsp;arithmetic&nbsp;and&nbsp;must&nbsp;fit&nbsp;the
> &gt;&gt;&nbsp;ByteBuffer&nbsp;integer&nbsp;capacity.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;I&nbsp;also&nbsp;corrected&nbsp;the&nbsp;TimeValueBuffer.merge()&nbsp;issue&nbsp;identified&nbsp;in&nbsp;the
>
> &gt;&gt;&nbsp;previous&nbsp;pseudocode:&nbsp;the&nbsp;original&nbsp;size&nbsp;is&nbsp;retained&nbsp;as&nbsp;the&nbsp;copy&nbsp;offset,&nbsp;and
>
> &gt;&gt;&nbsp;the&nbsp;size&nbsp;is&nbsp;updated&nbsp;only&nbsp;once&nbsp;after&nbsp;copying.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;Incremental&nbsp;grouped&nbsp;memory&nbsp;accounting
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Grouped&nbsp;Naive&nbsp;accumulators&nbsp;no&nbsp;longer&nbsp;traverse&nbsp;every&nbsp;non-empty&nbsp;group&nbsp;after
> &gt;&gt;&nbsp;each&nbsp;input&nbsp;batch.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;TimeValueBufferBigArray&nbsp;maintains&nbsp;buffersRetainedBytes&nbsp;incrementally.&nbsp;Only
>
> &gt;&gt;&nbsp;buffers&nbsp;modified&nbsp;by&nbsp;the&nbsp;current&nbsp;operation,&nbsp;together&nbsp;with&nbsp;any&nbsp;ObjectBigArray
>
> &gt;&gt;&nbsp;capacity&nbsp;change,&nbsp;contribute&nbsp;to&nbsp;the&nbsp;memory&nbsp;delta.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;As&nbsp;a&nbsp;result:
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Appending&nbsp;one&nbsp;sample&nbsp;has&nbsp;amortized&nbsp;O(1)&nbsp;accounting&nbsp;cost.
>
> &gt;&gt;&nbsp;Merging&nbsp;a&nbsp;state&nbsp;is&nbsp;proportional&nbsp;to&nbsp;the&nbsp;number&nbsp;of&nbsp;merged&nbsp;samples.
>
> &gt;&gt;&nbsp;Processing&nbsp;a&nbsp;batch&nbsp;is&nbsp;proportional&nbsp;to&nbsp;the&nbsp;positions&nbsp;or&nbsp;groups&nbsp;actually
> &gt;&gt;&nbsp;visited.
>
> &gt;&gt;&nbsp;There&nbsp;is&nbsp;no&nbsp;additional&nbsp;O(blockCount&nbsp;×&nbsp;groupCount)&nbsp;scan.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Final&nbsp;sorting&nbsp;is&nbsp;performed&nbsp;in&nbsp;place&nbsp;using&nbsp;introsort&nbsp;on&nbsp;the&nbsp;parallel
>
> &gt;&gt;&nbsp;timestamp&nbsp;and&nbsp;value&nbsp;arrays.&nbsp;Its&nbsp;worst-case&nbsp;time&nbsp;complexity&nbsp;is&nbsp;O(n&nbsp;log&nbsp;n),
> &gt;&gt;&nbsp;with&nbsp;O(log&nbsp;n)&nbsp;auxiliary&nbsp;space.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;Numerical&nbsp;edge&nbsp;cases
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;numerical&nbsp;rules&nbsp;have&nbsp;also&nbsp;been&nbsp;clarified:
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Timestamp&nbsp;subtraction&nbsp;uses&nbsp;BigInteger&nbsp;before&nbsp;conversion&nbsp;to&nbsp;seconds,
>
> &gt;&gt;&nbsp;avoiding&nbsp;long&nbsp;overflow&nbsp;while&nbsp;preserving&nbsp;exact&nbsp;tick&nbsp;differences.
>
> &gt;&gt;&nbsp;Window&nbsp;and&nbsp;sample&nbsp;intervals&nbsp;are&nbsp;validated&nbsp;before&nbsp;applying&nbsp;the&nbsp;increase&nbsp;==
> &gt;&gt;&nbsp;0&nbsp;shortcut.
>
> &gt;&gt;&nbsp;Intermediate&nbsp;and&nbsp;final&nbsp;arithmetic&nbsp;results&nbsp;are&nbsp;checked&nbsp;for&nbsp;finiteness.
>
> &gt;&gt;&nbsp;A&nbsp;non-finite&nbsp;durationToZero&nbsp;does&nbsp;not&nbsp;cause&nbsp;zero-point&nbsp;truncation&nbsp;and&nbsp;is
> &gt;&gt;&nbsp;not&nbsp;itself&nbsp;treated&nbsp;as&nbsp;an&nbsp;error.
>
> &gt;&gt;&nbsp;sampleCount&nbsp;uses&nbsp;int&nbsp;and&nbsp;is&nbsp;updated&nbsp;with&nbsp;exact&nbsp;overflow&nbsp;checks.&nbsp;The
>
> &gt;&gt;&nbsp;serialized&nbsp;state&nbsp;is&nbsp;also&nbsp;limited&nbsp;by&nbsp;the&nbsp;maximum&nbsp;ByteBuffer&nbsp;size.
>
> &gt;&gt;&nbsp;All&nbsp;input&nbsp;values&nbsp;are&nbsp;represented&nbsp;internally&nbsp;as&nbsp;double.&nbsp;Therefore,&nbsp;INT64
>
> &gt;&gt;&nbsp;values&nbsp;whose&nbsp;absolute&nbsp;value&nbsp;exceeds&nbsp;2^53&nbsp;follow&nbsp;IEEE&nbsp;754&nbsp;double&nbsp;semantics,
>
> &gt;&gt;&nbsp;and&nbsp;unit-level&nbsp;differences&nbsp;are&nbsp;not&nbsp;guaranteed&nbsp;to&nbsp;remain&nbsp;exact.&nbsp;This
> &gt;&gt;&nbsp;limitation&nbsp;is&nbsp;now&nbsp;documented&nbsp;explicitly.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;revised&nbsp;design&nbsp;continues&nbsp;to&nbsp;preserve&nbsp;complete&nbsp;samples&nbsp;during
>
> &gt;&gt;&nbsp;distributed&nbsp;aggregation&nbsp;and&nbsp;performs&nbsp;sorting,&nbsp;duplicate&nbsp;detection,
>
> &gt;&gt;&nbsp;counter-reset&nbsp;correction,&nbsp;and&nbsp;extrapolation&nbsp;only&nbsp;after&nbsp;all&nbsp;states&nbsp;have&nbsp;been
> &gt;&gt;&nbsp;merged.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;Best&nbsp;regards,
> &gt;&gt;&nbsp;Xinqi&nbsp;Zhao
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;原始邮件
> &gt;&gt;&nbsp;发件人:Yuan&nbsp;Tian&nbsp;<[email protected]&gt;
> &gt;&gt;&nbsp;发件时间:2026年7月17日&nbsp;11:57
> &gt;&gt;&nbsp;收件人:dev&nbsp;<[email protected]&gt;
>
> &gt;&gt;&nbsp;主题:Re:&nbsp;[DISCUSS]&nbsp;Technical&nbsp;design&nbsp;for&nbsp;rate(),&nbsp;irate(),&nbsp;increase(),&nbsp;and
> &gt;&gt;&nbsp;delta()&nbsp;aggregate&nbsp;functions
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;Hi&nbsp;Xinqi,
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Thanks&nbsp;for&nbsp;sharing&nbsp;the&nbsp;technical&nbsp;design.&nbsp;I&nbsp;reviewed&nbsp;the&nbsp;detailed&nbsp;design
>
> &gt;&gt;&nbsp;document&nbsp;and&nbsp;left&nbsp;several&nbsp;inline&nbsp;comments.&nbsp;Overall,&nbsp;reusing&nbsp;the&nbsp;existing
>
> &gt;&gt;&nbsp;table-model&nbsp;aggregation&nbsp;framework&nbsp;and&nbsp;preserving&nbsp;complete&nbsp;samples&nbsp;during
>
> &gt;&gt;&nbsp;distributed&nbsp;aggregation&nbsp;looks&nbsp;reasonable.&nbsp;Before&nbsp;implementation,&nbsp;I&nbsp;think
>
> &gt;&gt;&nbsp;the&nbsp;following&nbsp;points&nbsp;should&nbsp;be&nbsp;clarified&nbsp;or&nbsp;corrected.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;&nbsp;&nbsp;1.&nbsp;Accumulator&nbsp;organization
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;ordered&nbsp;and&nbsp;buffered&nbsp;modes&nbsp;maintain&nbsp;substantially&nbsp;different&nbsp;states&nbsp;and
>
> &gt;&gt;&nbsp;follow&nbsp;different&nbsp;processing&nbsp;paths.&nbsp;I&nbsp;suggest&nbsp;reconsidering&nbsp;whether&nbsp;both
>
> &gt;&gt;&nbsp;modes&nbsp;should&nbsp;live&nbsp;in&nbsp;the&nbsp;same&nbsp;concrete&nbsp;accumulator&nbsp;class.&nbsp;A&nbsp;common&nbsp;abstract
>
> &gt;&gt;&nbsp;base&nbsp;class&nbsp;could&nbsp;contain&nbsp;shared&nbsp;validation&nbsp;and&nbsp;calculation&nbsp;logic,&nbsp;while&nbsp;the
>
> &gt;&gt;&nbsp;ordered&nbsp;and&nbsp;buffered&nbsp;implementations&nbsp;could&nbsp;be&nbsp;separate&nbsp;subclasses.&nbsp;This&nbsp;may
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;reduce&nbsp;mode-specific&nbsp;branching&nbsp;and&nbsp;make&nbsp;their&nbsp;respective&nbsp;invariants&nbsp;clearer.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;2.&nbsp;Derivation&nbsp;of&nbsp;the&nbsp;ordered-input&nbsp;property
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;design&nbsp;says&nbsp;that&nbsp;the&nbsp;ordered&nbsp;implementation&nbsp;is&nbsp;selected&nbsp;when&nbsp;the
>
> &gt;&gt;&nbsp;planner&nbsp;can&nbsp;prove&nbsp;that&nbsp;samples&nbsp;are&nbsp;ordered&nbsp;by&nbsp;time_col,&nbsp;but&nbsp;it&nbsp;does&nbsp;not&nbsp;yet
> &gt;&gt;&nbsp;define&nbsp;how&nbsp;this&nbsp;proof&nbsp;is&nbsp;made.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;The&nbsp;design&nbsp;should&nbsp;specify:
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;At&nbsp;which&nbsp;physical-planning&nbsp;stage&nbsp;the&nbsp;property&nbsp;is&nbsp;derived.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;How&nbsp;per-group&nbsp;ordering,&nbsp;rather&nbsp;than&nbsp;only&nbsp;global&nbsp;ordering,&nbsp;is&nbsp;proven.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;How&nbsp;Project,&nbsp;Exchange,&nbsp;Join,&nbsp;Union,&nbsp;HOP/TUMBLE,&nbsp;and&nbsp;other&nbsp;operators
> &gt;&gt;&nbsp;&nbsp;&nbsp;affect&nbsp;the&nbsp;property.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Whether&nbsp;only&nbsp;a&nbsp;direct&nbsp;time_col&nbsp;symbol&nbsp;is&nbsp;supported;&nbsp;an&nbsp;arbitrary&nbsp;time
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;expression&nbsp;should&nbsp;conservatively&nbsp;fall&nbsp;back&nbsp;to&nbsp;the&nbsp;buffered&nbsp;implementation.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;That&nbsp;the&nbsp;property&nbsp;must&nbsp;be&nbsp;false&nbsp;whenever&nbsp;ordering&nbsp;cannot&nbsp;be&nbsp;proven.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Although&nbsp;inputOrderedByTimeAscending&nbsp;is&nbsp;not&nbsp;meaningful&nbsp;for&nbsp;every
>
> &gt;&gt;&nbsp;aggregation&nbsp;function,&nbsp;keeping&nbsp;it&nbsp;in&nbsp;AggregationNode.Aggregation&nbsp;as&nbsp;a
>
> &gt;&gt;&nbsp;serialized&nbsp;per-aggregation&nbsp;physical&nbsp;hint&nbsp;seems&nbsp;acceptable&nbsp;if&nbsp;its&nbsp;scope&nbsp;and
>
> &gt;&gt;&nbsp;exact&nbsp;meaning&nbsp;are&nbsp;clearly&nbsp;documented.&nbsp;The&nbsp;derivation&nbsp;should&nbsp;happen&nbsp;after
>
> &gt;&gt;&nbsp;the&nbsp;physical&nbsp;input&nbsp;is&nbsp;finalized&nbsp;rather&nbsp;than&nbsp;during&nbsp;logical&nbsp;function
> &gt;&gt;&nbsp;analysis.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;&nbsp;&nbsp;3.&nbsp;Runtime&nbsp;validation&nbsp;contract
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;design&nbsp;should&nbsp;define&nbsp;a&nbsp;common&nbsp;validation&nbsp;flow&nbsp;shared&nbsp;by
>
> &gt;&gt;&nbsp;ordered/buffered,&nbsp;Table/Grouped,&nbsp;and&nbsp;SINGLE/PARTIAL/FINAL&nbsp;paths.&nbsp;In
> &gt;&gt;&nbsp;particular:
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Ignore&nbsp;samples&nbsp;whose&nbsp;value&nbsp;or&nbsp;time&nbsp;is&nbsp;NULL&nbsp;before&nbsp;validating&nbsp;valid
> &gt;&gt;&nbsp;&nbsp;&nbsp;samples.
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Reject&nbsp;NaN&nbsp;and&nbsp;Infinity.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Reject&nbsp;negative&nbsp;counter&nbsp;values&nbsp;for&nbsp;rate(),&nbsp;increase(),&nbsp;and&nbsp;irate();
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;delta()&nbsp;may&nbsp;accept&nbsp;negative&nbsp;values.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Require&nbsp;non-NULL&nbsp;window&nbsp;bounds&nbsp;and&nbsp;window_start&nbsp;<&nbsp;window_end.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Require&nbsp;sample&nbsp;timestamps&nbsp;to&nbsp;be&nbsp;within&nbsp;[window_start,&nbsp;window_end).
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Require&nbsp;consistent&nbsp;window&nbsp;bounds&nbsp;within&nbsp;the&nbsp;same&nbsp;group.
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Reject&nbsp;duplicate&nbsp;timestamps.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Return&nbsp;NULL&nbsp;when&nbsp;fewer&nbsp;than&nbsp;two&nbsp;valid&nbsp;samples&nbsp;remain.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;Without&nbsp;one&nbsp;explicitly&nbsp;defined&nbsp;common&nbsp;entry&nbsp;point&nbsp;and&nbsp;validation&nbsp;order,&nbsp;the
>
> &gt;&gt;&nbsp;different&nbsp;accumulator&nbsp;paths&nbsp;may&nbsp;produce&nbsp;inconsistent&nbsp;behavior.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;4.&nbsp;Intermediate-state&nbsp;format&nbsp;and&nbsp;merge&nbsp;behavior
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;exact&nbsp;binary&nbsp;format&nbsp;should&nbsp;be&nbsp;specified,&nbsp;for&nbsp;example:
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;rate/increase/delta:
>
> &gt;&gt;&nbsp;version&nbsp;|&nbsp;windowStart&nbsp;|&nbsp;windowEnd&nbsp;|&nbsp;sampleCount&nbsp;|&nbsp;samples
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;irate:
> &gt;&gt;&nbsp;version&nbsp;|&nbsp;sampleCount&nbsp;|&nbsp;samples
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;The&nbsp;design&nbsp;should&nbsp;also&nbsp;define:
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Whether&nbsp;a&nbsp;partial&nbsp;state&nbsp;with&nbsp;no&nbsp;valid&nbsp;samples&nbsp;is&nbsp;NULL&nbsp;or&nbsp;has&nbsp;sampleCount
> &gt;&gt;&nbsp;&nbsp;&nbsp;=&nbsp;0.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;How&nbsp;a&nbsp;one-sample&nbsp;partial&nbsp;state&nbsp;is&nbsp;preserved.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;How&nbsp;addIntermediate()&nbsp;handles&nbsp;NULL&nbsp;positions.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;How&nbsp;inconsistent&nbsp;window&nbsp;bounds&nbsp;and&nbsp;duplicate&nbsp;timestamps&nbsp;across&nbsp;states
> &gt;&gt;&nbsp;&nbsp;&nbsp;are&nbsp;handled.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;How&nbsp;unknown&nbsp;versions,&nbsp;truncated&nbsp;states,&nbsp;trailing&nbsp;bytes,&nbsp;and&nbsp;oversized
> &gt;&gt;&nbsp;&nbsp;&nbsp;BLOBs&nbsp;are&nbsp;handled.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;There&nbsp;is&nbsp;also&nbsp;a&nbsp;correctness&nbsp;issue&nbsp;in&nbsp;the&nbsp;current&nbsp;TimeValueBuffer.merge()
>
> &gt;&gt;&nbsp;pseudocode:&nbsp;it&nbsp;assigns&nbsp;size&nbsp;=&nbsp;mergedSize&nbsp;before&nbsp;copying&nbsp;and&nbsp;then&nbsp;copies
>
> &gt;&gt;&nbsp;from&nbsp;offset&nbsp;size,&nbsp;which&nbsp;will&nbsp;cause&nbsp;an&nbsp;out-of-bounds&nbsp;access.&nbsp;The&nbsp;old&nbsp;size
>
> &gt;&gt;&nbsp;should&nbsp;be&nbsp;retained&nbsp;as&nbsp;the&nbsp;copy&nbsp;offset,&nbsp;and&nbsp;size&nbsp;should&nbsp;be&nbsp;updated&nbsp;only&nbsp;once
> &gt;&gt;&nbsp;after&nbsp;the&nbsp;copy.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;&nbsp;&nbsp;5.&nbsp;Grouped&nbsp;memory&nbsp;accounting
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;proposed&nbsp;grouped&nbsp;implementation&nbsp;recalculates&nbsp;retained&nbsp;memory&nbsp;by
>
> &gt;&gt;&nbsp;traversing&nbsp;every&nbsp;non-empty&nbsp;group&nbsp;after&nbsp;each&nbsp;input&nbsp;or&nbsp;intermediate&nbsp;batch.
>
> &gt;&gt;&nbsp;This&nbsp;adds&nbsp;approximately&nbsp;O(blockCount&nbsp;×&nbsp;groupCount)&nbsp;work&nbsp;and&nbsp;may&nbsp;approach
> &gt;&gt;&nbsp;O(n²)&nbsp;in&nbsp;unfavorable&nbsp;cases.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;It&nbsp;would&nbsp;be&nbsp;better&nbsp;to&nbsp;maintain&nbsp;the&nbsp;retained-size&nbsp;delta&nbsp;incrementally&nbsp;for
>
> &gt;&gt;&nbsp;only&nbsp;the&nbsp;buffers&nbsp;changed&nbsp;by&nbsp;the&nbsp;current&nbsp;batch,&nbsp;including&nbsp;any&nbsp;ObjectBigArray
> &gt;&gt;&nbsp;capacity&nbsp;change.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;&nbsp;&nbsp;6.&nbsp;Numerical&nbsp;edge&nbsp;cases
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;The&nbsp;extrapolation&nbsp;design&nbsp;should&nbsp;also&nbsp;address&nbsp;the&nbsp;following&nbsp;cases:
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Math.subtractExact(later,&nbsp;earlier)&nbsp;may&nbsp;overflow&nbsp;for&nbsp;two&nbsp;otherwise
> &gt;&gt;&nbsp;&nbsp;&nbsp;valid&nbsp;INT64&nbsp;timestamps.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;The&nbsp;final&nbsp;division&nbsp;performed&nbsp;by&nbsp;rate()&nbsp;or&nbsp;irate()&nbsp;may&nbsp;still&nbsp;produce
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;Infinity&nbsp;even&nbsp;if&nbsp;the&nbsp;extrapolated&nbsp;intermediate&nbsp;result&nbsp;is&nbsp;finite.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;The&nbsp;increase&nbsp;==&nbsp;0&nbsp;shortcut&nbsp;should&nbsp;occur&nbsp;only&nbsp;after&nbsp;validating&nbsp;the
> &gt;&gt;&nbsp;&nbsp;&nbsp;window&nbsp;and&nbsp;sample&nbsp;interval.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;Converting&nbsp;INT64&nbsp;values&nbsp;greater&nbsp;than&nbsp;2^53&nbsp;to&nbsp;double&nbsp;can&nbsp;lose&nbsp;unit
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;increments;&nbsp;the&nbsp;intended&nbsp;semantics&nbsp;should&nbsp;be&nbsp;documented.
>
> &gt;&gt;&nbsp;&nbsp;&nbsp;-&nbsp;The&nbsp;upper&nbsp;bound&nbsp;implied&nbsp;by&nbsp;using&nbsp;an&nbsp;int&nbsp;for&nbsp;sampleCount&nbsp;should&nbsp;be
> &gt;&gt;&nbsp;&nbsp;&nbsp;defined.
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;These&nbsp;points&nbsp;do&nbsp;not&nbsp;change&nbsp;the&nbsp;overall&nbsp;direction&nbsp;of&nbsp;the&nbsp;design,&nbsp;but&nbsp;they
>
> &gt;&gt;&nbsp;affect&nbsp;correctness,&nbsp;consistency,&nbsp;and&nbsp;performance.&nbsp;I&nbsp;suggest&nbsp;making&nbsp;them
>
> &gt;&gt;&nbsp;explicit&nbsp;in&nbsp;the&nbsp;technical&nbsp;design&nbsp;before&nbsp;implementation&nbsp;begins.
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;Best&nbsp;regards,
> &gt;&gt;&nbsp;---------------------
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;Yuan&nbsp;Tian
> &gt;&gt;&nbsp;
>
> &gt;&gt;&nbsp;On&nbsp;Fri,&nbsp;Jul&nbsp;17,&nbsp;2026&nbsp;at&nbsp;11:02 
> AM&nbsp;Xinqi&nbsp;Zhao&nbsp;<
> [email protected]&gt;&nbsp;wrote:
> &gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Hi&nbsp;IoTDB&nbsp;community,
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Following&nbsp;the&nbsp;previous&nbsp;requirements&nbsp;discussion,&nbsp;I&nbsp;have&nbsp;prepared&nbsp;an&nbsp;initial
>
> &gt;&gt;&gt;&nbsp;technical&nbsp;design&nbsp;for&nbsp;adding&nbsp;the&nbsp;Prometheus-like&nbsp;rate(),&nbsp;irate(),
>
> &gt;&gt;&gt;&nbsp;increase(),&nbsp;and&nbsp;delta()&nbsp;aggregate&nbsp;functions&nbsp;to&nbsp;the&nbsp;IoTDB&nbsp;table&nbsp;model.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Related&nbsp;issue:
> &gt;&gt;&gt;&nbsp;https://github.com/apache/iotdb/issues/17976
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;The&nbsp;main&nbsp;design&nbsp;is&nbsp;summarized&nbsp;below.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Integration&nbsp;with&nbsp;the&nbsp;existing&nbsp;aggregation&nbsp;framework
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;The&nbsp;four&nbsp;functions&nbsp;will&nbsp;be&nbsp;implemented&nbsp;entirely&nbsp;within&nbsp;the&nbsp;existing
>
> &gt;&gt;&gt;&nbsp;table-model&nbsp;aggregation&nbsp;framework.&nbsp;No&nbsp;new&nbsp;SQL&nbsp;execution&nbsp;layer&nbsp;or
>
> &gt;&gt;&gt;&nbsp;third-party&nbsp;dependency&nbsp;will&nbsp;be&nbsp;introduced.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Both&nbsp;execution&nbsp;paths&nbsp;will&nbsp;be&nbsp;supported:
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;TableAccumulator&nbsp;for&nbsp;global&nbsp;aggregation&nbsp;and&nbsp;streaming&nbsp;aggregation&nbsp;when
> &gt;&gt;&gt;&nbsp;groups&nbsp;are&nbsp;fully&nbsp;ordered.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;GroupedAccumulator&nbsp;for&nbsp;HashAggregationOperator&nbsp;and
> &gt;&gt;&gt;&nbsp;StreamingHashAggregationOperator.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Each&nbsp;function&nbsp;will&nbsp;provide&nbsp;both&nbsp;TableAccumulator&nbsp;and&nbsp;GroupedAccumulator
> &gt;&gt;&gt;&nbsp;implementations.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;The&nbsp;signatures&nbsp;are:
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;rate(value_col,&nbsp;time_col,&nbsp;window_start,&nbsp;window_end)
>
> &gt;&gt;&gt;&nbsp;increase(value_col,&nbsp;time_col,&nbsp;window_start,&nbsp;window_end)
> &gt;&gt;&gt;&nbsp;irate(value_col,&nbsp;time_col)
>
> &gt;&gt;&gt;&nbsp;delta(value_col,&nbsp;time_col,&nbsp;window_start,&nbsp;window_end)
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;The&nbsp;value&nbsp;column&nbsp;supports&nbsp;INT32,&nbsp;INT64,&nbsp;FLOAT,&nbsp;and&nbsp;DOUBLE.&nbsp;Values&nbsp;are
> &gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;converted&nbsp;to&nbsp;double&nbsp;internally,&nbsp;and&nbsp;all&nbsp;four&nbsp;functions&nbsp;return&nbsp;DOUBLE.&nbsp;Time
>
> &gt;&gt;&gt;&nbsp;arguments&nbsp;support&nbsp;TIMESTAMP&nbsp;and&nbsp;INT64.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Ordered&nbsp;and&nbsp;unordered&nbsp;implementations
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Each&nbsp;accumulator&nbsp;will&nbsp;support&nbsp;two&nbsp;internal&nbsp;modes&nbsp;rather&nbsp;than&nbsp;introducing
>
> &gt;&gt;&gt;&nbsp;separate&nbsp;Ordered&nbsp;and&nbsp;Naive&nbsp;accumulator&nbsp;classes.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;When&nbsp;the&nbsp;aggregation&nbsp;step&nbsp;is&nbsp;SINGLE&nbsp;and&nbsp;the&nbsp;planner&nbsp;can&nbsp;prove&nbsp;that&nbsp;samples
>
> &gt;&gt;&gt;&nbsp;within&nbsp;each&nbsp;group&nbsp;are&nbsp;ordered&nbsp;by&nbsp;time_col,&nbsp;the&nbsp;accumulator&nbsp;will&nbsp;use&nbsp;a
>
> &gt;&gt;&gt;&nbsp;streaming&nbsp;implementation&nbsp;with&nbsp;fixed-size&nbsp;state:
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Time&nbsp;complexity:&nbsp;O(n)
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Additional&nbsp;space&nbsp;per&nbsp;group:&nbsp;O(1)
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Otherwise,&nbsp;the&nbsp;accumulator&nbsp;will&nbsp;buffer&nbsp;all&nbsp;valid&nbsp;samples&nbsp;and&nbsp;sort&nbsp;them
> &gt;&gt;&gt;&nbsp;before&nbsp;the&nbsp;final&nbsp;calculation:
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Time&nbsp;complexity:&nbsp;O(n&nbsp;log&nbsp;n)
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Additional&nbsp;space&nbsp;per&nbsp;group:&nbsp;O(n)
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;The&nbsp;two&nbsp;modes&nbsp;will&nbsp;have&nbsp;identical&nbsp;function&nbsp;semantics,&nbsp;validation&nbsp;rules,
> &gt;&gt;&gt;&nbsp;and&nbsp;results.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;A&nbsp;new&nbsp;inputOrderedByTimeAscending&nbsp;property&nbsp;will&nbsp;be&nbsp;added&nbsp;to
>
> &gt;&gt;&gt;&nbsp;AggregationNode.Aggregation.&nbsp;The&nbsp;ordered&nbsp;implementation&nbsp;will&nbsp;be&nbsp;selected
> &gt;&gt;&gt;&nbsp;only&nbsp;when:
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;step&nbsp;==&nbsp;SINGLE&nbsp;&amp;amp;&amp;amp;&nbsp;inputOrderedByTimeAscending
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;PARTIAL,&nbsp;INTERMEDIATE,&nbsp;and&nbsp;FINAL&nbsp;aggregation&nbsp;stages&nbsp;will&nbsp;always&nbsp;use&nbsp;the
>
> &gt;&gt;&gt;&nbsp;buffered&nbsp;implementation&nbsp;because&nbsp;they&nbsp;need&nbsp;to&nbsp;generate,&nbsp;merge,&nbsp;or&nbsp;consume
> &gt;&gt;&gt;&nbsp;intermediate&nbsp;states.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;The&nbsp;ordered&nbsp;mode&nbsp;will&nbsp;still&nbsp;perform&nbsp;runtime&nbsp;checks&nbsp;for&nbsp;duplicate
>
> &gt;&gt;&gt;&nbsp;timestamps&nbsp;and&nbsp;unexpected&nbsp;out-of-order&nbsp;input.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Accumulator&nbsp;organization
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;rate()&nbsp;and&nbsp;increase()&nbsp;will&nbsp;share&nbsp;common&nbsp;base&nbsp;classes&nbsp;because&nbsp;they&nbsp;use&nbsp;the
>
> &gt;&gt;&gt;&nbsp;same&nbsp;counter-reset&nbsp;correction&nbsp;and&nbsp;boundary-extrapolation&nbsp;logic.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;The&nbsp;main&nbsp;TableAccumulator&nbsp;classes&nbsp;will&nbsp;include:
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;AbstractRateIncreaseAccumulator
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;RateAccumulator
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;IncreaseAccumulator
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;IrateAccumulator
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;DeltaAccumulator
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Equivalent&nbsp;GroupedAccumulator&nbsp;classes&nbsp;will&nbsp;maintain&nbsp;state&nbsp;independently
> &gt;&gt;&gt;&nbsp;for&nbsp;each&nbsp;groupId.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;In&nbsp;ordered&nbsp;mode,&nbsp;the&nbsp;accumulators&nbsp;retain&nbsp;only&nbsp;fixed&nbsp;state&nbsp;such&nbsp;as&nbsp;the
>
> &gt;&gt;&gt;&nbsp;first,&nbsp;previous,&nbsp;and&nbsp;last&nbsp;samples,&nbsp;sample&nbsp;count,&nbsp;corrected&nbsp;increase,&nbsp;and
> &gt;&gt;&gt;&nbsp;window&nbsp;boundaries.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;In&nbsp;unordered&nbsp;mode,&nbsp;samples&nbsp;will&nbsp;be&nbsp;stored&nbsp;in&nbsp;a&nbsp;new&nbsp;TimeValueBuffer.
>
> &gt;&gt;&gt;&nbsp;Grouped&nbsp;accumulators&nbsp;will&nbsp;use&nbsp;TimeValueBufferBigArray&nbsp;to&nbsp;maintain&nbsp;one
> &gt;&gt;&gt;&nbsp;buffer&nbsp;per&nbsp;groupId.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Intermediate-state&nbsp;handling
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;For&nbsp;distributed&nbsp;aggregation,&nbsp;PARTIAL,&nbsp;INTERMEDIATE,&nbsp;and&nbsp;FINAL&nbsp;stages&nbsp;must
>
> &gt;&gt;&gt;&nbsp;preserve&nbsp;the&nbsp;complete&nbsp;sample&nbsp;sequence&nbsp;because&nbsp;counter-reset&nbsp;detection,
> &gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;duplicate-timestamp&nbsp;validation,&nbsp;and&nbsp;the&nbsp;final&nbsp;result&nbsp;depend&nbsp;on&nbsp;global&nbsp;time
> &gt;&gt;&gt;&nbsp;ordering.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;The&nbsp;intermediate&nbsp;state&nbsp;will&nbsp;contain:
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;A&nbsp;state&nbsp;version
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;window_start&nbsp;and&nbsp;window_end,&nbsp;except&nbsp;for&nbsp;irate()
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;The&nbsp;number&nbsp;of&nbsp;valid&nbsp;samples
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;All&nbsp;timestamp/value&nbsp;pairs
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;PARTIAL&nbsp;stages&nbsp;collect&nbsp;and&nbsp;serialize&nbsp;their&nbsp;samples&nbsp;without&nbsp;calculating&nbsp;a
> &gt;&gt;&gt;&nbsp;final&nbsp;result.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;INTERMEDIATE&nbsp;stages&nbsp;deserialize&nbsp;and&nbsp;merge&nbsp;sample&nbsp;buffers&nbsp;without&nbsp;sorting
> &gt;&gt;&gt;&nbsp;them.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;The&nbsp;FINAL&nbsp;stage&nbsp;merges&nbsp;all&nbsp;states,&nbsp;sorts&nbsp;the&nbsp;complete&nbsp;sample&nbsp;set&nbsp;by
>
> &gt;&gt;&gt;&nbsp;timestamp,&nbsp;checks&nbsp;for&nbsp;duplicate&nbsp;timestamps,&nbsp;and&nbsp;then&nbsp;performs&nbsp;the&nbsp;final
> &gt;&gt;&gt;&nbsp;calculation.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Deserialization&nbsp;will&nbsp;validate&nbsp;the&nbsp;sample&nbsp;count&nbsp;and&nbsp;serialized&nbsp;length&nbsp;to
> &gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;reject&nbsp;corrupted&nbsp;intermediate&nbsp;states&nbsp;and&nbsp;prevent&nbsp;invalid&nbsp;memory&nbsp;allocation.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Memory&nbsp;management
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;The&nbsp;unordered&nbsp;implementation&nbsp;will&nbsp;integrate&nbsp;with&nbsp;the&nbsp;existing&nbsp;query
>
> &gt;&gt;&gt;&nbsp;memory-management&nbsp;mechanism,&nbsp;following&nbsp;a&nbsp;design&nbsp;similar&nbsp;to&nbsp;the&nbsp;exact
> &gt;&gt;&gt;&nbsp;percentile()&nbsp;accumulator.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;TimeValueBuffer&nbsp;and&nbsp;TimeValueBufferBigArray&nbsp;will&nbsp;report&nbsp;their&nbsp;retained
>
> &gt;&gt;&gt;&nbsp;memory.&nbsp;Accumulators&nbsp;will&nbsp;use&nbsp;MemoryReservationManager&nbsp;to&nbsp;reserve&nbsp;or
>
> &gt;&gt;&gt;&nbsp;release&nbsp;the&nbsp;difference&nbsp;whenever&nbsp;buffers&nbsp;grow,&nbsp;merge,&nbsp;or&nbsp;shrink.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;reset()&nbsp;will&nbsp;clear&nbsp;the&nbsp;calculation&nbsp;state,&nbsp;shrink&nbsp;oversized&nbsp;internal&nbsp;arrays
>
> &gt;&gt;&gt;&nbsp;to&nbsp;their&nbsp;initial&nbsp;capacity,&nbsp;and&nbsp;release&nbsp;the&nbsp;corresponding&nbsp;query&nbsp;memory.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Shared&nbsp;extrapolation&nbsp;logic
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;A&nbsp;shared&nbsp;ExtrapolationUtil&nbsp;will&nbsp;implement&nbsp;the&nbsp;boundary-extrapolation
>
> &gt;&gt;&gt;&nbsp;algorithm&nbsp;used&nbsp;by&nbsp;rate(),&nbsp;increase(),&nbsp;and&nbsp;delta().&nbsp;It&nbsp;will&nbsp;be&nbsp;responsible
> &gt;&gt;&gt;&nbsp;for:
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Converting&nbsp;timestamp&nbsp;differences&nbsp;to&nbsp;seconds&nbsp;according&nbsp;to&nbsp;the&nbsp;current
> &gt;&gt;&gt;&nbsp;timestamp_precision
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Calculating&nbsp;the&nbsp;average&nbsp;sample&nbsp;interval
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Applying&nbsp;the&nbsp;1.1-times&nbsp;extrapolation&nbsp;threshold
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Limiting&nbsp;extrapolation&nbsp;to&nbsp;half&nbsp;an&nbsp;average&nbsp;interval&nbsp;when&nbsp;a&nbsp;boundary&nbsp;is&nbsp;too
> &gt;&gt;&gt;&nbsp;far&nbsp;away
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Applying&nbsp;counter&nbsp;zero-point&nbsp;protection&nbsp;for&nbsp;rate()&nbsp;and&nbsp;increase()
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Calculating&nbsp;and&nbsp;validating&nbsp;the&nbsp;final&nbsp;extrapolation&nbsp;factor
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Counter-reset&nbsp;detection&nbsp;and&nbsp;sample&nbsp;traversal&nbsp;will&nbsp;remain&nbsp;in&nbsp;the
>
> &gt;&gt;&gt;&nbsp;accumulators&nbsp;rather&nbsp;than&nbsp;in&nbsp;ExtrapolationUtil.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;rate()&nbsp;will&nbsp;divide&nbsp;the&nbsp;extrapolated&nbsp;increase&nbsp;by&nbsp;the&nbsp;complete&nbsp;window
>
> &gt;&gt;&gt;&nbsp;duration.&nbsp;increase()&nbsp;will&nbsp;return&nbsp;the&nbsp;extrapolated&nbsp;increase&nbsp;directly.
>
> &gt;&gt;&gt;&nbsp;delta()&nbsp;will&nbsp;extrapolate&nbsp;the&nbsp;raw&nbsp;difference&nbsp;between&nbsp;the&nbsp;last&nbsp;and&nbsp;first
>
> &gt;&gt;&gt;&nbsp;values&nbsp;without&nbsp;counter&nbsp;zero-point&nbsp;protection.&nbsp;irate()&nbsp;will&nbsp;use&nbsp;only&nbsp;the
>
> &gt;&gt;&gt;&nbsp;final&nbsp;two&nbsp;samples&nbsp;and&nbsp;will&nbsp;not&nbsp;perform&nbsp;boundary&nbsp;extrapolation.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;All&nbsp;time&nbsp;conversions&nbsp;will&nbsp;respect&nbsp;the&nbsp;configured&nbsp;ms,&nbsp;us,&nbsp;or&nbsp;ns&nbsp;timestamp
>
> &gt;&gt;&gt;&nbsp;precision,&nbsp;while&nbsp;rate()&nbsp;and&nbsp;irate()&nbsp;will&nbsp;always&nbsp;return&nbsp;values&nbsp;per&nbsp;second.
> &gt;&gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;Please&nbsp;review&nbsp;this&nbsp;initial&nbsp;design,&nbsp;especially&nbsp;the&nbsp;ordered-input&nbsp;property,
> &gt;&gt;&nbsp;
>
> &gt;&gt;&gt;&nbsp;the&nbsp;complete-sample&nbsp;intermediate&nbsp;state,&nbsp;and&nbsp;the&nbsp;memory-management&nbsp;approach.
>
> &gt;&gt;&gt;&nbsp;Any&nbsp;comments&nbsp;or&nbsp;alternative&nbsp;suggestions&nbsp;are&nbsp;welcome.
> &gt;&gt;&gt;&nbsp;
> &gt;&gt;&gt;&nbsp;Best&nbsp;regards,
> &gt;&gt;&gt;&nbsp;Xinqi&nbsp;Zhao
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;
> &gt;&gt;&nbsp;

Reply via email to