@Test void testUpperBound() { GapAwareTrackingToken token0 = GapAwareTrackingToken.newInstance(9, emptyList()); GapAwareTrackingToken token1 = GapAwareTrackingToken.newInstance(10, singleton(9L)); GapAwareTrackingToken token2 = GapAwareTrackingToken.newInstance(10, asList(9L, 8L)); GapAwareTrackingToken token3 = GapAwareTrackingToken.newInstance(15, singletonList(14L)); GapAwareTrackingToken token4 = GapAwareTrackingToken.newInstance(15, asList(14L, 9L, 8L)); GapAwareTrackingToken token5 = GapAwareTrackingToken.newInstance(14, emptyList()); assertEquals(GapAwareTrackingToken.newInstance(10, emptyList()), token0.upperBound(token1)); assertEquals(token1, token1.upperBound(token2)); assertEquals(token3, token1.upperBound(token3)); assertEquals(GapAwareTrackingToken.newInstance(15, asList(14L, 9L)), token1.upperBound(token4)); assertEquals(GapAwareTrackingToken.newInstance(15, asList(14L, 9L, 8L)), token2.upperBound(token4)); assertEquals(GapAwareTrackingToken.newInstance(15, emptyList()), token5.upperBound(token3)); }
@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, Math.min(gapTruncationIndex, other.gapTruncationIndex)); }
GapAwareTrackingToken implements TrackingToken, Serializable { @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, Math.min(gapTruncationIndex, other.gapTruncationIndex)); } }
GapAwareTrackingToken implements TrackingToken, Serializable { @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, Math.min(gapTruncationIndex, other.gapTruncationIndex)); } @JsonCreator @ConstructorProperties({"index", "gaps"})  GapAwareTrackingToken(@JsonProperty("index") long index, @JsonProperty("gaps") Collection<Long> gaps); private  GapAwareTrackingToken(long index, SortedSet<Long> gaps, long gapTruncationIndex); }
GapAwareTrackingToken implements TrackingToken, Serializable { @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, Math.min(gapTruncationIndex, other.gapTruncationIndex)); } @JsonCreator @ConstructorProperties({"index", "gaps"})  GapAwareTrackingToken(@JsonProperty("index") long index, @JsonProperty("gaps") Collection<Long> gaps); private  GapAwareTrackingToken(long index, SortedSet<Long> gaps, long gapTruncationIndex); static GapAwareTrackingToken newInstance(long index, Collection<Long> gaps); GapAwareTrackingToken advanceTo(long index, int maxGapOffset); GapAwareTrackingToken withGapsTruncatedAt(long truncationPoint); long getIndex(); SortedSet<Long> getGaps(); @Override GapAwareTrackingToken lowerBound(TrackingToken other); @Override TrackingToken upperBound(TrackingToken otherToken); @Override boolean covers(TrackingToken other); boolean hasGaps(); @Override boolean equals(Object o); @Override int hashCode(); @Override String toString(); @Override OptionalLong position(); }
GapAwareTrackingToken implements TrackingToken, Serializable { @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, Math.min(gapTruncationIndex, other.gapTruncationIndex)); } @JsonCreator @ConstructorProperties({"index", "gaps"})  GapAwareTrackingToken(@JsonProperty("index") long index, @JsonProperty("gaps") Collection<Long> gaps); private  GapAwareTrackingToken(long index, SortedSet<Long> gaps, long gapTruncationIndex); static GapAwareTrackingToken newInstance(long index, Collection<Long> gaps); GapAwareTrackingToken advanceTo(long index, int maxGapOffset); GapAwareTrackingToken withGapsTruncatedAt(long truncationPoint); long getIndex(); SortedSet<Long> getGaps(); @Override GapAwareTrackingToken lowerBound(TrackingToken other); @Override TrackingToken upperBound(TrackingToken otherToken); @Override boolean covers(TrackingToken other); boolean hasGaps(); @Override boolean equals(Object o); @Override int hashCode(); @Override String toString(); @Override OptionalLong position();  }