public static void readFactHandles(
      MarshallerReaderContext context,
      org.drools.core.marshalling.impl.ProtobufMessages.EntryPoint _ep,
      ObjectStore objectStore,
      List<PropagationContextImpl> pctxs)
      throws IOException, ClassNotFoundException {
    InternalWorkingMemory wm = context.wm;

    SessionEntryPoint entryPoint = context.wm.getEntryPoints().get(_ep.getEntryPointId());
    // load the handles
    for (ProtobufMessages.FactHandle _handle : _ep.getHandleList()) {
      InternalFactHandle handle = readFactHandle(context, entryPoint, _handle);

      context.handles.put(handle.getId(), handle);

      if (!_handle.getIsJustified()) {
        // BeliefSystem handles the Object type
        if (handle.getObject() != null) {
          objectStore.addHandle(handle, handle.getObject());
        }

        // add handle to object type node
        assertHandleIntoOTN(context, wm, handle, pctxs);
      }
    }
  }
    public boolean evaluate(
        InternalWorkingMemory workingMemory,
        final InternalReadAccessor extractor1,
        final InternalFactHandle handle1,
        final InternalReadAccessor extractor2,
        final InternalFactHandle handle2) {
      if (extractor1.isNullValue(workingMemory, handle1.getObject())
          || extractor2.isNullValue(workingMemory, handle2.getObject())) {
        return false;
      }

      long rightTS;
      if (extractor1.isSelfReference()) {
        rightTS = ((EventFactHandle) handle1).getEndTimestamp();
      } else {
        rightTS = extractor1.getLongValue(workingMemory, handle1.getObject());
      }

      long leftTS;
      if (extractor2.isSelfReference()) {
        leftTS = ((EventFactHandle) handle2).getStartTimestamp();
      } else {
        leftTS = extractor2.getLongValue(workingMemory, handle2.getObject());
      }

      return evaluate(rightTS, leftTS);
    }
  private static void assertHandleIntoOTN(
      MarshallerReaderContext context,
      InternalWorkingMemory wm,
      InternalFactHandle handle,
      List<PropagationContextImpl> pctxs) {
    Object object = handle.getObject();
    InternalWorkingMemoryEntryPoint ep = (InternalWorkingMemoryEntryPoint) handle.getEntryPoint();
    ObjectTypeConf typeConf =
        ((InternalWorkingMemoryEntryPoint) handle.getEntryPoint())
            .getObjectTypeConfigurationRegistry()
            .getObjectTypeConf(ep.getEntryPoint(), object);
    PropagationContextImpl propagationContext =
        new PropagationContextImpl(
            wm.getNextPropagationIdCounter(),
            PropagationContext.INSERTION,
            null,
            null,
            handle,
            ep.getEntryPoint(),
            context);
    // keeping this list for a later cleanup is necessary because of the lazy propagations that
    // might occur
    pctxs.add(propagationContext);

    ep.getEntryPointNode().assertObject(handle, propagationContext, typeConf, wm);

    propagationContext.evaluateActionQueue(wm);
    wm.executeQueuedActions();
  }
    public boolean evaluate(
        InternalWorkingMemory workingMemory,
        final InternalReadAccessor extractor1,
        final InternalFactHandle handle1,
        final InternalReadAccessor extractor2,
        final InternalFactHandle handle2) {
      if (extractor1.isNullValue(workingMemory, handle1.getObject())
          || extractor2.isNullValue(workingMemory, handle2.getObject())) {
        return false;
      }

      long rightTS;
      if (extractor1.isSelfReference()) {
        rightTS = ((EventFactHandle) handle1).getEndTimestamp();
      } else {
        rightTS = extractor1.getLongValue(workingMemory, handle1.getObject());
      }

      long leftTS;
      if (extractor2.isSelfReference()) {
        leftTS = ((EventFactHandle) handle2).getStartTimestamp();
      } else {
        leftTS = extractor2.getLongValue(workingMemory, handle2.getObject());
      }

      long dist = leftTS - rightTS;

      return this.getOperator().isNegated() ^ (dist >= this.initRange && dist <= this.finalRange);
    }
  private static ProtobufMessages.NodeMemory writeRIANodeMemory(
      final int nodeId,
      final MarshallerWriteContext context,
      final BaseNode node,
      final NodeMemories memories,
      final Memory memory) {
    RightInputAdapterNode riaNode = (RightInputAdapterNode) node;

    ObjectSink[] sinks = riaNode.getSinkPropagator().getSinks();
    BetaNode betaNode = (BetaNode) sinks[0];

    Memory betaMemory = memories.peekNodeMemory(betaNode.getId());
    if (betaMemory == null) {
      return null;
    }
    BetaMemory bm;
    if (betaNode.getType() == NodeTypeEnums.AccumulateNode) {
      bm = ((AccumulateMemory) betaMemory).getBetaMemory();
    } else {
      bm = (BetaMemory) betaMemory;
    }

    // for RIA nodes, we need to store the ID of the created handles
    bm.getRightTupleMemory().iterator();
    if (bm.getRightTupleMemory().size() > 0) {
      ProtobufMessages.NodeMemory.RIANodeMemory.Builder _ria =
          ProtobufMessages.NodeMemory.RIANodeMemory.newBuilder();
      final org.drools.core.util.Iterator it = bm.getRightTupleMemory().iterator();

      // iterates over all propagated handles and assert them to the new sink
      for (RightTuple entry = (RightTuple) it.next();
          entry != null;
          entry = (RightTuple) it.next()) {
        LeftTuple leftTuple = (LeftTuple) entry.getFactHandle().getObject();
        InternalFactHandle handle = (InternalFactHandle) leftTuple.getObject();
        FactHandle _handle =
            ProtobufMessages.FactHandle.newBuilder()
                .setId(handle.getId())
                .setRecency(handle.getRecency())
                .build();
        _ria.addContext(
            ProtobufMessages.NodeMemory.RIANodeMemory.RIAContext.newBuilder()
                .setTuple(PersisterHelper.createTuple(leftTuple))
                .setResultHandle(_handle)
                .build());
      }

      return ProtobufMessages.NodeMemory.newBuilder()
          .setNodeId(nodeId)
          .setNodeType(ProtobufMessages.NodeMemory.NodeType.RIA)
          .setRia(_ria.build())
          .build();
    }
    return null;
  }
 public static Tuple writeTuple(LeftTuple tuple) {
   ProtobufMessages.Tuple.Builder _tb = ProtobufMessages.Tuple.newBuilder();
   for (LeftTuple entry = tuple; entry != null; entry = entry.getParent()) {
     InternalFactHandle handle = entry.getLastHandle();
     if (handle != null) {
       // can be null for eval, not and exists that have no right input
       _tb.addHandleId(handle.getId());
     }
   }
   return _tb.build();
 }
    public boolean evaluate(
        InternalWorkingMemory workingMemory,
        final InternalReadAccessor extractor1,
        final InternalFactHandle handl1,
        final InternalReadAccessor extractor2,
        final InternalFactHandle handl2) {
      final Object value1 = extractor1.getValue(workingMemory, handl1.getObject());
      final Object value2 = extractor2.getValue(workingMemory, handl2.getObject());

      return !soundslike((String) value1, (String) value2);
    }
  public void modifyLeftTuple(
      LeftTuple leftTuple, PropagationContext context, InternalWorkingMemory workingMemory) {
    // add it to a memory mapping
    InternalFactHandle handle = (InternalFactHandle) leftTuple.getObject();

    // propagate it
    for (RightTuple rightTuple = handle.getFirstRightTuple();
        rightTuple != null;
        rightTuple = rightTuple.getHandleNext()) {
      rightTuple.getRightTupleSink().modifyRightTuple(rightTuple, context, workingMemory);
    }
  }
