Skip to content

Commit c6592b0

Browse files
mp911dechristophstrobl
authored andcommitted
DATAMONGO-2393 - Polishing.
Extract read requests into inner class. Original Pull Request: spring-projects#799
1 parent 48176a8 commit c6592b0

File tree

1 file changed

+79
-55
lines changed

1 file changed

+79
-55
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/AsyncInputStreamAdapter.java

+79-55
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@
2727
import java.nio.ByteBuffer;
2828
import java.util.Queue;
2929
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
30-
import java.util.concurrent.atomic.AtomicLong;
3130
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
32-
import java.util.function.BiConsumer;
3331

3432
import org.reactivestreams.Publisher;
3533
import org.reactivestreams.Subscription;
@@ -74,8 +72,7 @@ class AsyncInputStreamAdapter implements AsyncInputStream {
7472
private volatile boolean cancelled;
7573
private volatile boolean allDataBuffersReceived;
7674
private volatile Throwable error;
77-
private final Queue<BiConsumer<DataBuffer, Integer>> readRequests = Queues.<BiConsumer<DataBuffer, Integer>> small()
78-
.get();
75+
private final Queue<ReadRequest> readRequests = Queues.<ReadRequest> small().get();
7976

8077
private final Queue<DataBuffer> bufferQueue = Queues.<DataBuffer> small().get();
8178

@@ -94,52 +91,7 @@ public Publisher<Integer> read(ByteBuffer dst) {
9491

9592
return Flux.create(sink -> {
9693

97-
AtomicLong written = new AtomicLong();
98-
readRequests.offer((db, bytecount) -> {
99-
100-
try {
101-
102-
if (error != null) {
103-
onError(sink, error);
104-
return;
105-
}
106-
107-
if (bytecount == -1) {
108-
109-
onComplete(sink, written.get() > 0 ? written.intValue() : -1);
110-
return;
111-
}
112-
113-
ByteBuffer byteBuffer = db.asByteBuffer();
114-
int remaining = byteBuffer.remaining();
115-
int writeCapacity = Math.min(dst.remaining(), remaining);
116-
int limit = Math.min(byteBuffer.position() + writeCapacity, byteBuffer.capacity());
117-
int toWrite = limit - byteBuffer.position();
118-
119-
if (toWrite == 0) {
120-
121-
onComplete(sink, written.intValue());
122-
return;
123-
}
124-
125-
int oldPosition = byteBuffer.position();
126-
127-
byteBuffer.limit(toWrite);
128-
dst.put(byteBuffer);
129-
byteBuffer.limit(byteBuffer.capacity());
130-
byteBuffer.position(oldPosition);
131-
db.readPosition(db.readPosition() + toWrite);
132-
written.addAndGet(toWrite);
133-
134-
} catch (Exception e) {
135-
onError(sink, e);
136-
} finally {
137-
138-
if (db != null && db.readableByteCount() == 0) {
139-
DataBufferUtils.release(db);
140-
}
141-
}
142-
});
94+
readRequests.offer(new ReadRequest(sink, dst));
14395

14496
sink.onCancel(this::terminatePendingReads);
14597
sink.onDispose(this::terminatePendingReads);
@@ -243,12 +195,12 @@ void drainLoop() {
243195
continue;
244196
}
245197

246-
BiConsumer<DataBuffer, Integer> consumer = AsyncInputStreamAdapter.this.readRequests.peek();
198+
ReadRequest consumer = AsyncInputStreamAdapter.this.readRequests.peek();
247199
if (consumer == null) {
248200
break;
249201
}
250202

251-
consumer.accept(wip, wip.readableByteCount());
203+
consumer.transferBytes(wip, wip.readableByteCount());
252204
}
253205

254206
if (bufferQueue.isEmpty()) {
@@ -269,10 +221,10 @@ void drainLoop() {
269221
*/
270222
void terminatePendingReads() {
271223

272-
BiConsumer<DataBuffer, Integer> readers;
224+
ReadRequest readers;
273225

274226
while ((readers = readRequests.poll()) != null) {
275-
readers.accept(null, -1);
227+
readers.onComplete();
276228
}
277229
}
278230

@@ -299,7 +251,7 @@ public void onNext(DataBuffer dataBuffer) {
299251
return;
300252
}
301253

302-
BiConsumer<DataBuffer, Integer> readRequest = AsyncInputStreamAdapter.this.readRequests.peek();
254+
ReadRequest readRequest = AsyncInputStreamAdapter.this.readRequests.peek();
303255

304256
if (readRequest == null) {
305257

@@ -336,4 +288,76 @@ public void onComplete() {
336288
}
337289
}
338290
}
291+
292+
/**
293+
* Request to read bytes and transfer these to the associated {@link ByteBuffer}.
294+
*/
295+
class ReadRequest {
296+
297+
private final FluxSink<Integer> sink;
298+
private final ByteBuffer dst;
299+
300+
private int writtenBytes;
301+
302+
ReadRequest(FluxSink<Integer> sink, ByteBuffer dst) {
303+
this.sink = sink;
304+
this.dst = dst;
305+
this.writtenBytes = -1;
306+
}
307+
308+
public void onComplete() {
309+
310+
if (error != null) {
311+
AsyncInputStreamAdapter.this.onError(sink, error);
312+
return;
313+
}
314+
315+
AsyncInputStreamAdapter.this.onComplete(sink, writtenBytes);
316+
}
317+
318+
public void transferBytes(DataBuffer db, int bytes) {
319+
320+
try {
321+
322+
if (error != null) {
323+
AsyncInputStreamAdapter.this.onError(sink, error);
324+
return;
325+
}
326+
327+
ByteBuffer byteBuffer = db.asByteBuffer();
328+
int remaining = byteBuffer.remaining();
329+
int writeCapacity = Math.min(dst.remaining(), remaining);
330+
int limit = Math.min(byteBuffer.position() + writeCapacity, byteBuffer.capacity());
331+
int toWrite = limit - byteBuffer.position();
332+
333+
if (toWrite == 0) {
334+
335+
AsyncInputStreamAdapter.this.onComplete(sink, writtenBytes);
336+
return;
337+
}
338+
339+
int oldPosition = byteBuffer.position();
340+
341+
byteBuffer.limit(toWrite);
342+
dst.put(byteBuffer);
343+
byteBuffer.limit(byteBuffer.capacity());
344+
byteBuffer.position(oldPosition);
345+
db.readPosition(db.readPosition() + toWrite);
346+
347+
if (writtenBytes == -1) {
348+
writtenBytes = bytes;
349+
} else {
350+
writtenBytes += bytes;
351+
}
352+
353+
} catch (Exception e) {
354+
AsyncInputStreamAdapter.this.onError(sink, e);
355+
} finally {
356+
357+
if (db.readableByteCount() == 0) {
358+
DataBufferUtils.release(db);
359+
}
360+
}
361+
}
362+
}
339363
}

0 commit comments

Comments
 (0)