public void addOrMerge(long offset, long end, boolean doMerge, boolean doLogNew) { if (doMerge && tail != null && tail.merge(offset, end)) return; if (doLogNew) { LOG.info("Creating new range; last range (which can include some previous adds) was " + tail); } DiskRangeList node = new DiskRangeList(offset, end); if (tail == null) { head = tail = node; } else { tail = tail.insertAfter(node); } }
/** Splits current element in the list, using DiskRange::slice */ public DiskRangeList split(long cOffset) { insertAfter((DiskRangeList)this.sliceAndShift(cOffset, end, 0)); return replaceSelfWith((DiskRangeList)this.sliceAndShift(offset, cOffset, 0)); }
if (range.hasData()) { range = range.next; continue; int len = (int) (range.getEnd() - range.getOffset()); long off = range.getOffset(); file.seek(base + off); if (zcr != null) { BufferChunk bc = new BufferChunk(partial, off); if (!hasReplaced) { range.replaceSelfWith(bc); hasReplaced = true; } else { range.insertAfter(bc); ByteBuffer directBuf = ByteBuffer.allocateDirect(len); readDirect(file, len, directBuf); range = range.replaceSelfWith(new BufferChunk(directBuf, range.getOffset())); } else { byte[] buffer = new byte[len]; file.readFully(buffer, 0, buffer.length); range = range.replaceSelfWith(new BufferChunk(ByteBuffer.wrap(buffer), range.getOffset()));
while (range != null) { if (!inRange) { if (range.getEnd() <= offset) { range = range.next; continue; // Skip until we are in range. if (range.getOffset() < offset) { buffers.add(range.sliceAndShift(offset, Math.min(streamEnd, range.getEnd()), -offset)); if (range.getEnd() >= streamEnd) break; // Partial first buffer is also partial last buffer. range = range.next; continue; } else if (range.getOffset() >= streamEnd) { break; if (range.getEnd() > streamEnd) { buffers.add(range.sliceAndShift(range.getOffset(), streamEnd, -offset)); break; buffers.add(range.sliceAndShift(range.getOffset(), range.getEnd(), -offset)); if (range.getEnd() == streamEnd) break; range = range.next;
/** * Inserts an intersecting range after current in the list and adjusts offset accordingly. * @returns the new element. */ public DiskRangeList insertPartAfter(DiskRangeList other) { assert other.offset <= this.end; this.end = other.offset; return insertAfter(other); }
@VisibleForTesting public DiskRangeList[] listToArray() { DiskRangeList[] result = new DiskRangeList[listSize()]; int i = 0; DiskRangeList current = this.next; while (current != null) { result[i] = current; ++i; current = current.next; } return result; }
/** * Build a string representation of a list of disk ranges. * @param ranges ranges to stringify * @return the resulting string */ static String stringifyDiskRanges(DiskRangeList range) { StringBuilder buffer = new StringBuilder(); buffer.append("["); boolean isFirst = true; while (range != null) { if (!isFirst) { buffer.append(", "); } isFirst = false; buffer.append(range.toString()); range = range.next; } buffer.append("]"); return buffer.toString(); }
private void readAllDataStreams(StripeInformation stripe) throws IOException { long start = stripe.getIndexLength(); long end = start + stripe.getDataLength(); // explicitly trigger 1 big read DiskRangeList toRead = new DiskRangeList(start, end); bufferChunks = RecordReaderUtils.readDiskRanges(file, zcr, stripe.getOffset(), toRead, false); List<OrcProto.Stream> streamDescriptions = stripeFooter.getStreamsList(); createStreams( streamDescriptions, bufferChunks, null, codec, bufferSize, streams); }