Example #9
0
    @Override
    public Iterator getResults(
        Tuple leftTuple, InternalWorkingMemory wm, PropagationContext ctx, Object providerContext) {
      InternalFactHandle fh = leftTuple.getFactHandle();
      Object obj = fh.getObject();

      if (obj instanceof DroolsQuery) {
        obj = ((DroolsQuery) obj).getElements()[declaration.getPattern().getOffset()];
      }

      return xpathEvaluator.evaluate(wm, leftTuple, obj).iterator();
    }
Example #10
0
  public void closeLiveQuery(final InternalFactHandle factHandle) {

    try {
      startOperation();
      this.ruleBase.readLock();
      this.lock.lock();

      final PropagationContext pCtx =
          new PropagationContextImpl(
              getNextPropagationIdCounter(),
              PropagationContext.INSERTION,
              null,
              null,
              factHandle,
              getEntryPoint());

      if (this.ruleBase.getConfiguration().isPhreakEnabled()) {
        LeftInputAdapterNode lian =
            (LeftInputAdapterNode)
                factHandle.getFirstLeftTuple().getLeftTupleSink().getLeftTupleSource();
        LiaNodeMemory lmem = (LiaNodeMemory) getNodeMemory((MemoryFactory) lian);
        SegmentMemory lsmem = lmem.getSegmentMemory();

        LeftTuple childLeftTuple =
            factHandle.getFirstLeftTuple(); // there is only one, all other LTs are peers
        LeftInputAdapterNode.doDeleteObject(
            childLeftTuple, childLeftTuple.getPropagationContext(), lsmem, this, lian, false, lmem);

        List<PathMemory> rmems = lmem.getSegmentMemory().getPathMemories();
        for (int i = 0, length = rmems.size(); i < length; i++) {
          PathMemory rm = rmems.get(i);

          RuleNetworkEvaluatorActivation evaluator =
              agenda.createRuleNetworkEvaluatorActivation(
                  Integer.MAX_VALUE, rm, (TerminalNode) rm.getNetworkNode());
          evaluator.evaluateNetwork(this, 0, -1);
        }
      } else {
        getEntryPointNode().retractQuery(factHandle, pCtx, this);

        pCtx.evaluateActionQueue(this);
      }

      getFactHandleFactory().destroyFactHandle(factHandle);

    } finally {
      this.lock.unlock();
      this.ruleBase.readUnlock();
      endOperation();
    }
  }
 public Collection<FactHandle> execute(Context context) {
   KieSession ksession = ((KnowledgeCommandContext) context).getKieSession();
   Collection<FactHandle> disconnectedFactHandles = new ArrayList<FactHandle>();
   if (filter != null) {
     Collection<InternalFactHandle> factHandles = ksession.getFactHandles(this.filter);
     if (factHandles != null && disconnected) {
       for (InternalFactHandle factHandle : factHandles) {
         InternalFactHandle handle = factHandle.clone();
         handle.disconnect();
         disconnectedFactHandles.add(handle);
       }
       return disconnectedFactHandles;
     } else {
       return ksession.getFactHandles(this.filter);
     }
   } else {
     Collection<InternalFactHandle> factHandles = ksession.getFactHandles();
     if (factHandles != null && disconnected) {
       for (InternalFactHandle factHandle : factHandles) {
         InternalFactHandle handle = factHandle.clone();
         handle.disconnect();
         disconnectedFactHandles.add(handle);
       }
       return disconnectedFactHandles;
     } else {
       return ksession.getFactHandles();
     }
   }
 }
