public static void dpUpdatesReorderRightMemory(BetaMemory bm, RightTupleSets srcRightTuples) {
    RightTupleMemory rtm = bm.getRightTupleMemory();

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getMemory() != null) {
        rightTuple.setTempRightTupleMemory(rightTuple.getMemory());
        rtm.remove(rightTuple);
      }
      rightTuple = next;
    }

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getTempRightTupleMemory() != null) {
        rtm.add(rightTuple);
        for (LeftTuple childLeftTuple = rightTuple.getFirstChild(); childLeftTuple != null; ) {
          LeftTuple childNext = childLeftTuple.getRightParentNext();
          childLeftTuple.reAddLeft();
          childLeftTuple = childNext;
        }
      }
      rightTuple = next;
    }
  }
Exemple #2
0
  public void doNode(
      NotNode notNode,
      LeftTupleSink sink,
      BetaMemory bm,
      InternalWorkingMemory wm,
      LeftTupleSets srcLeftTuples,
      LeftTupleSets trgLeftTuples,
      LeftTupleSets stagedLeftTuples) {
    RightTupleSets srcRightTuples = bm.getStagedRightTuples().takeAll();

    if (srcLeftTuples.getDeleteFirst() != null) {
      // left deletes must come before right deletes. Otherwise right deletes could
      // stage an insertion, that is later deleted in the rightDelete, causing potential problems
      doLeftDeletes(bm, srcLeftTuples, trgLeftTuples, stagedLeftTuples);
    }

    if (srcLeftTuples.getUpdateFirst() != null) {
      // must happen before right inserts, so it can find left tuples to block.
      RuleNetworkEvaluator.doUpdatesExistentialReorderLeftMemory(bm, srcLeftTuples);
    }

    if (srcRightTuples.getUpdateFirst() != null) {
      RuleNetworkEvaluator.doUpdatesExistentialReorderRightMemory(
          bm, notNode, srcRightTuples); // this also preserves the next rightTuple
    }

    if (srcRightTuples.getInsertFirst() != null) {
      // must come before right updates and inserts, as they might cause insert propagation, while
      // this causes delete propagations, resulting in staging clash.
      doRightInserts(notNode, bm, wm, srcRightTuples, trgLeftTuples, stagedLeftTuples);
    }

    if (srcRightTuples.getUpdateFirst() != null) {
      // must come after rightInserts and before rightDeletes, to avoid staging clash
      doRightUpdates(notNode, sink, bm, wm, srcRightTuples, trgLeftTuples, stagedLeftTuples);
    }

    if (srcRightTuples.getDeleteFirst() != null) {
      // must come after rightUpdates, to avoid staging clash
      doRightDeletes(notNode, sink, bm, wm, srcRightTuples, trgLeftTuples);
    }

    if (srcLeftTuples.getUpdateFirst() != null) {
      doLeftUpdates(notNode, sink, bm, wm, srcLeftTuples, trgLeftTuples, stagedLeftTuples);
    }

    if (srcLeftTuples.getInsertFirst() != null) {
      doLeftInserts(notNode, sink, bm, wm, srcLeftTuples, trgLeftTuples);
    }

    srcRightTuples.resetAll();
    srcLeftTuples.resetAll();
  }
