public void updateSink( final ObjectSink sink, final PropagationContext context, final InternalWorkingMemory workingMemory) { // @todo // JBRULES-612: the cache MUST be invalidated when a new node type is added to the network, so // iterate and reset all caches. final ObjectTypeNode node = (ObjectTypeNode) sink; final ObjectType newObjectType = node.getObjectType(); InternalWorkingMemoryEntryPoint wmEntryPoint = (InternalWorkingMemoryEntryPoint) workingMemory.getWorkingMemoryEntryPoint(this.entryPoint.getEntryPointId()); for (ObjectTypeConf objectTypeConf : wmEntryPoint.getObjectTypeConfigurationRegistry().values()) { if (newObjectType.isAssignableFrom( objectTypeConf.getConcreteObjectTypeNode().getObjectType())) { objectTypeConf.resetCache(); ObjectTypeNode sourceNode = objectTypeConf.getConcreteObjectTypeNode(); Iterator it = ((ObjectTypeNodeMemory) workingMemory.getNodeMemory(sourceNode)).memory.iterator(); for (ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next()) { sink.assertObject((InternalFactHandle) entry.getValue(), context, workingMemory); } } } }
public void attachAlphaNodes( final BuildContext context, final BuildUtils utils, final Pattern pattern, List<Constraint> alphaConstraints) throws InvalidPatternException { // Drools Query ObjectTypeNode never has memory, but other ObjectTypeNode/AlphaNoesNodes may (if // not in sequential), // so need to preserve, so we can restore after this node is added. LeftMemory and Terminal // remain the same once set. boolean objectMemory = context.isObjectTypeNodeMemoryEnabled(); boolean alphaMemory = context.isAlphaMemoryAllowed(); ObjectType objectType = pattern.getObjectType(); if (pattern.getObjectType() instanceof ClassObjectType) { // Is this the query node, if so we don't want any memory if (DroolsQuery.class == ((ClassObjectType) pattern.getObjectType()).getClassType()) { context.setTupleMemoryEnabled(false); context.setObjectTypeNodeMemoryEnabled(false); context.setTerminalNodeMemoryEnabled(false); context.setAlphaNodeMemoryAllowed(false); } } context.setObjectSource( (ObjectSource) utils.attachNode( context, new EntryPointNode(context.getNextId(), context.getRuleBase().getRete(), context))); ObjectTypeNode otn = new ObjectTypeNode( context.getNextId(), (EntryPointNode) context.getObjectSource(), objectType, context); if (objectType.isEvent() && EventProcessingOption.STREAM.equals( context.getRuleBase().getConfiguration().getEventProcessingMode())) { long expirationOffset = getExpiratioOffsetForType(context, objectType); if (expirationOffset != -1) { // expiration policy is set, so use it otn.setExpirationOffset(expirationOffset); } else { // otherwise calculate it based on behaviours and temporal constraints for (Behavior behavior : pattern.getBehaviors()) { if (behavior.getExpirationOffset() != -1) { expirationOffset = Math.max(behavior.getExpirationOffset(), expirationOffset); } } long distance = context.getTemporalDistance().getExpirationOffset(pattern); if (distance == -1) { // it means the rules have no temporal constraints, or // the constraints require events to be hold forever. In this // case, we allow type declarations to override the implicit // expiration offset by defining an expiration policy with the // @expires tag otn.setExpirationOffset(expirationOffset); } else { otn.setExpirationOffset(Math.max(distance, expirationOffset)); } } } context.setObjectSource((ObjectSource) utils.attachNode(context, otn)); for (final Iterator<Constraint> it = alphaConstraints.iterator(); it.hasNext(); ) { final AlphaNodeFieldConstraint constraint = (AlphaNodeFieldConstraint) it.next(); context.pushRuleComponent(constraint); context.setObjectSource( (ObjectSource) utils.attachNode( context, new AlphaNode( context.getNextId(), (AlphaNodeFieldConstraint) constraint, context.getObjectSource(), context))); context.popRuleComponent(); } // now restore back to original values context.setObjectTypeNodeMemoryEnabled(objectMemory); context.setAlphaNodeMemoryAllowed(alphaMemory); }