Example #12
0
    public void execute(InternalWorkingMemory workingMemory) {
      DroolsQuery query = (DroolsQuery) factHandle.getObject();
      RightTupleList rightTuples = query.getResultInsertRightTupleList();
      query.setResultInsertRightTupleList(
          null); // null so further operations happen on a new stack element

      for (RightTuple rightTuple = rightTuples.getFirst(); rightTuple != null; ) {
        RightTuple tmp = (RightTuple) rightTuple.getNext();
        rightTuples.remove(rightTuple);
        for (LeftTuple childLeftTuple = rightTuple.firstChild;
            childLeftTuple != null;
            childLeftTuple = (LeftTuple) childLeftTuple.getRightParentNext()) {
          node.getSinkPropagator()
              .doPropagateAssertLeftTuple(
                  context, workingMemory, childLeftTuple, childLeftTuple.getLeftTupleSink());
        }
        rightTuple = tmp;
      }

      // @FIXME, this should work, but it's closing needed fact handles
      // actually an evaluation 34 appears on the stack twice....
      //            if ( !node.isOpenQuery() ) {
      //                workingMemory.getFactHandleFactory().destroyFactHandle( this.factHandle );
      //            }
    }
    public boolean evaluateCachedLeft(
        InternalWorkingMemory workingMemory,
        final VariableContextEntry context,
        final InternalFactHandle right) {
      final String value = (String) context.extractor.getValue(workingMemory, right.getObject());

      return !soundslike(value, (String) ((ObjectVariableContextEntry) context).left);
    }
    public boolean evaluateCachedLeft(
        InternalWorkingMemory workingMemory,
        final VariableContextEntry context,
        final InternalFactHandle right) {
      if (context.leftNull || context.extractor.isNullValue(workingMemory, right.getObject())) {
        return false;
      }

      long leftTS = ((LeftStartRightEndContextEntry) context).timestamp;
      long rightTS;
      if (context.getFieldExtractor().isSelfReference()) {
        rightTS = ((EventFactHandle) right).getEndTimestamp();
      } else {
        rightTS = context.getFieldExtractor().getLongValue(workingMemory, right.getObject());
      }
      return evaluate(rightTS, leftTS);
    }
    public boolean evaluateCachedLeft(
        InternalWorkingMemory workingMemory,
        final VariableContextEntry context,
        final InternalFactHandle right) {
      if (context.leftNull || context.extractor.isNullValue(workingMemory, right.getObject())) {
        return false;
      }

      long leftTS = ((LeftStartRightEndContextEntry) context).timestamp;
      long rightTS;
      if (context.getFieldExtractor().isSelfReference()) {
        rightTS = ((EventFactHandle) right).getEndTimestamp();
      } else {
        rightTS = context.getFieldExtractor().getLongValue(workingMemory, right.getObject());
      }
      long dist = leftTS - rightTS;
      return this.getOperator().isNegated() ^ (dist >= this.initRange && dist <= this.finalRange);
    }
  private static ProtobufMessages.NodeMemory writeQueryElementNodeMemory(
      final int nodeId, final Memory memory, final InternalWorkingMemory wm) {
    org.drools.core.util.Iterator<LeftTuple> it =
        LeftTupleIterator.iterator(wm, ((QueryElementNodeMemory) memory).getNode());

    ProtobufMessages.NodeMemory.QueryElementNodeMemory.Builder _query =
        ProtobufMessages.NodeMemory.QueryElementNodeMemory.newBuilder();
    for (LeftTuple leftTuple = it.next(); leftTuple != null; leftTuple = it.next()) {
      InternalFactHandle handle = (InternalFactHandle) leftTuple.getObject();
      FactHandle _handle =
          ProtobufMessages.FactHandle.newBuilder()
              .setId(handle.getId())
              .setRecency(handle.getRecency())
              .build();

      ProtobufMessages.NodeMemory.QueryElementNodeMemory.QueryContext.Builder _context =
          ProtobufMessages.NodeMemory.QueryElementNodeMemory.QueryContext.newBuilder()
              .setTuple(PersisterHelper.createTuple(leftTuple))
              .setHandle(_handle);

      LeftTuple childLeftTuple = leftTuple.getFirstChild();
      while (childLeftTuple != null) {
        RightTuple rightParent = childLeftTuple.getRightParent();
        _context.addResult(
            ProtobufMessages.FactHandle.newBuilder()
                .setId(rightParent.getFactHandle().getId())
                .setRecency(rightParent.getFactHandle().getRecency())
                .build());
        while (childLeftTuple != null && childLeftTuple.getRightParent() == rightParent) {
          // skip to the next child that has a different right parent
          childLeftTuple = childLeftTuple.getLeftParentNext();
        }
      }
      _query.addContext(_context.build());
    }

    return _query.getContextCount() > 0
        ? ProtobufMessages.NodeMemory.newBuilder()
            .setNodeId(nodeId)
            .setNodeType(ProtobufMessages.NodeMemory.NodeType.QUERY_ELEMENT)
            .setQueryElement(_query.build())
            .build()
        : null;
  }
    public boolean evaluateCachedRight(
        InternalWorkingMemory workingMemory,
        final VariableContextEntry context,
        final InternalFactHandle left) {
      final String value = (String) ((ObjectVariableContextEntry) context).right;

      return !soundslike(
          value,
          (String) context.declaration.getExtractor().getValue(workingMemory, left.getObject()));
    }
 private static ProtobufMessages.FactHandle.HandleType getHandleType(InternalFactHandle handle) {
   if (handle instanceof EventFactHandle) {
     return ProtobufMessages.FactHandle.HandleType.EVENT;
   } else if (handle instanceof QueryElementFactHandle) {
     return ProtobufMessages.FactHandle.HandleType.QUERY;
   } else if (handle.getObject() instanceof InitialFact) {
     return ProtobufMessages.FactHandle.HandleType.INITIAL_FACT;
   }
   return ProtobufMessages.FactHandle.HandleType.FACT;
 }
    public boolean evaluate(
        InternalWorkingMemory workingMemory,
        final InternalReadAccessor extractor,
        final InternalFactHandle handle1,
        final FieldValue object2) {
      final String value1 = (String) extractor.getValue(workingMemory, handle1.getObject());
      final String value2 = (String) object2.getValue();

      return !soundslike(value1, value2);
    }
