示例#1
0
  public static void doUpdatesExistentialReorderLeftMemory(
      BetaMemory bm, TupleSets<LeftTuple> srcLeftTuples) {
    TupleMemory ltm = bm.getLeftTupleMemory();

    // sides must first be re-ordered, to ensure iteration integrity
    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();
      if (leftTuple.getMemory() != null) {
        ltm.remove(leftTuple);
      }
      leftTuple = next;
    }

    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();
      RightTuple blocker = leftTuple.getBlocker();
      if (blocker == null) {
        ltm.add(leftTuple);
        for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; ) {
          LeftTuple childNext = childLeftTuple.getHandleNext();
          childLeftTuple.reAddRight();
          childLeftTuple = childNext;
        }
      } else if (blocker.getStagedType() != LeftTuple.NONE) {
        // it's blocker is also being updated, so remove to force it to start from the beginning
        blocker.removeBlocked(leftTuple);
      }
      leftTuple = next;
    }
  }
示例#2
0
  public static void dpUpdatesExistentialReorderLeftMemory(
      BetaMemory bm, LeftTupleSets srcLeftTuples) {
    LeftTupleMemory ltm = bm.getLeftTupleMemory();

    // sides must first be re-ordered, to ensure iteration integrity
    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();
      if (leftTuple.getMemory() != null) {
        ltm.remove(leftTuple);
      }
      leftTuple = next;
    }

    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();
      if (leftTuple.getBlocker() == null) {
        ltm.add(leftTuple);
        for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; ) {
          LeftTuple childNext = childLeftTuple.getLeftParentNext();
          childLeftTuple.reAddRight();
          childLeftTuple = childNext;
        }
      }
      leftTuple = next;
    }
  }
示例#3
0
  public void doLeftDeletes(
      BetaMemory bm,
      LeftTupleSets srcLeftTuples,
      LeftTupleSets trgLeftTuples,
      LeftTupleSets stagedLeftTuples) {
    LeftTupleMemory ltm = bm.getLeftTupleMemory();

    for (LeftTuple leftTuple = srcLeftTuples.getDeleteFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();
      RightTuple blocker = leftTuple.getBlocker();
      if (blocker == null) {
        if (leftTuple.getMemory() != null) {
          // it may have been staged and never actually added
          ltm.remove(leftTuple);
        }

        LeftTuple childLeftTuple = leftTuple.getFirstChild();

        if (childLeftTuple != null) { // NotNode only has one child
          childLeftTuple.setPropagationContext(leftTuple.getPropagationContext());
          RuleNetworkEvaluator.deleteLeftChild(
              childLeftTuple,
              trgLeftTuples,
              stagedLeftTuples); // no need to update pctx, as no right available, and pctx will
                                 // exist on a parent LeftTuple anyway
        }
      } else {
        blocker.removeBlocked(leftTuple);
      }
      leftTuple.clearStaged();
      leftTuple = next;
    }
  }
示例#4
0
  public static void doUpdatesReorderLeftMemory(BetaMemory bm, TupleSets<LeftTuple> srcLeftTuples) {
    TupleMemory ltm = bm.getLeftTupleMemory();

    // sides must first be re-ordered, to ensure iteration integrity
    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();
      ltm.remove(leftTuple);
      leftTuple = next;
    }

    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();
      ltm.add(leftTuple);
      for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; ) {
        LeftTuple childNext = childLeftTuple.getHandleNext();
        childLeftTuple.reAddRight();
        childLeftTuple = childNext;
      }
      leftTuple = next;
    }
  }
