| connpool.h | | connpool.h | |
| | | | |
| skipping to change at line 64 | | skipping to change at line 64 | |
| mongo::mutex poolMutex; | | mongo::mutex poolMutex; | |
| map<string,PoolForHost*> pools; // servername -> pool | | map<string,PoolForHost*> pools; // servername -> pool | |
| list<DBConnectionHook*> _hooks; | | list<DBConnectionHook*> _hooks; | |
| | | | |
| void onCreate( DBClientBase * conn ); | | void onCreate( DBClientBase * conn ); | |
| void onHandedOut( DBClientBase * conn ); | | void onHandedOut( DBClientBase * conn ); | |
| public: | | public: | |
| void flush(); | | void flush(); | |
| DBClientBase *get(const string& host); | | DBClientBase *get(const string& host); | |
| void release(const string& host, DBClientBase *c) { | | void release(const string& host, DBClientBase *c) { | |
|
| if ( c->isFailed() ) | | if ( c->isFailed() ){ | |
| | | delete c; | |
| return; | | return; | |
|
| | | } | |
| scoped_lock L(poolMutex); | | scoped_lock L(poolMutex); | |
| pools[host]->pool.push(c); | | pools[host]->pool.push(c); | |
| } | | } | |
| void addHook( DBConnectionHook * hook ); | | void addHook( DBConnectionHook * hook ); | |
| }; | | }; | |
| | | | |
| extern DBConnectionPool pool; | | extern DBConnectionPool pool; | |
| | | | |
| /** Use to get a connection from the pool. On exceptions things | | /** Use to get a connection from the pool. On exceptions things | |
| clean up nicely. | | clean up nicely. | |
| | | | |
End of changes. 2 change blocks. |
| 1 lines changed or deleted | | 3 lines changed or added | |
|
| dbclient.h | | dbclient.h | |
| | | | |
| skipping to change at line 920 | | skipping to change at line 920 | |
| DBClientConnection& slaveConn(); | | DBClientConnection& slaveConn(); | |
| | | | |
| /* TODO - not yet implemented. mongos may need these. */ | | /* TODO - not yet implemented. mongos may need these. */ | |
| virtual bool call( Message &toSend, Message &response, bool assertO
k=true ) { assert(false); return false; } | | virtual bool call( Message &toSend, Message &response, bool assertO
k=true ) { assert(false); return false; } | |
| virtual void say( Message &toSend ) { assert(false); } | | virtual void say( Message &toSend ) { assert(false); } | |
| virtual void sayPiggyBack( Message &toSend ) { assert(false); } | | virtual void sayPiggyBack( Message &toSend ) { assert(false); } | |
| virtual void checkResponse( const char *data, int nReturned ) { ass
ert(false); } | | virtual void checkResponse( const char *data, int nReturned ) { ass
ert(false); } | |
| | | | |
| bool isFailed() const { | | bool isFailed() const { | |
| // TODO: this really should check isFailed on current master as
well | | // TODO: this really should check isFailed on current master as
well | |
|
| return master > NotSetR; | | return master < Left; | |
| } | | } | |
| }; | | }; | |
| | | | |
| DBClientBase * createDirectClient(); | | DBClientBase * createDirectClient(); | |
| | | | |
| } // namespace mongo | | } // namespace mongo | |
| | | | |
End of changes. 1 change blocks. |
| 1 lines changed or deleted | | 1 lines changed or added | |
|
| repl.h | | repl.h | |
| | | | |
| skipping to change at line 430 | | skipping to change at line 430 | |
| enum FindingStartMode { Initial, FindExtent, InExtent }; | | enum FindingStartMode { Initial, FindExtent, InExtent }; | |
| const QueryPlan &_qp; | | const QueryPlan &_qp; | |
| bool _findingStart; | | bool _findingStart; | |
| FindingStartMode _findingStartMode; | | FindingStartMode _findingStartMode; | |
| auto_ptr< CoveredIndexMatcher > _matcher; | | auto_ptr< CoveredIndexMatcher > _matcher; | |
| Timer _findingStartTimer; | | Timer _findingStartTimer; | |
| ClientCursor * _findingStartCursor; | | ClientCursor * _findingStartCursor; | |
| auto_ptr< Cursor > _c; | | auto_ptr< Cursor > _c; | |
| DiskLoc startLoc( const DiskLoc &rec ) { | | DiskLoc startLoc( const DiskLoc &rec ) { | |
| Extent *e = rec.rec()->myExtent( rec ); | | Extent *e = rec.rec()->myExtent( rec ); | |
|
| if ( e->myLoc != _qp.nsd()->capExtent ) | | if ( !_qp.nsd()->capLooped() || ( e->myLoc != _qp.nsd()->capExt
ent ) ) | |
| return e->firstRecord; | | return e->firstRecord; | |
| // Likely we are on the fresh side of capExtent, so return firs
t fresh record. | | // Likely we are on the fresh side of capExtent, so return firs
t fresh record. | |
| // If we are on the stale side of capExtent, then the collectio
n is small and it | | // If we are on the stale side of capExtent, then the collectio
n is small and it | |
| // doesn't matter if we start the extent scan with capFirstNewR
ecord. | | // doesn't matter if we start the extent scan with capFirstNewR
ecord. | |
| return _qp.nsd()->capFirstNewRecord; | | return _qp.nsd()->capFirstNewRecord; | |
| } | | } | |
| | | | |
|
| | | // should never have an empty extent in the oplog, so don't worry a
bout that case | |
| DiskLoc prevLoc( const DiskLoc &rec ) { | | DiskLoc prevLoc( const DiskLoc &rec ) { | |
| Extent *e = rec.rec()->myExtent( rec ); | | Extent *e = rec.rec()->myExtent( rec ); | |
|
| if ( e->xprev.isNull() ) | | if ( _qp.nsd()->capLooped() ) { | |
| e = _qp.nsd()->lastExtent.ext(); | | if ( e->xprev.isNull() ) | |
| else | | e = _qp.nsd()->lastExtent.ext(); | |
| e = e->xprev.ext(); | | else | |
| if ( e->myLoc != _qp.nsd()->capExtent ) | | e = e->xprev.ext(); | |
| return e->firstRecord; | | if ( e->myLoc != _qp.nsd()->capExtent ) | |
| | | return e->firstRecord; | |
| | | } else { | |
| | | if ( !e->xprev.isNull() ) { | |
| | | e = e->xprev.ext(); | |
| | | return e->firstRecord; | |
| | | } | |
| | | } | |
| return DiskLoc(); // reached beginning of collection | | return DiskLoc(); // reached beginning of collection | |
| } | | } | |
| void createClientCursor( const DiskLoc &startLoc = DiskLoc() ) { | | void createClientCursor( const DiskLoc &startLoc = DiskLoc() ) { | |
| auto_ptr<Cursor> c = _qp.newCursor( startLoc ); | | auto_ptr<Cursor> c = _qp.newCursor( startLoc ); | |
| _findingStartCursor = new ClientCursor(c, _qp.ns(), false); | | _findingStartCursor = new ClientCursor(c, _qp.ns(), false); | |
| } | | } | |
| void destroyClientCursor() { | | void destroyClientCursor() { | |
| if ( _findingStartCursor ) { | | if ( _findingStartCursor ) { | |
| ClientCursor::erase( _findingStartCursor->cursorid ); | | ClientCursor::erase( _findingStartCursor->cursorid ); | |
| _findingStartCursor = 0; | | _findingStartCursor = 0; | |
| | | | |
End of changes. 3 change blocks. |
| 7 lines changed or deleted | | 15 lines changed or added | |
|
| update.h | | update.h | |
| | | | |
| skipping to change at line 103 | | skipping to change at line 103 | |
| switch (op){ | | switch (op){ | |
| case PUSH: | | case PUSH: | |
| case PUSH_ALL: | | case PUSH_ALL: | |
| case POP: | | case POP: | |
| return true; | | return true; | |
| default: | | default: | |
| return false; | | return false; | |
| } | | } | |
| } | | } | |
| | | | |
|
| bool isIndexed( const set<string>& idxKeys ) const { | | static bool isIndexed( const string& fullName , const set<string>& | |
| | | idxKeys ){ | |
| | | const char * fieldName = fullName.c_str(); | |
| // check if there is an index key that is a parent of mod | | // check if there is an index key that is a parent of mod | |
| for( const char *dot = strchr( fieldName, '.' ); dot; dot = str
chr( dot + 1, '.' ) ) | | for( const char *dot = strchr( fieldName, '.' ); dot; dot = str
chr( dot + 1, '.' ) ) | |
| if ( idxKeys.count( string( fieldName, dot - fieldName ) )
) | | if ( idxKeys.count( string( fieldName, dot - fieldName ) )
) | |
| return true; | | return true; | |
|
| string fullName = fieldName; | | | |
| // check if there is an index key equal to mod | | // check if there is an index key equal to mod | |
| if ( idxKeys.count(fullName) ) | | if ( idxKeys.count(fullName) ) | |
| return true; | | return true; | |
| // check if there is an index key that is a child of mod | | // check if there is an index key that is a child of mod | |
| set< string >::const_iterator j = idxKeys.upper_bound( fullName
); | | set< string >::const_iterator j = idxKeys.upper_bound( fullName
); | |
| if ( j != idxKeys.end() && j->find( fullName ) == 0 && (*j)[ful
lName.size()] == '.' ) | | if ( j != idxKeys.end() && j->find( fullName ) == 0 && (*j)[ful
lName.size()] == '.' ) | |
| return true; | | return true; | |
|
| | | | |
| | | return false; | |
| | | } | |
| | | | |
| | | bool isIndexed( const set<string>& idxKeys ) const { | |
| | | string fullName = fieldName; | |
| | | | |
| | | if ( isIndexed( fullName , idxKeys ) ) | |
| | | return true; | |
| | | | |
| | | if ( strstr( fieldName , "." ) ){ | |
| | | // check for a.0.1 | |
| | | StringBuilder buf( fullName.size() + 1 ); | |
| | | for ( size_t i=0; i<fullName.size(); i++ ){ | |
| | | char c = fullName[i]; | |
| | | buf << c; | |
| | | | |
| | | if ( c != '.' ) | |
| | | continue; | |
| | | | |
| | | if ( ! isdigit( fullName[i+1] ) ) | |
| | | continue; | |
| | | | |
| | | bool possible = true; | |
| | | size_t j=i+2; | |
| | | for ( ; j<fullName.size(); j++ ){ | |
| | | char d = fullName[j]; | |
| | | if ( d == '.' ) | |
| | | break; | |
| | | if ( isdigit( d ) ) | |
| | | continue; | |
| | | possible = false; | |
| | | break; | |
| | | } | |
| | | | |
| | | if ( possible ) | |
| | | i = j; | |
| | | } | |
| | | string x = buf.str(); | |
| | | if ( isIndexed( x , idxKeys ) ) | |
| | | return true; | |
| | | } | |
| | | | |
| return false; | | return false; | |
| } | | } | |
| | | | |
| template< class Builder > | | template< class Builder > | |
| void apply( Builder& b , BSONElement in , ModState& ms ) const; | | void apply( Builder& b , BSONElement in , ModState& ms ) const; | |
| | | | |
| /** | | /** | |
| * @return true iff toMatch should be removed from the array | | * @return true iff toMatch should be removed from the array | |
| */ | | */ | |
| bool _pullElementMatch( BSONElement& toMatch ) const; | | bool _pullElementMatch( BSONElement& toMatch ) const; | |
| | | | |
End of changes. 3 change blocks. |
| 2 lines changed or deleted | | 47 lines changed or added | |
|