Example #20
0
  public void modifyActivation(
      final InternalFactHandle factHandle,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    if (activationNode == null) {
      this.activationNode = objectTypeNodes.get(ClassObjectType.Match_ObjectType);
    }

    if (activationNode != null) {
      ModifyPreviousTuples modifyPreviousTuples =
          new ModifyPreviousTuples(
              factHandle.getFirstLeftTuple(), factHandle.getFirstRightTuple(), unlinkingEnabled);
      factHandle.clearLeftTuples();
      factHandle.clearRightTuples();

      // There may be no queries defined
      this.activationNode.modifyObject(factHandle, modifyPreviousTuples, context, workingMemory);
      modifyPreviousTuples.retractTuples(context, workingMemory);
    }
  }
  private static ProtobufMessages.FactHandle writeFactHandle(
      MarshallerWriteContext context,
      ObjectMarshallingStrategyStore objectMarshallingStrategyStore,
      InternalFactHandle handle)
      throws IOException {
    ProtobufMessages.FactHandle.Builder _handle = ProtobufMessages.FactHandle.newBuilder();

    _handle.setType(getHandleType(handle));
    _handle.setId(handle.getId());
    _handle.setRecency(handle.getRecency());

    if (_handle.getType() == ProtobufMessages.FactHandle.HandleType.EVENT) {
      // is event
      EventFactHandle efh = (EventFactHandle) handle;
      _handle.setTimestamp(efh.getStartTimestamp());
      _handle.setDuration(efh.getDuration());
      _handle.setIsExpired(efh.isExpired());
      _handle.setActivationsCount(efh.getActivationsCount());
    }

    if (handle.getEqualityKey() != null
        && handle.getEqualityKey().getStatus() == EqualityKey.JUSTIFIED) {
      _handle.setIsJustified(true);
    } else {
      _handle.setIsJustified(false);
    }

    Object object = handle.getObject();

    if (object != null) {
      ObjectMarshallingStrategy strategy = objectMarshallingStrategyStore.getStrategyObject(object);

      Integer index = context.getStrategyIndex(strategy);
      _handle.setStrategyIndex(index.intValue());
      _handle.setObject(
          ByteString.copyFrom(
              strategy.marshal(context.strategyContext.get(strategy), context, object)));
    }

    return _handle.build();
  }
