Skip to content

Commit 8ef996b

Browse files
Fix #777: Don't request excessive read-ahead packets in RemoteFile (#778)
Due to a bug in logic introduced by #769, RemoteFile.ReadAheadRemoteFileInputStream started to send new read ahead requests for file parts that had already been requested. Every call to read() asked the server to send parts of the file from the point which is already downloaded. Instead, it should have asked to send parts after the last requested part. This commit adds exactly this logic. The bug didn't cause content corruption. It only affected performance, both on servers and on clients.
1 parent e9cb909 commit 8ef996b

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

src/main/java/net/schmizz/sshj/sftp/RemoteFile.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import java.io.IOException;
2424
import java.io.InputStream;
2525
import java.io.OutputStream;
26+
import java.util.ArrayDeque;
27+
import java.util.Deque;
2628
import java.util.LinkedList;
2729
import java.util.Queue;
2830
import java.util.concurrent.TimeUnit;
@@ -252,7 +254,7 @@ public int getLength() {
252254

253255
private final int maxUnconfirmedReads;
254256
private final long readAheadLimit;
255-
private final Queue<UnconfirmedRead> unconfirmedReads = new LinkedList<>();
257+
private final Deque<UnconfirmedRead> unconfirmedReads = new ArrayDeque<>();
256258

257259
private long currentOffset;
258260
private int maxReadLength = Integer.MAX_VALUE;
@@ -336,7 +338,14 @@ public int read(byte[] into, int off, int len) throws IOException {
336338
// we also need to go here for len <= 0, because pending may be at
337339
// EOF in which case it would return -1 instead of 0
338340

339-
long requestOffset = currentOffset;
341+
long requestOffset;
342+
if (unconfirmedReads.isEmpty()) {
343+
requestOffset = currentOffset;
344+
}
345+
else {
346+
final UnconfirmedRead lastRequest = unconfirmedReads.getLast();
347+
requestOffset = lastRequest.offset + lastRequest.length;
348+
}
340349
while (unconfirmedReads.size() <= maxUnconfirmedReads) {
341350
// Send read requests as long as there is no EOF and we have not reached the maximum parallelism
342351
int reqLen = Math.min(Math.max(1024, len), maxReadLength);

0 commit comments

Comments
 (0)