JAVA-1948: Use nToReturn calculation to determine batchSize for the … · pkdevbox/mongo-java-driver@0d36abb · GitHub
Skip to content

Commit 0d36abb

Browse files
committed
JAVA-1948: Use nToReturn calculation to determine batchSize for the getMore command, and in addition take the absolute value and then check for zero, as getMore requires that any specified batchSize be a positive integer.
1 parent d483f7e commit 0d36abb

6 files changed

Lines changed: 39 additions & 19 deletions

File tree

driver-core/src/main/com/mongodb/operation/AsyncQueryBatchCursor.java

Lines changed: 4 additions & 3 deletions

driver-core/src/main/com/mongodb/operation/FindOperation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ private Function<BsonDocument, BatchCursor<T>> transformer(final ConnectionSourc
728728
public BatchCursor<T> apply(final BsonDocument result) {
729729
QueryResult<T> queryResult = cursorDocumentToQueryResult(result.getDocument("cursor"),
730730
connection.getDescription().getServerAddress());
731-
return new QueryBatchCursor<T>(queryResult, 0, batchSize, decoder, source);
731+
return new QueryBatchCursor<T>(queryResult, limit, batchSize, decoder, source);
732732
}
733733
};
734734
}
@@ -740,7 +740,7 @@ private Function<BsonDocument, AsyncBatchCursor<T>> asyncTransformer(final Async
740740
public AsyncBatchCursor<T> apply(final BsonDocument result) {
741741
QueryResult<T> queryResult = cursorDocumentToQueryResult(result.getDocument("cursor"),
742742
connection.getDescription().getServerAddress());
743-
return new AsyncQueryBatchCursor<T>(queryResult, 0, batchSize, decoder, source, connection);
743+
return new AsyncQueryBatchCursor<T>(queryResult, limit, batchSize, decoder, source, connection);
744744
}
745745
};
746746
}

driver-core/src/main/com/mongodb/operation/QueryBatchCursor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ class QueryBatchCursor<T> implements BatchCursor<T> {
7777

7878
initFromQueryResult(firstQueryResult);
7979
if (limitReached()) {
80-
notNull("connection", connection);
8180
killCursor(connection);
8281
}
8382
}
@@ -228,8 +227,9 @@ private BsonDocument asGetMoreCommandDocument() {
228227
BsonDocument document = new BsonDocument("getMore", new BsonInt64(serverCursor.getId()))
229228
.append("collection", new BsonString(namespace.getCollectionName()));
230229

231-
if (batchSize != 0) {
232-
document.append("batchSize", new BsonInt32(Math.abs(batchSize)));
230+
int batchSizeForGetMoreCommand = Math.abs(getNumberToReturn(limit, this.batchSize, count));
231+
if (batchSizeForGetMoreCommand != 0) {
232+
document.append("batchSize", new BsonInt32(batchSizeForGetMoreCommand));
233233
}
234234

235235
return document;
@@ -248,7 +248,7 @@ private void initFromCommandResult(final BsonDocument getMoreCommandResultDocume
248248
}
249249

250250
private boolean limitReached() {
251-
return limit != 0 && count >= limit;
251+
return Math.abs(limit) != 0 && count >= Math.abs(limit);
252252
}
253253

254254
private void killCursor() {
@@ -264,6 +264,7 @@ private void killCursor() {
264264

265265
private void killCursor(final Connection connection) {
266266
if (serverCursor != null) {
267+
notNull("connection", connection);
267268
connection.killCursor(namespace, singletonList(serverCursor.getId()));
268269
serverCursor = null;
269270
}

driver-core/src/test/functional/com/mongodb/operation/AsyncQueryBatchCursorSpecification.groovy

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,25 @@ class AsyncQueryBatchCursorSpecification extends OperationFunctionalSpecificatio
109109
!nextBatch()
110110
}
111111

112+
def 'should exhaust multiple batches with limit'() {
113+
given:
114+
cursor = new AsyncQueryBatchCursor<Document>(executeQuery(limit, 2), limit, 2, new DocumentCodec(), connectionSource, connection)
115+
116+
when:
117+
def next = nextBatch()
118+
def total = 0
119+
while (next) {
120+
total +=next.size()
121+
next = nextBatch()
122+
}
123+
124+
then:
125+
total == Math.abs(limit)
126+
127+
where:
128+
limit << [5, -5]
129+
}
130+
112131
def 'should exhaust multiple batches'() {
113132
given:
114133
cursor = new AsyncQueryBatchCursor<Document>(executeQuery(3), 0, 2, new DocumentCodec(), connectionSource, connection)
@@ -311,11 +330,9 @@ class AsyncQueryBatchCursorSpecification extends OperationFunctionalSpecificatio
311330
if (serverIsAtLeastVersionThreeDotTwo(connection.getDescription())) {
312331
def findCommand = new BsonDocument('find', new BsonString(getCollectionName()))
313332
.append('filter', filter)
333+
.append('batchSize', new BsonInt32(batchSize))
314334
.append('tailable', BsonBoolean.valueOf(tailable))
315335
.append('awaitData', BsonBoolean.valueOf(awaitData))
316-
if (batchSize > 0) {
317-
findCommand.append('batchSize', new BsonInt32(batchSize))
318-
}
319336
if (limit > 0) {
320337
findCommand.append('limit', new BsonInt32(limit))
321338
}

driver-core/src/test/functional/com/mongodb/operation/QueryBatchCursorSpecification.groovy

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,17 +147,20 @@ class QueryBatchCursorSpecification extends OperationFunctionalSpecification {
147147

148148
def 'test limit exhaustion'() {
149149
given:
150-
def firstBatch = executeQuery(5, 2)
150+
def firstBatch = executeQuery(limit, 2)
151151
def connection = connectionSource.getConnection()
152152

153153
when:
154-
cursor = new QueryBatchCursor<Document>(firstBatch, 5, 2, new DocumentCodec(), connectionSource, connection)
154+
cursor = new QueryBatchCursor<Document>(firstBatch, limit, 2, new DocumentCodec(), connectionSource, connection)
155155

156156
then:
157-
cursor.iterator().sum { it.size } == 5
157+
cursor.iterator().sum { it.size } == Math.abs(limit)
158158

159159
cleanup:
160160
connection?.release()
161+
162+
where:
163+
limit << [5, -5]
161164
}
162165

163166
def 'test remove'() {
@@ -488,12 +491,10 @@ class QueryBatchCursorSpecification extends OperationFunctionalSpecification {
488491
if (serverIsAtLeastVersionThreeDotTwo(connection.getDescription())) {
489492
def findCommand = new BsonDocument('find', new BsonString(getCollectionName()))
490493
.append('filter', filter)
494+
.append('limit', new BsonInt32(Math.abs(limit)))
491495
.append('batchSize', new BsonInt32(batchSize))
492496
.append('tailable', BsonBoolean.valueOf(tailable))
493497
.append('awaitData', BsonBoolean.valueOf(awaitData))
494-
if (limit > 0) {
495-
findCommand.append('limit', new BsonInt32(limit))
496-
}
497498
def response = connection.command(getDatabaseName(), findCommand,
498499
slaveOk, new NoOpFieldNameValidator(),
499500
CommandResultDocumentCodec.create(new DocumentCodec(), 'firstBatch'))

driver-core/src/test/resources/command-monitoring/find.json

Lines changed: 1 addition & 1 deletion

0 commit comments

Comments
 (0)