/** * @inheritDoc As the accumulate node will always generate a resulting tuple, we must always * destroy it */ public void retractLeftTuple( final LeftTuple leftTuple, final PropagationContext context, final InternalWorkingMemory workingMemory) { final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory(this); if (leftTuple.getMemory().isStagingMemory()) { leftTuple.getMemory().remove(leftTuple); } else { ((BetaMemory) memory.getBetaMemory()).getLeftTupleMemory().remove(leftTuple); } leftTuple.setMemory(null); final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject(); if (accctx.getAction() != null) { // there is a scheduled activation, we must cancel it context.removeInsertAction(accctx.getAction()); } leftTuple.setObject(null); removePreviousMatchesForLeftTuple(leftTuple, workingMemory, memory, accctx); if (accctx.propagated) { // if tuple was previously propagated, retract it and destroy result fact handle this.sink.propagateRetractLeftTupleDestroyRightTuple(leftTuple, context, workingMemory); } else { // if not propagated, just destroy the result fact handle // workingMemory.getFactHandleFactory().destroyFactHandle( accctx.result.getFactHandle() ); } }
/** Creates a BetaMemory for the BetaNode's memory. */ public Memory createMemory(final RuleBaseConfiguration config) { AccumulateMemory memory = new AccumulateMemory(); memory.betaMemory = this.constraints.createBetaMemory(config, NodeTypeEnums.AccumulateNode); memory.workingMemoryContext = this.accumulate.createWorkingMemoryContext(); memory.resultsContext = this.resultBinder.createContext(); memory.alphaContexts = new ContextEntry[this.resultConstraints.length]; for (int i = 0; i < this.resultConstraints.length; i++) { memory.alphaContexts[i] = this.resultConstraints[i].createContextEntry(); } return memory; }
/** @inheritDoc If an object is retract, call modify tuple for each tuple match. */ public void retractRightTuple( final RightTuple rightTuple, final PropagationContext context, final InternalWorkingMemory workingMemory) { final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory(this); final InternalFactHandle origin = (InternalFactHandle) context.getFactHandleOrigin(); if (context.getType() == PropagationContext.EXPIRATION) { ((PropagationContextImpl) context).setFactHandle(null); } BetaMemory bm = memory.getBetaMemory(); if (isUnlinkingEnabled()) { StagedRightTuples stagedRightTuples = bm.getStagedRightTuples(); switch (rightTuple.getStagedType()) { // handle clash with already staged entries case LeftTuple.INSERT: stagedRightTuples.removeInsert(rightTuple); break; case LeftTuple.UPDATE: stagedRightTuples.removeUpdate(rightTuple); break; } stagedRightTuples.addDelete(rightTuple); if (bm.getDecAndGetCounter() == 0 && !isRightInputIsRiaNode()) { bm.unlinkNode(workingMemory); } return; } bm.getRightTupleMemory().remove(rightTuple); removePreviousMatchesForRightTuple( rightTuple, context, workingMemory, memory, rightTuple.firstChild); if (context.getType() == PropagationContext.EXPIRATION) { ((PropagationContextImpl) context).setFactHandle(origin); } }