Exemple #3
0
  public void doRightUpdates(
      NotNode notNode,
      LeftTupleSink sink,
      BetaMemory bm,
      InternalWorkingMemory wm,
      RightTupleSets srcRightTuples,
      LeftTupleSets trgLeftTuples,
      LeftTupleSets stagedLeftTuples) {
    LeftTupleMemory ltm = bm.getLeftTupleMemory();
    RightTupleMemory rtm = bm.getRightTupleMemory();
    ContextEntry[] contextEntry = bm.getContext();
    BetaConstraints constraints = notNode.getRawConstraints();

    boolean iterateFromStart =
        notNode.isIndexedUnificationJoin() || rtm.getIndexType().isComparison();

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      PropagationContext context = rightTuple.getPropagationContext();

      constraints.updateFromFactHandle(contextEntry, wm, rightTuple.getFactHandle());

      FastIterator leftIt = notNode.getLeftIterator(ltm);
      LeftTuple firstLeftTuple = notNode.getFirstLeftTuple(rightTuple, ltm, context, leftIt);

      LeftTuple firstBlocked = rightTuple.getTempBlocked();

      // first process non-blocked tuples, as we know only those ones are in the left memory.
      for (LeftTuple leftTuple = firstLeftTuple; leftTuple != null; ) {
        // preserve next now, in case we remove this leftTuple
        LeftTuple temp = (LeftTuple) leftIt.next(leftTuple);

        if (leftTuple.getStagedType() == LeftTuple.UPDATE) {
          // ignore, as it will get processed via left iteration. Children cannot be processed twice
          leftTuple = temp;
          continue;
        }

        // we know that only unblocked LeftTuples are  still in the memory
        if (constraints.isAllowedCachedRight(contextEntry, leftTuple)) {
          leftTuple.setBlocker(rightTuple);
          rightTuple.addBlocked(leftTuple);

          // this is now blocked so remove from memory
          ltm.remove(leftTuple);

          LeftTuple childLeftTuple = leftTuple.getFirstChild();
          if (childLeftTuple != null) {
            childLeftTuple.setPropagationContext(rightTuple.getPropagationContext());
            RuleNetworkEvaluator.deleteRightChild(childLeftTuple, trgLeftTuples, stagedLeftTuples);
          }
        }

        leftTuple = temp;
      }

      if (firstBlocked != null) {
        RightTuple rootBlocker = rightTuple.getTempNextRightTuple();
        if (rootBlocker == null) {
          iterateFromStart = true;
        }

        FastIterator rightIt = notNode.getRightIterator(rtm);

        // iterate all the existing previous blocked LeftTuples
        for (LeftTuple leftTuple = firstBlocked; leftTuple != null; ) {
          LeftTuple temp = leftTuple.getBlockedNext();

          leftTuple.clearBlocker();

          if (leftTuple.getStagedType() == LeftTuple.UPDATE) {
            // ignore, as it will get processed via left iteration. Children cannot be processed
            // twice
            // but need to add it back into list first
            leftTuple.setBlocker(rightTuple);
            rightTuple.addBlocked(leftTuple);

            leftTuple = temp;
            continue;
          }

          constraints.updateFromTuple(contextEntry, wm, leftTuple);

          if (iterateFromStart) {
            rootBlocker = notNode.getFirstRightTuple(leftTuple, rtm, null, rightIt);
          }

          // we know that older tuples have been checked so continue next
          for (RightTuple newBlocker = rootBlocker;
              newBlocker != null;
              newBlocker = (RightTuple) rightIt.next(newBlocker)) {
            // cannot select a RightTuple queued in the delete list
            // There may be UPDATE RightTuples too, but that's ok. They've already been re-added to
            // the correct bucket, safe to be reprocessed.
            if (leftTuple.getStagedType() != LeftTuple.DELETE
                && newBlocker.getStagedType() != LeftTuple.DELETE
                && constraints.isAllowedCachedLeft(contextEntry, newBlocker.getFactHandle())) {

              leftTuple.setBlocker(newBlocker);
              newBlocker.addBlocked(leftTuple);

              break;
            }
          }

          if (leftTuple.getBlocker() == null) {
            // was previous blocked and not in memory, so add
            ltm.add(leftTuple);

            // subclasses like ForallNotNode might override this propagation
            trgLeftTuples.addInsert(
                sink.createLeftTuple(leftTuple, sink, rightTuple.getPropagationContext(), true));
          }

          leftTuple = temp;
        }
      }
      rightTuple.clearStaged();
      rightTuple = next;
    }

    constraints.resetFactHandle(contextEntry);
    constraints.resetTuple(contextEntry);
  }
  public static void dpUpdatesExistentialReorderRightMemory(
      BetaMemory bm, BetaNode betaNode, RightTupleSets srcRightTuples) {
    RightTupleMemory rtm = bm.getRightTupleMemory();

    boolean resumeFromCurrent =
        !(betaNode.isIndexedUnificationJoin() || rtm.getIndexType().isComparison());

    // remove all the staged rightTuples from the memory before to readd them all
    // this is to avoid split bucket when an updated rightTuple hasn't been moved yet
    // and so it is the first entry in the wrong bucket

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getMemory() != null) {
        rightTuple.setTempRightTupleMemory(rightTuple.getMemory());

        if (resumeFromCurrent) {
          if (rightTuple.getBlocked() != null) {
            // look for a non-staged right tuple first forward ...
            RightTuple tempRightTuple = (RightTuple) rightTuple.getNext();
            while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) {
              // next cannot be an updated or deleted rightTuple
              tempRightTuple = (RightTuple) tempRightTuple.getNext();
            }

            // ... and if cannot find one try backward
            if (tempRightTuple == null) {
              tempRightTuple = (RightTuple) rightTuple.getPrevious();
              while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) {
                // next cannot be an updated or deleted rightTuple
                tempRightTuple = (RightTuple) tempRightTuple.getPrevious();
              }
            }

            rightTuple.setTempNextRightTuple(tempRightTuple);
          }
        }

        rightTuple.setTempBlocked(rightTuple.getBlocked());
        rightTuple.nullBlocked();
        rtm.remove(rightTuple);
      }
      rightTuple = next;
    }

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getTempRightTupleMemory() != null) {

        rtm.add(rightTuple);

        if (resumeFromCurrent) {
          RightTuple tempRightTuple = rightTuple.getTempNextRightTuple();
          if (rightTuple.getBlocked() != null
              && tempRightTuple == null
              && rightTuple.getMemory() == rightTuple.getTempRightTupleMemory()) {
            // the next RightTuple was null, but current RightTuple was added back into the same
            // bucket, so reset as root blocker to re-match can be attempted
            rightTuple.setTempNextRightTuple(rightTuple);
          }
        }

        for (LeftTuple childLeftTuple = rightTuple.getFirstChild(); childLeftTuple != null; ) {
          LeftTuple childNext = childLeftTuple.getRightParentNext();
          childLeftTuple.reAddLeft();
          childLeftTuple = childNext;
        }
      }
      rightTuple = next;
    }
  }