Exemple #1
0
  private void intersectSequences(SargIntervalSequence targetSeq, SargIntervalSequence sourceSeq) {
    ListIterator<SargInterval> targetIter = targetSeq.list.listIterator();
    if (!targetIter.hasNext()) {
      // No target intervals at all, so quit.
      return;
    }

    ListIterator<SargInterval> sourceIter = sourceSeq.list.listIterator();
    if (!sourceIter.hasNext()) {
      // No source intervals at all, so result is empty
      targetSeq.list.clear();
      return;
    }

    // Start working on first source and target intervals
    SargInterval target = targetIter.next();
    SargInterval source = sourceIter.next();

    // loop invariant:  both source and target are non-null on entry
    for (; ; ) {
      if (source.getUpperBound().compareTo(target.getLowerBound()) < 0) {
        // Source is completely below target; discard it and
        // move on to next one.
        if (!sourceIter.hasNext()) {
          // No more sources.
          break;
        }
        source = sourceIter.next();
        continue;
      }

      if (target.getUpperBound().compareTo(source.getLowerBound()) < 0) {
        // Target is completely below source; discard it and
        // move on to next one.
        targetIter.remove();
        if (!targetIter.hasNext()) {
          // All done.
          return;
        }
        target = targetIter.next();
        continue;
      }

      // Overlap case:  perform intersection of the two intervals.

      if (source.getLowerBound().compareTo(target.getLowerBound()) > 0) {
        // Source starts after target starts, so trim the target.
        target.setLower(
            source.getLowerBound().getCoordinate(), source.getLowerBound().getStrictness());
      }

      int c = source.getUpperBound().compareTo(target.getUpperBound());
      if (c < 0) {
        // The source ends before the target ends, so split the target
        // into two parts.  The first part will be kept for sure; the
        // second part will be compared against further source ranges.
        SargInterval newTarget = new SargInterval(factory, dataType);
        newTarget.setLower(
            source.getUpperBound().getCoordinate(),
            source.getUpperBound().getStrictnessComplement());

        if (target.getUpperBound().isFinite()) {
          newTarget.setUpper(
              target.getUpperBound().getCoordinate(), target.getUpperBound().getStrictness());
        }

        // Trim current target to exclude the part of the range
        // which will move to newTarget.
        target.setUpper(
            source.getUpperBound().getCoordinate(), source.getUpperBound().getStrictness());

        // Insert newTarget after target.  This makes newTarget
        // into previous().
        targetIter.add(newTarget);

        // Next time through, work on newTarget.
        // targetIter.previous() is pointing at the newTarget.
        target = targetIter.previous();

        // Now targetIter.next() is also pointing at the newTarget;
        // need to do this redundant step to get targetIter in sync
        // with target.
        target = targetIter.next();

        // Advance source.
        if (!sourceIter.hasNext()) {
          break;
        }
        source = sourceIter.next();
      } else if (c == 0) {
        // Source and target ends coincide, so advance both source and
        // target.
        if (!targetIter.hasNext()) {
          return;
        }
        target = targetIter.next();
        if (!sourceIter.hasNext()) {
          break;
        }
        source = sourceIter.next();
      } else {
        // Source ends after target ends, so advance target.
        assert (c > 0);
        if (!targetIter.hasNext()) {
          return;
        }
        target = targetIter.next();
      }
    }

    // Discard any remaining targets since they didn't have corresponding
    // sources.
    for (; ; ) {
      targetIter.remove();
      if (!targetIter.hasNext()) {
        break;
      }
      targetIter.next();
    }
  }