示例#5
0
  public void doLeftInserts(
      NotNode notNode,
      LeftTupleSink sink,
      BetaMemory bm,
      InternalWorkingMemory wm,
      LeftTupleSets srcLeftTuples,
      LeftTupleSets trgLeftTuples) {
    LeftTupleMemory ltm = bm.getLeftTupleMemory();
    RightTupleMemory rtm = bm.getRightTupleMemory();
    ContextEntry[] contextEntry = bm.getContext();
    BetaConstraints constraints = notNode.getRawConstraints();

    for (LeftTuple leftTuple = srcLeftTuples.getInsertFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      FastIterator it = notNode.getRightIterator(rtm);

      boolean useLeftMemory = RuleNetworkEvaluator.useLeftMemory(notNode, leftTuple);

      constraints.updateFromTuple(contextEntry, wm, leftTuple);

      // This method will also remove rightTuples that are from subnetwork where no leftmemory use
      // used
      RuleNetworkEvaluator.findLeftTupleBlocker(
          notNode, rtm, contextEntry, constraints, leftTuple, it, useLeftMemory);

      if (leftTuple.getBlocker() == null) {
        // tuple is not blocked, so add to memory so other fact handles can attempt to match
        if (useLeftMemory) {
          ltm.add(leftTuple);
        }

        trgLeftTuples.addInsert(
            sink.createLeftTuple(
                leftTuple,
                sink,
                leftTuple.getPropagationContext(),
                useLeftMemory)); // use leftTuple pctx here, as no right input caused the trigger
                                 // anway
      }
      leftTuple.clearStaged();
      leftTuple = next;
    }
    constraints.resetTuple(contextEntry);
  }
示例#6
0
  public void doLeftDeletes(
      FromMemory fm,
      TupleSets<LeftTuple> srcLeftTuples,
      TupleSets<LeftTuple> trgLeftTuples,
      TupleSets<LeftTuple> stagedLeftTuples) {
    BetaMemory bm = fm.getBetaMemory();
    TupleMemory ltm = bm.getLeftTupleMemory();

    for (LeftTuple leftTuple = srcLeftTuples.getDeleteFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      ltm.remove(leftTuple);

      Map<Object, RightTuple> matches = (Map<Object, RightTuple>) leftTuple.getContextObject();

      if (leftTuple.getFirstChild() != null) {
        LeftTuple childLeftTuple = leftTuple.getFirstChild();

        while (childLeftTuple != null) {
          childLeftTuple.setPropagationContext(leftTuple.getPropagationContext());
          LeftTuple nextChild = childLeftTuple.getLeftParentNext();
          RuleNetworkEvaluator.unlinkAndDeleteChildLeftTuple(
              childLeftTuple, trgLeftTuples, stagedLeftTuples);
          childLeftTuple = nextChild;
        }
      }

      // if matches == null, the deletion might be happening before the fact was even propagated.
      // See BZ-1019473 for details.
      if (matches != null) {

        // @TODO (mdp) is this really necessary? won't the entire FH and RightTuple chaines just et
        // GC'd?
        unlinkCreatedHandles(leftTuple);
      }

      leftTuple.clearStaged();
      leftTuple = next;
    }
  }
示例#7
0
  public void doLeftInserts(
      FromNode fromNode,
      FromMemory fm,
      LeftTupleSink sink,
      InternalWorkingMemory wm,
      TupleSets<LeftTuple> srcLeftTuples,
      TupleSets<LeftTuple> trgLeftTuples) {

    BetaMemory bm = fm.getBetaMemory();
    ContextEntry[] context = bm.getContext();
    BetaConstraints betaConstraints = fromNode.getBetaConstraints();
    AlphaNodeFieldConstraint[] alphaConstraints = fromNode.getAlphaConstraints();
    DataProvider dataProvider = fromNode.getDataProvider();
    Class<?> resultClass = fromNode.getResultClass();

    for (LeftTuple leftTuple = srcLeftTuples.getInsertFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      PropagationContext propagationContext = leftTuple.getPropagationContext();

      Map<Object, RightTuple> matches = null;
      boolean useLeftMemory = RuleNetworkEvaluator.useLeftMemory(fromNode, leftTuple);

      if (useLeftMemory) {
        fm.getBetaMemory().getLeftTupleMemory().add(leftTuple);
        matches = new LinkedHashMap<Object, RightTuple>();
        leftTuple.setContextObject(matches);
      }

      betaConstraints.updateFromTuple(context, wm, leftTuple);

      for (final java.util.Iterator<?> it =
              dataProvider.getResults(leftTuple, wm, propagationContext, fm.providerContext);
          it.hasNext(); ) {
        final Object object = it.next();
        if ((object == null) || !resultClass.isAssignableFrom(object.getClass())) {
          continue; // skip anything if it not assignable
        }

        RightTuple rightTuple =
            fromNode.createRightTuple(leftTuple, propagationContext, wm, object);

        checkConstraintsAndPropagate(
            sink,
            leftTuple,
            rightTuple,
            alphaConstraints,
            betaConstraints,
            propagationContext,
            wm,
            fm,
            context,
            useLeftMemory,
            trgLeftTuples,
            null);
        if (useLeftMemory) {
          fromNode.addToCreatedHandlesMap(matches, rightTuple);
        }
      }

      leftTuple.clearStaged();
      leftTuple = next;
    }
    betaConstraints.resetTuple(context);
  }
