/** * Returns the minimal DiskRange that encloses both this DiskRange * and otherDiskRange. If there was a gap between the ranges the * new range will cover that gap. */ public DiskRange span(DiskRange otherDiskRange) { requireNonNull(otherDiskRange, "otherDiskRange is null"); long start = Math.min(this.offset, otherDiskRange.getOffset()); long end = Math.max(getEnd(), otherDiskRange.getEnd()); return new DiskRange(start, toIntExact(end - start)); }
/** * Returns the minimal DiskRange that encloses both this DiskRange * and otherDiskRange. If there was a gap between the ranges the * new range will cover that gap. */ public DiskRange span(DiskRange otherDiskRange) { requireNonNull(otherDiskRange, "otherDiskRange is null"); long start = Math.min(this.offset, otherDiskRange.getOffset()); long end = Math.max(getEnd(), otherDiskRange.getEnd()); return new DiskRange(start, toIntExact(end - start)); }
@Override public DiskRange getRangeFor(long desiredOffset) { // Assumption: range are always read in order // Assumption: bytes that are not part of any range are never read for (; index < diskRanges.size(); index++) { DiskRange range = diskRanges.get(index); if (range.getEnd() > desiredOffset) { checkArgument(range.getOffset() <= desiredOffset); return range; } } throw new IllegalArgumentException("Invalid desiredOffset " + desiredOffset); }
@Override public DiskRange getRangeFor(long desiredOffset) { // Assumption: range are always read in order // Assumption: bytes that are not part of any range are never read while (index < diskRanges.size()) { DiskRange range = diskRanges.get(index); if (range.getEnd() > desiredOffset) { checkArgument(range.getOffset() <= desiredOffset); return range; } index++; } throw new IllegalArgumentException("Invalid desiredOffset " + desiredOffset); }
/** * Merge disk ranges that are closer than {@code maxMergeDistance}. */ public static List<DiskRange> mergeAdjacentDiskRanges(Collection<DiskRange> diskRanges, DataSize maxMergeDistance, DataSize maxReadSize) { // sort ranges by start offset List<DiskRange> ranges = new ArrayList<>(diskRanges); ranges.sort(comparingLong(DiskRange::getOffset)); // merge overlapping ranges long maxReadSizeBytes = maxReadSize.toBytes(); long maxMergeDistanceBytes = maxMergeDistance.toBytes(); ImmutableList.Builder<DiskRange> result = ImmutableList.builder(); DiskRange last = ranges.get(0); for (int i = 1; i < ranges.size(); i++) { DiskRange current = ranges.get(i); DiskRange merged = last.span(current); if (merged.getLength() <= maxReadSizeBytes && last.getEnd() + maxMergeDistanceBytes >= current.getOffset()) { last = merged; } else { result.add(last); last = current; } } result.add(last); return result.build(); }
DiskRange current = ranges.get(i); DiskRange merged = last.span(current); if (merged.getLength() <= maxReadSizeBytes && last.getEnd() + maxMergeDistanceBytes >= current.getOffset()) { last = merged;