Example #22
0
 public void execute(InternalWorkingMemory workingMemory) {
   InternalFactHandle factHandle = (InternalFactHandle) leftTuple.getObject();
   if (node.isOpenQuery()) {
     // iterate to the query terminal node, as the child leftTuples will get picked up there
     workingMemory
         .getEntryPointNode()
         .retractObject(
             factHandle,
             context,
             workingMemory
                 .getObjectTypeConfigurationRegistry()
                 .getObjectTypeConf(workingMemory.getEntryPoint(), factHandle.getObject()),
             workingMemory);
     // workingMemory.getFactHandleFactory().destroyFactHandle( factHandle );
   } else {
     // get child left tuples, as there is no open query
     if (leftTuple.getFirstChild() != null) {
       node.getSinkPropagator().propagateRetractLeftTuple(leftTuple, context, workingMemory);
     }
   }
 }
  /** Retracts the corresponding tuple by retrieving and retracting the fact created for it */
  public void retractLeftTuple(
      final LeftTuple tuple,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    // retrieve handle from memory
    final InternalFactHandle factHandle = (InternalFactHandle) tuple.getObject();

    for (RightTuple rightTuple = factHandle.getFirstRightTuple();
        rightTuple != null;
        rightTuple = rightTuple.getHandleNext()) {
      rightTuple.getRightTupleSink().retractRightTuple(rightTuple, context, workingMemory);
    }
    factHandle.clearRightTuples();

    for (LeftTuple leftTuple = factHandle.getLastLeftTuple();
        leftTuple != null;
        leftTuple = leftTuple.getLeftParentNext()) {
      leftTuple.getLeftTupleSink().retractLeftTuple(leftTuple, context, workingMemory);
    }
    factHandle.clearLeftTuples();
  }