示例#8
0
  public void doLeftUpdates(
      FromNode fromNode,
      FromMemory fm,
      LeftTupleSink sink,
      InternalWorkingMemory wm,
      TupleSets<LeftTuple> srcLeftTuples,
      TupleSets<LeftTuple> trgLeftTuples,
      TupleSets<LeftTuple> stagedLeftTuples) {
    BetaMemory bm = fm.getBetaMemory();
    ContextEntry[] context = bm.getContext();
    BetaConstraints betaConstraints = fromNode.getBetaConstraints();
    AlphaNodeFieldConstraint[] alphaConstraints = fromNode.getAlphaConstraints();
    DataProvider dataProvider = fromNode.getDataProvider();
    Class<?> resultClass = fromNode.getResultClass();

    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      PropagationContext propagationContext = leftTuple.getPropagationContext();

      final Map<Object, RightTuple> previousMatches =
          (Map<Object, RightTuple>) leftTuple.getContextObject();
      final Map<Object, RightTuple> newMatches = new HashMap<Object, RightTuple>();
      leftTuple.setContextObject(newMatches);

      betaConstraints.updateFromTuple(context, wm, leftTuple);

      FastIterator rightIt = LinkedList.fastIterator;
      for (final java.util.Iterator<?> it =
              dataProvider.getResults(leftTuple, wm, propagationContext, fm.providerContext);
          it.hasNext(); ) {
        final Object object = it.next();
        if ((object == null) || !resultClass.isAssignableFrom(object.getClass())) {
          continue; // skip anything if it not assignable
        }

        RightTuple rightTuple = previousMatches.remove(object);

        if (rightTuple == null) {
          // new match, propagate assert
          rightTuple = fromNode.createRightTuple(leftTuple, propagationContext, wm, object);
        } else {
          // previous match, so reevaluate and propagate modify
          if (rightIt.next(rightTuple) != null) {
            // handle the odd case where more than one object has the same hashcode/equals value
            previousMatches.put(object, (RightTuple) rightIt.next(rightTuple));
            rightTuple.setNext(null);
          }
        }

        checkConstraintsAndPropagate(
            sink,
            leftTuple,
            rightTuple,
            alphaConstraints,
            betaConstraints,
            propagationContext,
            wm,
            fm,
            context,
            true,
            trgLeftTuples,
            null);

        fromNode.addToCreatedHandlesMap(newMatches, rightTuple);
      }

      for (RightTuple rightTuple : previousMatches.values()) {
        for (RightTuple current = rightTuple;
            current != null;
            current = (RightTuple) rightIt.next(current)) {
          deleteChildLeftTuple(
              propagationContext, trgLeftTuples, stagedLeftTuples, current.getFirstChild());
        }
      }

      leftTuple.clearStaged();
      leftTuple = next;
    }
    betaConstraints.resetTuple(context);
  }
