|
17 | 17 | */ |
18 | 18 |
|
19 | 19 | #include "pch.h" |
| 20 | + |
| 21 | +#include "../client/connpool.h" |
| 22 | +#include "../db/instance.h" |
| 23 | + |
20 | 24 | #include "d_chunk_matcher.h" |
21 | 25 |
|
22 | 26 | namespace mongo { |
23 | 27 |
|
24 | | - ChunkMatcher::ChunkMatcher( ShardChunkVersion version , const BSONObj& key ) : _version( version ) { |
| 28 | + ChunkMatcher::ChunkMatcher( const string& configServer , const string& ns , const string& shardName ) { |
| 29 | + |
| 30 | + // have to get a connection to the config db |
| 31 | + // special case if i'm the configdb since i'm locked and if i connect to myself |
| 32 | + // its a deadlock |
| 33 | + auto_ptr<ScopedDbConnection> scoped; |
| 34 | + auto_ptr<DBDirectClient> direct; |
| 35 | + DBClientBase * conn; |
| 36 | + if ( configServer.empty() ){ |
| 37 | + direct.reset( new DBDirectClient() ); |
| 38 | + conn = direct.get(); |
| 39 | + } else { |
| 40 | + scoped.reset( new ScopedDbConnection( configServer ) ); |
| 41 | + conn = scoped->get(); |
| 42 | + } |
| 43 | + |
| 44 | + // get this collection's key |
| 45 | + BSONObj collection = conn->findOne( "config.collections", BSON( "_id" << ns ) ); |
| 46 | + assert( ! collection["key"].eoo() && collection["key"].isABSONObj() ); |
| 47 | + BSONObj key = collection["key"].Obj().getOwned(); |
25 | 48 | BSONObjBuilder b; |
26 | 49 | BSONForEach( e , key ) { |
27 | 50 | b.append( e.fieldName() , 1 ); |
28 | 51 | } |
29 | 52 | _key = b.obj(); |
30 | | - } |
31 | 53 |
|
32 | | - void ChunkMatcher::addChunk( const BSONObj& min , const BSONObj& max ) { |
33 | | - _chunksMap[min] == make_pair( min , max ); |
34 | | - } |
| 54 | + // actually query all the chunks for 'ns' that live in this shard, sorting so we can efficiently bucket them |
| 55 | + BSONObj q; |
| 56 | + { |
| 57 | + BSONObjBuilder b; |
| 58 | + b.append( "ns" , ns.c_str() ); |
| 59 | + b.append( "shard" , shardName ); |
| 60 | + q = b.obj(); |
| 61 | + } |
| 62 | + auto_ptr<DBClientCursor> cursor = conn->query( "config.chunks" , Query(q).sort( "min" ) ); |
| 63 | + |
| 64 | + assert( cursor.get() ); |
| 65 | + if ( ! cursor->more() ){ |
| 66 | + log() << "No chunks for collection " << ns << " on shard " << shardName << endl; |
| 67 | + if ( scoped.get() ) |
| 68 | + scoped->done(); |
| 69 | + |
| 70 | + return; |
| 71 | + } |
35 | 72 |
|
36 | | - void ChunkMatcher::addRange( const BSONObj& min , const BSONObj& max ){ |
37 | | - //TODO debug mode only? |
38 | | - assert(min.nFields() == _key.nFields()); |
39 | | - assert(max.nFields() == _key.nFields()); |
| 73 | + // load the tablet information, coallesceing the ranges |
| 74 | + // the version for this shard would be the highest version for any of the chunks |
| 75 | + ShardChunkVersion version; |
| 76 | + BSONObj min,max; |
| 77 | + while ( cursor->more() ){ |
| 78 | + BSONObj d = cursor->next(); |
40 | 79 |
|
41 | | - _rangesMap[min] = make_pair(min,max); |
| 80 | + _chunksMap[min] == make_pair( d["min"].Obj().getOwned() , d["max"].Obj().getOwned() ); |
| 81 | + |
| 82 | + ShardChunkVersion currVersion( d["lastmod"] ); |
| 83 | + if ( currVersion > version ) { |
| 84 | + version = currVersion; |
| 85 | + } |
| 86 | + |
| 87 | + // coallesce the chunk's bounds in ranges if they are adjacent chunks |
| 88 | + if ( min.isEmpty() ){ |
| 89 | + min = d["min"].Obj().getOwned(); |
| 90 | + max = d["max"].Obj().getOwned(); |
| 91 | + continue; |
| 92 | + } |
| 93 | + if ( max == d["min"].Obj() ){ |
| 94 | + max = d["max"].Obj().getOwned(); |
| 95 | + continue; |
| 96 | + } |
| 97 | + |
| 98 | + _rangesMap[min] = make_pair( min.getOwned() , max.getOwned() ); |
| 99 | + |
| 100 | + min = d["min"].Obj().getOwned(); |
| 101 | + max = d["max"].Obj().getOwned(); |
| 102 | + } |
| 103 | + assert( ! min.isEmpty() ); |
| 104 | + |
| 105 | + _rangesMap[min] = make_pair( min.getOwned() , max.getOwned() ); |
| 106 | + _version = version; |
| 107 | + |
| 108 | + if ( scoped.get() ) |
| 109 | + scoped->done(); |
42 | 110 | } |
43 | 111 |
|
44 | 112 | bool ChunkMatcher::belongsToMe( const BSONObj& obj ) const { |
45 | 113 | if ( _rangesMap.size() == 0 ) |
46 | 114 | return false; |
47 | | - |
| 115 | + |
48 | 116 | BSONObj x = obj.extractFields(_key); |
49 | 117 |
|
50 | 118 | RangeMap::const_iterator a = _rangesMap.upper_bound( x ); |
|
0 commit comments