Class StreamDemand
head N bounds the PULL (decision 10, rule B) - use this, never
re-derive which heads gate a loop or how the gate is folded into a loop condition.
Every head in a segment stops the pull once it has its N items. A segment runs from the nearest
upstream stage that must see everything (sort, tail, join, and group/split/async, which are lowered as
drains) - or the source - down to the next such stage. A must-drain stage always consumes its whole input;
a head after it limits only what it emits, so it gates the drain's EMISSION loop, never the drain.
The gate is ordinary IR: each loop condition becomes c1 < l1 AND (c2 < l2 AND ... hasNext()) as
nested short-circuit LOGICAL_AND blocks, the counters FIRST, so hasNext()/next() are never
called once any head is satisfied. That ordering is backend Contract 12: no back end may hoist, prefetch or
speculatively call hasNext() - on an unbounded or infinite source it blocks or never ends.
Which heads gate a loop are PullBoundingHeads (and AsyncCappingHeads for an async), where
a segment ends DemandSegmentEnd - held instances, one question each; this class folds them into the
loop's condition.
-
Field Summary
Fields inherited from class AbstractStreamStageGenerator
generators, listBufferCalls, symbolTypeOrException, valuePromoterFields inherited from class AbstractGenerator
stackContext, typeNameOrException, variableNameForIR -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) StringappendBoundedCondition(List<IRInstr> conditionEvaluation, List<IRInstr> leftInstructions, String leftResult, String leftPrimitive, List<IRInstr> rightInstructions, String rightResult, String scopeId, DebugInfo debugInfo) Append a short-circuitLEFT AND RIGHTBoolean condition toconditionEvaluationand return the combined Boolean result variable.(package private) StringappendDemandCondition(List<IRInstr> conditionEvaluation, List<StageState.Counter> bounds, List<IRInstr> rightInstructions, String rightResult, String scopeId, DebugInfo debugInfo) Append the demand-bounded conditionc1 < l1 AND (... AND right)toconditionEvaluationand return its Boolean result.(package private) StringappendDemandOverPrimitive(List<IRInstr> condition, List<StageState.Counter> heads, List<IRInstr> primitiveInstructions, String primitiveResult, String scopeId, DebugInfo debugInfo) Gate a loop whose continuation is a runtime helper's PRIMITIVEhasNext-style call (Ek9Group.hasNextGroup,Ek9Async.hasNext): with no heads the condition is unchanged; otherwise the primitive is lifted to a Boolean (Boolean._of) so it can be the right operand of the demand AND.(package private) FreshBooleanOperandcontinueCondition(List<StageState.Counter> heads, String scopeId, DebugInfo debugInfo) The demand condition of a loop whose own continuation is not ahasNext()- aforrange, whose range test the back end evaluates itself.Methods inherited from class AbstractStreamStageGenerator
addManagedCall, borrowedBy, concrete, counterBelowLimit, emitStageFunctionOperand, evaluateExpressionOperand, extractPrimitive, gate, generateCounterDelta, generateTerminalPipe, loadManagedLiteral, ownedBy, publishAndContinue, publishCallResultAndContinue, rebind, rebindToCallResult, rebindToCastCallResult, returnTypeOf, streamFunctionCall
-
Constructor Details
-
StreamDemand
StreamDemand(IRGenerationContext stackContext, GeneratorSet generators)
-
-
Method Details
-
appendDemandCondition
String appendDemandCondition(List<IRInstr> conditionEvaluation, List<StageState.Counter> bounds, List<IRInstr> rightInstructions, String rightResult, String scopeId, DebugInfo debugInfo) Append the demand-bounded conditionc1 < l1 AND (... AND right)toconditionEvaluationand return its Boolean result. With no bounds,rightis appended unchanged (byte-identical to an ungated loop).boundsare counter/limit pairs: the heads, or the async window's in-flight bound. -
continueCondition
FreshBooleanOperand continueCondition(List<StageState.Counter> heads, String scopeId, DebugInfo debugInfo) The demand condition of a loop whose own continuation is not ahasNext()- aforrange, whose range test the back end evaluates itself. Returns the heads alone (c1 < l1 AND ...) in their own scope-free instruction list, or null when no head bounds the loop. -
appendDemandOverPrimitive
String appendDemandOverPrimitive(List<IRInstr> condition, List<StageState.Counter> heads, List<IRInstr> primitiveInstructions, String primitiveResult, String scopeId, DebugInfo debugInfo) Gate a loop whose continuation is a runtime helper's PRIMITIVEhasNext-style call (Ek9Group.hasNextGroup,Ek9Async.hasNext): with no heads the condition is unchanged; otherwise the primitive is lifted to a Boolean (Boolean._of) so it can be the right operand of the demand AND. Returns the {primitive} to branch on, appending everything tocondition. -
appendBoundedCondition
String appendBoundedCondition(List<IRInstr> conditionEvaluation, List<IRInstr> leftInstructions, String leftResult, String leftPrimitive, List<IRInstr> rightInstructions, String rightResult, String scopeId, DebugInfo debugInfo) Append a short-circuitLEFT AND RIGHTBoolean condition toconditionEvaluationand return the combined Boolean result variable. RIGHT is evaluated ONLY when LEFT's primitive is true (LOGICAL_AND_BLOCK short-circuit). This is the generic two-operand AND-block; callers build LEFT (the short-circuit decision: head'scounter < limit, the window'sinFlight < W, etc.) and pass its result+primitive, plus the RIGHT operand's instructions+result (e.g. the managed hasNext()). MirrorsGuardedConditionEvaluator's guard-into-condition fold.
-