[ https://issues.apache.org/jira/browse/ORC-251?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16542234#comment-16542234 ]
ASF GitHub Bot commented on ORC-251: ------------------------------------ Github user prasanthj commented on a diff in the pull request: https://github.com/apache/orc/pull/278#discussion_r202146043 --- Diff: java/core/src/java/org/apache/orc/impl/InStream.java --- @@ -55,112 +60,137 @@ public long getStreamLength() { @Override public abstract void close(); + static int getRangeNumber(DiskRangeList list, DiskRangeList current) { + int result = 0; + DiskRangeList range = list; + while (range != null && range != current) { + result += 1; + range = range.next; + } + return result; + } + + /** + * Implements a stream over an uncompressed stream. + */ public static class UncompressedStream extends InStream { - private List<DiskRange> bytes; + private DiskRangeList bytes; private long length; protected long currentOffset; - private ByteBuffer range; - private int currentRange; + protected ByteBuffer decrypted; + protected DiskRangeList currentRange; + + /** + * Create the stream without calling reset on it. + * This is used for the subclass that needs to do more setup. + * @param name name of the stream + * @param length the number of bytes for the stream + */ + public UncompressedStream(String name, long length) { + super(name, length); + } - public UncompressedStream(String name, List<DiskRange> input, long length) { + public UncompressedStream(String name, + DiskRangeList input, + long length) { super(name, length); reset(input, length); } - protected void reset(List<DiskRange> input, long length) { + protected void reset(DiskRangeList input, long length) { this.bytes = input; this.length = length; - currentRange = 0; - currentOffset = 0; - range = null; + currentOffset = input == null ? 0 : input.getOffset(); + setCurrent(input, true); } @Override public int read() { - if (range == null || range.remaining() == 0) { + if (decrypted == null || decrypted.remaining() == 0) { if (currentOffset == length) { return -1; } - seek(currentOffset); + setCurrent(currentRange.next, false); } currentOffset += 1; - return 0xff & range.get(); + return 0xff & decrypted.get(); + } + + protected void setCurrent(DiskRangeList newRange, boolean isJump) { + currentRange = newRange; + if (newRange != null) { + decrypted = newRange.getData().slice(); + decrypted.position((int) (currentOffset - newRange.getOffset())); + } } @Override public int read(byte[] data, int offset, int length) { - if (range == null || range.remaining() == 0) { + if (decrypted == null || decrypted.remaining() == 0) { if (currentOffset == this.length) { return -1; } - seek(currentOffset); + setCurrent(currentRange.next, false); } - int actualLength = Math.min(length, range.remaining()); - range.get(data, offset, actualLength); + int actualLength = Math.min(length, decrypted.remaining()); + decrypted.get(data, offset, actualLength); currentOffset += actualLength; return actualLength; } @Override public int available() { - if (range != null && range.remaining() > 0) { - return range.remaining(); + if (decrypted != null && decrypted.remaining() > 0) { + return decrypted.remaining(); } return (int) (length - currentOffset); } @Override public void close() { - currentRange = bytes.size(); + currentRange = null; currentOffset = length; // explicit de-ref of bytes[] - bytes.clear(); + decrypted = null; + bytes = null; } @Override public void seek(PositionProvider index) throws IOException { seek(index.getNext()); } - public void seek(long desired) { - if (desired == 0 && bytes.isEmpty()) { + public void seek(long desired) throws IOException { + if (desired == 0 && bytes == null) { return; } - int i = 0; - for (DiskRange curRange : bytes) { - if (curRange.getOffset() <= desired && - (desired - curRange.getOffset()) < curRange.getLength()) { - currentOffset = desired; - currentRange = i; - this.range = curRange.getData().duplicate(); - int pos = range.position(); - pos += (int)(desired - curRange.getOffset()); // this is why we duplicate - this.range.position(pos); - return; - } - ++i; - } - // if they are seeking to the precise end, go ahead and let them go there - int segments = bytes.size(); - if (segments != 0 && desired == bytes.get(segments - 1).getEnd()) { + // If we are seeking inside of the current range, just reposition. + if (currentRange != null && desired >= currentRange.getOffset() && + desired < currentRange.getEnd()) { --- End diff -- <= currentRange.getEnd()? > Modify InStream and OutStream to optionally encrypt data > -------------------------------------------------------- > > Key: ORC-251 > URL: https://issues.apache.org/jira/browse/ORC-251 > Project: ORC > Issue Type: Sub-task > Reporter: Owen O'Malley > Assignee: Owen O'Malley > Priority: Major > -- This message was sent by Atlassian JIRA (v7.6.3#76005)