Пример #1
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;
  }