Example #1
0
    // implement Comparator
    public int compare(SargInterval i1, SargInterval i2) {
      int c = i1.getLowerBound().compareTo(i2.getLowerBound());
      if (c != 0) {
        return c;
      }

      return i1.getUpperBound().compareTo(i2.getUpperBound());
    }
Example #2
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();
    }
  }
Example #3
0
  private SargIntervalSequence evaluateUnion(List<SargIntervalSequence> list) {
    SargIntervalSequence seq = new SargIntervalSequence();

    // Toss all entries from each sequence in the list into one big sorted
    // set.
    SortedSet<SargInterval> intervals = new TreeSet<SargInterval>(new IntervalComparator());
    for (SargIntervalSequence childSeq : list) {
      intervals.addAll(childSeq.getList());
    }

    // Now, overlapping ranges are consecutive in the set.  Merge them by
    // increasing the upper bound of the first; discard the others.  In the
    // example, [4, 6] and [5, 7) are combined to form [4, 7).  (7, 8] is
    // not merged with the new range because neither range contains the
    // value 7.
    //
    // Input:
    //          1  2  3  4  5  6  7  8  9
    // 1 [1, 3] [-----]
    // 2 [4, 6]          [-----]
    // 3 [5, 7)             [-----)
    // 4 (7, 8]                   (--]
    //
    // Output:
    // 1 [1, 3] [-----]
    // 2 [4, 7)          [--------)
    // 3 (7, 8]                   (--]
    SargInterval accumulator = null;
    for (SargInterval interval : intervals) {
      // Empty intervals should have been previously filtered out.
      assert (!interval.isEmpty());

      if (accumulator == null) {
        // The very first interval:  start accumulating.
        accumulator = new SargInterval(factory, getDataType());
        accumulator.copyFrom(interval);
        seq.addInterval(accumulator);
        continue;
      }

      if (accumulator.contains(interval)) {
        // Just drop new interval because it's already covered
        // by accumulator.
        continue;
      }

      // Test for overlap.
      int c = interval.getLowerBound().compareTo(accumulator.getUpperBound());

      // If no overlap, test for touching instead.
      if (c > 0) {
        if (interval.getLowerBound().isTouching(accumulator.getUpperBound())) {
          // Force test below to pass.
          c = -1;
        }
      }

      if (c <= 0) {
        // Either touching or overlap:  grow the accumulator.
        accumulator.upperBound.copyFrom(interval.getUpperBound());
      } else {
        // Disjoint:  start accumulating a new interval
        accumulator = new SargInterval(factory, getDataType());
        accumulator.copyFrom(interval);
        seq.addInterval(accumulator);
      }
    }

    return seq;
  }