Example #24
0
 /**
  * This is the entry point into the network for all asserted Facts. Iterates a cache of matching
  * <code>ObjectTypdeNode</code>s asserting the Fact. If the cache does not exist it first iteraes
  * and builds the cache.
  *
  * @param factHandle The FactHandle of the fact to assert
  * @param context The <code>PropagationContext</code> of the <code>WorkingMemory</code> action
  * @param workingMemory The working memory session.
  */
 public void assertObject(
     final InternalFactHandle factHandle,
     final PropagationContext context,
     final InternalWorkingMemory workingMemory) {
   EntryPointId entryPoint = context.getEntryPoint();
   EntryPointNode node = this.entryPoints.get(entryPoint);
   ObjectTypeConf typeConf =
       ((InternalWorkingMemoryEntryPoint)
               workingMemory.getWorkingMemoryEntryPoint(entryPoint.getEntryPointId()))
           .getObjectTypeConfigurationRegistry()
           .getObjectTypeConf(entryPoint, factHandle.getObject());
   node.assertObject(factHandle, context, typeConf, workingMemory);
 }
Example #25
0
  public void assertObject(
      final InternalFactHandle handle,
      final PropagationContext context,
      final ObjectTypeConf objectTypeConf,
      final InternalWorkingMemory workingMemory) {
    if (log.isTraceEnabled()) {
      log.trace("Insert {}", handle.toString());
    }

    // checks if shadow is enabled
    if (objectTypeConf.isShadowEnabled()) {
      // the user has implemented the ShadowProxy interface, let their implementation
      // know it is safe to update the information the engine can see.
      ((ShadowProxy) handle.getObject()).updateProxy();
    }

    ObjectTypeNode[] cachedNodes = objectTypeConf.getObjectTypeNodes();

    for (int i = 0, length = cachedNodes.length; i < length; i++) {
      cachedNodes[i].assertObject(handle, context, workingMemory);
    }
  }
  private static ReteooStatefulSession createAndInitializeSession(
      MarshallerReaderContext context,
      int id,
      Environment environment,
      SessionConfiguration config,
      ProtobufMessages.KnowledgeSession _session)
      throws IOException {
    FactHandleFactory handleFactory =
        context.ruleBase.newFactHandleFactory(
            _session.getRuleData().getLastId(), _session.getRuleData().getLastRecency());

    InternalFactHandle initialFactHandle =
        new DefaultFactHandle(
            _session.getRuleData().getInitialFact().getId(),
            InitialFactImpl.getInstance(),
            _session.getRuleData().getInitialFact().getRecency(),
            null);
    context.handles.put(initialFactHandle.getId(), initialFactHandle);

    DefaultAgenda agenda =
        context
            .ruleBase
            .getConfiguration()
            .getComponentFactory()
            .getAgendaFactory()
            .createAgenda(context.ruleBase, false);
    readAgenda(context, _session.getRuleData(), agenda);

    ReteooStatefulSession session =
        new ReteooStatefulSession(
            id, context.ruleBase, handleFactory, initialFactHandle, 0, config, agenda, environment);
    new StatefulKnowledgeSessionImpl(session);

    initialFactHandle.setEntryPoint(
        session.getEntryPoints().get(EntryPoint.DEFAULT.getEntryPointId()));
    return session;
  }
