0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

Use FieldRangeSet to pick chunks for queries. SERVER-954 SERVER-952 SERVER-947

This commit is contained in:
Mathias Stearn 2010-04-12 23:04:03 -04:00
parent 1ef66b2155
commit bc63a3f9c7
2 changed files with 43 additions and 7 deletions

View File

@ -86,6 +86,7 @@ for ( var i=0; i<types.length; i++ ){
assert.eq( 6 , c.find().sort( makeObjectDotted( 1 ) ).count() , curT.name + " total count with count()" );
assert.eq( curT.values , c.find().sort( makeObjectDotted( 1 ) ).toArray().map( getKey ) , curT.name + " sort 1" );
assert.eq( curT.values , c.find(makeObjectDotted({$in: curT.values})).sort( makeObjectDotted( 1 ) ).toArray().map( getKey ) , curT.name + " sort 1" );
assert.eq( curT.values.reverse() , c.find().sort( makeObjectDotted( -1 ) ).toArray().map( getKey ) , curT.name + " sort 2" );

View File

@ -21,6 +21,7 @@
#include "config.h"
#include "../util/unittest.h"
#include "../client/connpool.h"
#include "../db/queryutil.h"
#include "cursors.h"
#include "strategy.h"
@ -489,16 +490,50 @@ namespace mongo {
}
int ChunkManager::getChunksForQuery( vector<Chunk*>& chunks , const BSONObj& query ){
int added = 0;
FieldRangeSet ranges(_ns.c_str(), query, false);
BSONObjIterator fields(_key.key());
BSONElement field = fields.next();
FieldRange range = ranges.range(field.fieldName());
for ( vector<Chunk*>::iterator i=_chunks.begin(); i != _chunks.end(); i++ ){
Chunk * c = *i;
if ( _key.relevantForQuery( query , c ) ){
chunks.push_back( c );
added++;
uassert(13085, "no support for special queries yet", range.getSpecial().empty());
if (range.empty()) {
return 0;
} else if (range.equality()) {
chunks.push_back(&findChunk(BSON(field.fieldName() << range.min())));
return 1;
} else if (!range.nontrivial()) {
chunks = _chunks;
return chunks.size();
} else {
set<Chunk*, ChunkCmp> chunkSet;
for (vector<FieldInterval>::const_iterator it=range.intervals().begin(), end=range.intervals().end();
it != end;
++it)
{
const FieldInterval& fi = *it;
assert(fi.valid());
BSONObj minObj = BSON(field.fieldName() << fi.lower_.bound_);
BSONObj maxObj = BSON(field.fieldName() << fi.upper_.bound_);
ChunkMap::iterator min = (fi.lower_.inclusive_ ? _chunkMap.upper_bound(minObj) : _chunkMap.lower_bound(minObj));
ChunkMap::iterator max = (fi.upper_.inclusive_ ? _chunkMap.upper_bound(maxObj) : _chunkMap.lower_bound(maxObj));
assert(min != _chunkMap.end());
// make max non-inclusive like end iterators
if(max != _chunkMap.end())
++max;
for (ChunkMap::iterator it=min; it != max; ++it){
chunkSet.insert(it->second);
}
}
chunks.assign(chunkSet.begin(), chunkSet.end());
return chunks.size();
}
return added;
}
void ChunkManager::getAllServers( set<string>& allServers ){