@Override public TrackingToken upperBound(TrackingToken otherToken) { Assert.isTrue(otherToken instanceof GapAwareTrackingToken, () -> "Incompatible token type provided."); GapAwareTrackingToken other = (GapAwareTrackingToken) otherToken; SortedSet<Long> newGaps = CollectionUtils.intersect(this.gaps, other.gaps, ConcurrentSkipListSet::new); long min = Math.min(this.index, other.index) + 1; SortedSet<Long> mergedGaps = CollectionUtils.merge(this.gaps.tailSet(min), other.gaps.tailSet(min), ConcurrentSkipListSet::new); newGaps.addAll(mergedGaps); return new GapAwareTrackingToken(Math.max(this.index, other.index), newGaps); }
/** * Returns a new {@link GapAwareTrackingToken} instance based on the given {@code index} and collection of {@code * gaps}. * * @param index the highest global sequence number of events up until (and including) this tracking token * @param gaps global sequence numbers of events that have not been seen yet even though these sequence numbers are * smaller than the current index. These missing sequence numbers may be filled in later when those * events get committed to the store or may never be filled in if those events never get committed. * @return a new tracking token from given index and gaps */ @JsonCreator public static GapAwareTrackingToken newInstance(@JsonProperty("index") long index, @JsonProperty("gaps") Collection<Long> gaps) { if (gaps.isEmpty()) { return new GapAwareTrackingToken(index, Collections.emptySortedSet()); } SortedSet<Long> gapSet = new ConcurrentSkipListSet<>(gaps); Assert.isTrue(gapSet.last() < index, () -> String.format("Gap indices [%s] should all be smaller than head index [%d]", gaps, index)); return new GapAwareTrackingToken(index, gapSet); }
@Override public GapAwareTrackingToken lowerBound(TrackingToken other) { Assert.isTrue(other instanceof GapAwareTrackingToken, () -> "Incompatible token type provided."); GapAwareTrackingToken otherToken = (GapAwareTrackingToken) other; SortedSet<Long> mergedGaps = new ConcurrentSkipListSet<>(this.gaps); mergedGaps.addAll(otherToken.gaps); long mergedIndex = calculateIndex(otherToken, mergedGaps); mergedGaps.removeIf(i -> i >= mergedIndex); return new GapAwareTrackingToken(mergedIndex, mergedGaps); }
return new GapAwareTrackingToken(newIndex, gaps);
/** * Returns a new {@link GapAwareTrackingToken} instance based on the given {@code index} and collection of {@code * gaps}. * * @param index the highest global sequence number of events up until (and including) this tracking token * @param gaps global sequence numbers of events that have not been seen yet even though these sequence numbers are * smaller than the current index. These missing sequence numbers may be filled in later when those * events get committed to the store or may never be filled in if those events never get committed. * @return a new tracking token from given index and gaps */ @JsonCreator public static GapAwareTrackingToken newInstance(@JsonProperty("index") long index, @JsonProperty("gaps") Collection<Long> gaps) { if (gaps.isEmpty()) { return new GapAwareTrackingToken(index, Collections.emptySortedSet()); } SortedSet<Long> gapSet = new ConcurrentSkipListSet<>(gaps); Assert.isTrue(gapSet.last() < index, () -> String.format("Gap indices [%s] should all be smaller than head index [%d]", gaps, index)); return new GapAwareTrackingToken(index, gapSet); }
@Override public TrackingToken upperBound(TrackingToken otherToken) { Assert.isTrue(otherToken instanceof GapAwareTrackingToken, () -> "Incompatible token type provided."); GapAwareTrackingToken other = (GapAwareTrackingToken) otherToken; SortedSet<Long> newGaps = CollectionUtils.intersect(this.gaps, other.gaps, ConcurrentSkipListSet::new); long min = Math.min(this.index, other.index) + 1; SortedSet<Long> mergedGaps = CollectionUtils.merge(this.gaps.tailSet(min), other.gaps.tailSet(min), ConcurrentSkipListSet::new); newGaps.addAll(mergedGaps); return new GapAwareTrackingToken(Math.max(this.index, other.index), newGaps); }
@Override public GapAwareTrackingToken lowerBound(TrackingToken other) { Assert.isTrue(other instanceof GapAwareTrackingToken, () -> "Incompatible token type provided."); GapAwareTrackingToken otherToken = (GapAwareTrackingToken) other; SortedSet<Long> mergedGaps = new ConcurrentSkipListSet<>(this.gaps); mergedGaps.addAll(otherToken.gaps); long mergedIndex = calculateIndex(otherToken, mergedGaps); mergedGaps.removeIf(i -> i >= mergedIndex); return new GapAwareTrackingToken(mergedIndex, mergedGaps); }
return new GapAwareTrackingToken(newIndex, gaps);