Example #27
0
    public void execute(InternalWorkingMemory workingMemory) {
      DroolsQuery query = (DroolsQuery) factHandle.getObject();
      RightTupleList rightTuples = query.getResultRetractRightTupleList();
      query.setResultRetractRightTupleList(
          null); // null so further operations happen on a new stack element

      for (RightTuple rightTuple = rightTuples.getFirst(); rightTuple != null; ) {
        RightTuple tmp = (RightTuple) rightTuple.getNext();
        rightTuples.remove(rightTuple);
        this.node
            .getSinkPropagator()
            .propagateRetractRightTuple(rightTuple, context, workingMemory);
        rightTuple = tmp;
      }
    }
  public void byPassModifyToBetaNode(
      final InternalFactHandle factHandle,
      final ModifyPreviousTuples modifyPreviousTuples,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final Object object = factHandle.getObject();

    // We need to iterate in the same order as the assert
    if (this.hashedFieldIndexes != null) {
      // Iterate the FieldIndexes to see if any are hashed
      for (FieldIndex fieldIndex = this.hashedFieldIndexes.getFirst();
          fieldIndex != null;
          fieldIndex = fieldIndex.getNext()) {
        if (!fieldIndex.isHashed()) {
          continue;
        }
        // this field is hashed so set the existing hashKey and see if there is a sink for it
        final AlphaNode sink = (AlphaNode) this.hashedSinkMap.get(new HashKey(fieldIndex, object));
        if (sink != null) {
          // only alpha nodes are hashable
          sink.getObjectSinkPropagator()
              .byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
        }
      }
    }

    // propagate unhashed
    if (this.hashableSinks != null) {
      for (ObjectSinkNode sink = this.hashableSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        // only alpha nodes are hashable
        ((AlphaNode) sink)
            .getObjectSinkPropagator()
            .byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
      }
    }

    if (this.otherSinks != null) {
      // propagate others
      for (ObjectSinkNode sink = this.otherSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        // compound alpha, lianode or betanode
        sink.byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
      }
    }
  }
    public boolean evaluate(
        InternalWorkingMemory workingMemory,
        final InternalReadAccessor extractor,
        final InternalFactHandle object1,
        final FieldValue object2) {
      long rightTS;
      if (extractor.isSelfReference()) {
        rightTS = ((EventFactHandle) object1).getStartTimestamp();
      } else {
        rightTS = extractor.getLongValue(workingMemory, object1.getObject());
      }

      long leftTS = ((Date) object2.getValue()).getTime();

      return evaluate(rightTS, leftTS);
    }
  public void propagateModifyObject(
      final InternalFactHandle factHandle,
      final ModifyPreviousTuples modifyPreviousTuples,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final Object object = factHandle.getObject();

    // Iterates the FieldIndex collection, which tells you if particularly field is hashed or not
    // if the field is hashed then it builds the hashkey to return the correct sink for the current
    // objects slot's
    // value, one object may have multiple fields indexed.
    if (this.hashedFieldIndexes != null) {
      // Iterate the FieldIndexes to see if any are hashed
      for (FieldIndex fieldIndex = this.hashedFieldIndexes.getFirst();
          fieldIndex != null;
          fieldIndex = fieldIndex.getNext()) {
        if (!fieldIndex.isHashed()) {
          continue;
        }
        // this field is hashed so set the existing hashKey and see if there is a sink for it
        final AlphaNode sink = (AlphaNode) this.hashedSinkMap.get(new HashKey(fieldIndex, object));
        if (sink != null) {
          // go straight to the AlphaNode's propagator, as we know it's true and no need to retest
          sink.getObjectSinkPropagator()
              .propagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory);
        }
      }
    }

    // propagate unhashed
    if (this.hashableSinks != null) {
      for (ObjectSinkNode sink = this.hashableSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        doPropagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory, sink);
      }
    }

    if (this.otherSinks != null) {
      // propagate others
      for (ObjectSinkNode sink = this.otherSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        doPropagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory, sink);
      }
    }
  }