mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-07 15:50:57 +03:00
Add parameter to limit read ahead to maximum length. Allows to use mu… (#724)
* Add parameter to limit read ahead to maximum length. Allows to use multiple concurrent threads reading from the same file with an offset without reading too much ahead for a single segment. * Review and add tests. Signed-off-by: David Kocher <dkocher@iterate.ch> Co-authored-by: Yves Langisch <yves@langisch.ch>
This commit is contained in:
@@ -224,6 +224,7 @@ public class RemoteFile
|
||||
private final byte[] b = new byte[1];
|
||||
|
||||
private final int maxUnconfirmedReads;
|
||||
private final long readAheadLimit;
|
||||
private final Queue<Promise<Response, SFTPException>> unconfirmedReads = new LinkedList<Promise<Response, SFTPException>>();
|
||||
private final Queue<Long> unconfirmedReadOffsets = new LinkedList<Long>();
|
||||
|
||||
@@ -232,17 +233,22 @@ public class RemoteFile
|
||||
private boolean eof;
|
||||
|
||||
public ReadAheadRemoteFileInputStream(int maxUnconfirmedReads) {
|
||||
assert 0 <= maxUnconfirmedReads;
|
||||
|
||||
this.maxUnconfirmedReads = maxUnconfirmedReads;
|
||||
this(maxUnconfirmedReads, 0L, -1L);
|
||||
}
|
||||
|
||||
public ReadAheadRemoteFileInputStream(int maxUnconfirmedReads, long fileOffset) {
|
||||
/**
|
||||
*
|
||||
* @param maxUnconfirmedReads Maximum number of unconfirmed requests to send
|
||||
* @param fileOffset Initial offset in file to read from
|
||||
* @param readAheadLimit Read ahead is disabled after this limit has been reached
|
||||
*/
|
||||
public ReadAheadRemoteFileInputStream(int maxUnconfirmedReads, long fileOffset, long readAheadLimit) {
|
||||
assert 0 <= maxUnconfirmedReads;
|
||||
assert 0 <= fileOffset;
|
||||
|
||||
this.maxUnconfirmedReads = maxUnconfirmedReads;
|
||||
this.requestOffset = this.responseOffset = fileOffset;
|
||||
this.readAheadLimit = readAheadLimit > 0 ? fileOffset + readAheadLimit : Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
private ByteArrayInputStream pending = new ByteArrayInputStream(new byte[0]);
|
||||
@@ -293,9 +299,18 @@ public class RemoteFile
|
||||
while (unconfirmedReads.size() <= maxUnconfirmedReads) {
|
||||
// Send read requests as long as there is no EOF and we have not reached the maximum parallelism
|
||||
int reqLen = Math.max(1024, len); // don't be shy!
|
||||
if (readAheadLimit > requestOffset) {
|
||||
long remaining = readAheadLimit - requestOffset;
|
||||
if (reqLen > remaining) {
|
||||
reqLen = (int) remaining;
|
||||
}
|
||||
}
|
||||
unconfirmedReads.add(RemoteFile.this.asyncRead(requestOffset, reqLen));
|
||||
unconfirmedReadOffsets.add(requestOffset);
|
||||
requestOffset += reqLen;
|
||||
if (requestOffset >= readAheadLimit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
long nextOffset = unconfirmedReadOffsets.peek();
|
||||
|
||||
Reference in New Issue
Block a user