Permalink
Browse files

SERVER-4680 sendNextBatch logic isn't correct with nonzero batch size

  • Loading branch information...
1 parent dc84eaf commit baa097c07b244a69a8d409059eca4ce42810266e Greg Studer committed Jan 18, 2012
Showing with 22 additions and 12 deletions.
  1. +13 −1 src/mongo/client/parallel.cpp
  2. +7 −9 src/mongo/s/cursors.cpp
  3. +2 −2 src/mongo/s/strategy_shard.cpp
@@ -766,7 +766,19 @@ namespace mongo {
// Does this need to be a ptr?
_qSpec.fields().isEmpty() ? 0 : &_qSpec._fields, // fieldsToReturn
_qSpec.options(), // options
- _qSpec.ntoreturn() == 0 ? 0 : _qSpec.ntoreturn() + _qSpec.ntoskip() ) ); // batchSize
+ // NtoReturn is weird.
+ // If zero, it means use default size, so we do that for all cursors
+ // If positive, it's the batch size (we don't want this cursor limiting results), that's
+ // done at a higher level
+ // If negative, it's the batch size, but we don't create a cursor - so we don't want
+ // to create a child cursor either.
+ // Either way, if non-zero, we want to pull back the batch size + the skip amount as
+ // quickly as possible. Potentially, for a cursor on a single shard or if we keep better track of
+ // chunks, we can actually add the skip value into the cursor and/or make some assumptions about the
+ // return value size ( (batch size + skip amount) / num_servers ).
+ _qSpec.ntoreturn() == 0 ? 0 :
+ ( _qSpec.ntoreturn() > 0 ? _qSpec.ntoreturn() + _qSpec.ntoskip() :
+ _qSpec.ntoreturn() - _qSpec.ntoskip() ) ) ); // batchSize
}
bool lazyInit = state->conn->get()->lazySupported();
View
@@ -82,7 +82,10 @@ namespace mongo {
BufBuilder b(32768);
int num = 0;
- bool sendMore = true;
+
+ // Send more if ntoreturn is 0, or any value > 1 (one is assumed to be a single doc return, with no cursor)
+ bool sendMore = ntoreturn == 0 || ntoreturn > 1;
+ ntoreturn = abs( ntoreturn );
while ( _cursor->more() ) {
BSONObj o = _cursor->next();
@@ -99,20 +102,15 @@ namespace mongo {
break;
}
- if ( ntoreturn != 0 && ( -1 * num + _totalSent ) == ntoreturn ) {
- // hard limit - total to send
- sendMore = false;
- break;
- }
-
- if ( ntoreturn == 0 && _totalSent == 0 && num > 100 ) {
+ if ( ntoreturn == 0 && _totalSent == 0 && num >= 100 ) {
// first batch should be max 100 unless batch size specified
break;
}
}
bool hasMore = sendMore && _cursor->more();
- LOG(6) << "\t hasMore:" << hasMore << " wouldSendMoreIfHad: " << sendMore << " id:" << getId() << " totalSent: " << _totalSent << endl;
+ LOG(5) << "\t hasMore: " << hasMore << " sendMore: " << sendMore << " cursorMore: " << _cursor->more() << " ntoreturn: " << ntoreturn
+ << " num: " << num << " wouldSendMoreIfHad: " << sendMore << " id:" << getId() << " totalSent: " << _totalSent << endl;
replyToQuery( 0 , r.p() , r.m() , b.buf() , b.len() , num , _totalSent , hasMore ? getId() : 0 );
_totalSent += num;
@@ -84,11 +84,11 @@ namespace mongo {
if( cursor->isSharded() ){
ShardedClientCursorPtr cc (new ShardedClientCursor( q , cursor ));
- if ( ! cc->sendNextBatch( r ) ) {
+ if ( ! cc->sendNextBatch( r, q.ntoreturn ) ) {
return;
}
- LOG(6) << "storing cursor : " << cc->getId() << endl;
+ LOG(5) << "storing cursor : " << cc->getId() << endl;
cursorCache.store( cc );
}
else{

0 comments on commit baa097c

Please sign in to comment.