示例#9
0
  public void doLeftUpdates(
      NotNode notNode,
      LeftTupleSink sink,
      BetaMemory bm,
      InternalWorkingMemory wm,
      LeftTupleSets srcLeftTuples,
      LeftTupleSets trgLeftTuples,
      LeftTupleSets stagedLeftTuples) {
    LeftTupleMemory ltm = bm.getLeftTupleMemory();
    RightTupleMemory rtm = bm.getRightTupleMemory();
    ContextEntry[] contextEntry = bm.getContext();
    BetaConstraints constraints = notNode.getRawConstraints();
    boolean leftUpdateOptimizationAllowed = notNode.isLeftUpdateOptimizationAllowed();

    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      FastIterator rightIt = notNode.getRightIterator(rtm);
      RightTuple firstRightTuple = notNode.getFirstRightTuple(leftTuple, rtm, null, rightIt);

      // If in memory, remove it, because we'll need to add it anyway if it's not blocked, to ensure
      // iteration order
      RightTuple blocker = leftTuple.getBlocker();
      if (blocker == null) {
        if (leftTuple.getMemory()
            != null) { // memory can be null, if blocker was deleted in same do loop
          ltm.remove(leftTuple);
        }
      } else {
        // check if we changed bucket
        if (rtm.isIndexed() && !rightIt.isFullIterator()) {
          // if newRightTuple is null, we assume there was a bucket change and that bucket is empty
          if (firstRightTuple == null || firstRightTuple.getMemory() != blocker.getMemory()) {
            blocker.removeBlocked(leftTuple);
            blocker = null;
          }
        }
      }

      constraints.updateFromTuple(contextEntry, wm, leftTuple);

      if (!leftUpdateOptimizationAllowed && blocker != null) {
        blocker.removeBlocked(leftTuple);
        blocker = null;
      }

      // if we where not blocked before (or changed buckets), or the previous blocker no longer
      // blocks, then find the next blocker
      if (blocker == null
          || !constraints.isAllowedCachedLeft(contextEntry, blocker.getFactHandle())) {
        if (blocker != null) {
          // remove previous blocker if it exists, as we know it doesn't block any more
          blocker.removeBlocked(leftTuple);
        }

        // find first blocker, because it's a modify, we need to start from the beginning again
        for (RightTuple newBlocker = firstRightTuple;
            newBlocker != null;
            newBlocker = (RightTuple) rightIt.next(newBlocker)) {
          if (constraints.isAllowedCachedLeft(contextEntry, newBlocker.getFactHandle())) {
            leftTuple.setBlocker(newBlocker);
            newBlocker.addBlocked(leftTuple);

            break;
          }
        }

        LeftTuple childLeftTuple = leftTuple.getFirstChild();

        if (leftTuple.getBlocker() != null) {
          // blocked
          if (childLeftTuple != null) {
            // blocked, with previous children, so must have not been previously blocked, so retract
            // no need to remove, as we removed at the start
            // to be matched against, as it's now blocked
            childLeftTuple.setPropagationContext(
                leftTuple
                    .getBlocker()
                    .getPropagationContext()); // we have the righttuple, so use it for the pctx
            RuleNetworkEvaluator.deleteLeftChild(childLeftTuple, trgLeftTuples, stagedLeftTuples);
          } // else: it's blocked now and no children so blocked before, thus do nothing
        } else if (childLeftTuple == null) {
          // not blocked, with no children, must have been previously blocked so assert
          ltm.add(leftTuple); // add to memory so other fact handles can attempt to match
          trgLeftTuples.addInsert(
              sink.createLeftTuple(
                  leftTuple,
                  sink,
                  leftTuple.getPropagationContext(),
                  true)); // use leftTuple for the pctx here, as the right one is not available
          // this won't cause a problem, as the trigger tuple (to the left) will be more recent
          // anwyay
        } else {
          updateChildLeftTuple(childLeftTuple, stagedLeftTuples, trgLeftTuples);

          // not blocked, with children, so wasn't previous blocked and still isn't so modify
          ltm.add(leftTuple); // add to memory so other fact handles can attempt to match
          childLeftTuple.reAddLeft();
        }
      }
      leftTuple.clearStaged();
      leftTuple = next;
    }
    constraints.resetTuple(contextEntry);
  }
示例#10
0
  private void doRiaNode2(
      InternalWorkingMemory wm, TupleSets<LeftTuple> srcTuples, RightInputAdapterNode riaNode) {

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

    BetaNode betaNode = (BetaNode) sinks[0];
    BetaMemory bm;
    Memory nodeMem = wm.getNodeMemory(betaNode);
    if (NodeTypeEnums.AccumulateNode == betaNode.getType()) {
      bm = ((AccumulateMemory) nodeMem).getBetaMemory();
    } else {
      bm = (BetaMemory) nodeMem;
    }

    // Build up iteration array for other sinks
    BetaNode[] bns = null;
    BetaMemory[] bms = null;
    int length = sinks.length;
    if (length > 1) {
      bns = new BetaNode[sinks.length - 1];
      bms = new BetaMemory[sinks.length - 1];
      for (int i = 1; i < length; i++) {
        bns[i - 1] = (BetaNode) sinks[i];
        Memory nodeMem2 = wm.getNodeMemory(bns[i - 1]);
        if (NodeTypeEnums.AccumulateNode == betaNode.getType()) {
          bms[i - 1] = ((AccumulateMemory) nodeMem2).getBetaMemory();
        } else {
          bms[i - 1] = (BetaMemory) nodeMem2;
        }
      }
    }

    length--; // subtract one, as first is not in the array;
    for (LeftTuple leftTuple = srcTuples.getInsertFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      PropagationContext pctx = leftTuple.getPropagationContext();
      InternalFactHandle handle = riaNode.createFactHandle(leftTuple, pctx, wm);

      RightTuple rightTuple = new RightTupleImpl(handle, betaNode);
      leftTuple.setContextObject(handle);
      rightTuple.setPropagationContext(pctx);

      if (bm.getStagedRightTuples().isEmpty()) {
        bm.setNodeDirtyWithoutNotify();
      }
      bm.getStagedRightTuples().addInsert(rightTuple);

      if (bns != null) {
        // Add peered RightTuples, they are attached to FH - unlink LeftTuples that has a peer ref
        for (int i = 0; i < length; i++) {
          rightTuple = new RightTupleImpl(handle, bns[i]);
          rightTuple.setPropagationContext(pctx);

          if (bms[i].getStagedRightTuples().isEmpty()) {
            bms[i].setNodeDirtyWithoutNotify();
          }
          bms[i].getStagedRightTuples().addInsert(rightTuple);
        }
      }

      leftTuple.clearStaged();
      leftTuple = next;
    }

    for (LeftTuple leftTuple = srcTuples.getDeleteFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      InternalFactHandle handle = (InternalFactHandle) leftTuple.getContextObject();
      RightTuple rightTuple = handle.getFirstRightTuple();
      TupleSets<RightTuple> rightTuples = bm.getStagedRightTuples();

      if (rightTuples.isEmpty()) {
        bm.setNodeDirtyWithoutNotify();
      }
      rightTuples.addDelete(rightTuple);

      if (bns != null) {
        // Add peered RightTuples, they are attached to FH - unlink LeftTuples that has a peer ref
        for (int i = 0; i < length; i++) {
          rightTuple = rightTuple.getHandleNext();
          rightTuples = bms[i].getStagedRightTuples();
          if (rightTuples.isEmpty()) {
            bms[i].setNodeDirtyWithoutNotify();
          }
          rightTuples.addDelete(rightTuple);
        }
      }

      leftTuple.clearStaged();
      leftTuple = next;
    }

    for (LeftTuple leftTuple = srcTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      InternalFactHandle handle = (InternalFactHandle) leftTuple.getContextObject();
      RightTuple rightTuple = handle.getFirstRightTuple();
      TupleSets<RightTuple> rightTuples = bm.getStagedRightTuples();

      if (rightTuples.isEmpty()) {
        bm.setNodeDirtyWithoutNotify();
      }
      rightTuples.addUpdate(rightTuple);

      if (bns != null) {
        // Add peered RightTuples, they are attached to FH - unlink LeftTuples that has a peer ref
        for (int i = 0; i < length; i++) {
          rightTuple = rightTuple.getHandleNext();
          rightTuples = bms[i].getStagedRightTuples();

          if (rightTuples.isEmpty()) {
            bms[i].setNodeDirtyWithoutNotify();
          }
          rightTuples.addUpdate(rightTuple);
        }
      }

      leftTuple.clearStaged();
      leftTuple = next;
    }

    srcTuples.resetAll();
  }