accumulator.h   accumulator.h 
skipping to change at line 35 skipping to change at line 35
namespace mongo { namespace mongo {
class ExpressionContext; class ExpressionContext;
class Accumulator : class Accumulator :
public ExpressionNary { public ExpressionNary {
public: public:
// virtuals from ExpressionNary // virtuals from ExpressionNary
virtual void addOperand(const intrusive_ptr<Expression> &pExpressio n); virtual void addOperand(const intrusive_ptr<Expression> &pExpressio n);
virtual void addToBsonObj( virtual void addToBsonObj(
BSONObjBuilder *pBuilder, string fieldName, BSONObjBuilder *pBuilder, const std::string& fieldName,
bool requireExpression) const; bool requireExpression) const;
virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const; virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const;
/* /*
Get the accumulated value. Get the accumulated value.
@returns the accumulated value @returns the accumulated value
*/ */
virtual intrusive_ptr<const Value> getValue() const = 0; virtual intrusive_ptr<const Value> getValue() const = 0;
skipping to change at line 59 skipping to change at line 59
/* /*
Convenience method for doing this for accumulators. The pattern Convenience method for doing this for accumulators. The pattern
is always the same, so a common implementation works, but require s is always the same, so a common implementation works, but require s
knowing the operator name. knowing the operator name.
@param pBuilder the builder to add to @param pBuilder the builder to add to
@param fieldName the projected name @param fieldName the projected name
@param opName the operator name @param opName the operator name
*/ */
void opToBson( void opToBson(
BSONObjBuilder *pBuilder, string fieldName, string opName, BSONObjBuilder *pBuilder, const std::string& fieldName, const s td::string& opName,
bool requireExpression) const; bool requireExpression) const;
}; };
class AccumulatorAddToSet : class AccumulatorAddToSet :
public Accumulator { public Accumulator {
public: public:
// virtuals from Expression // virtuals from Expression
virtual intrusive_ptr<const Value> evaluate( virtual intrusive_ptr<const Value> evaluate(
const intrusive_ptr<Document> &pDocument) const; const intrusive_ptr<Document> &pDocument) const;
virtual intrusive_ptr<const Value> getValue() const; virtual intrusive_ptr<const Value> getValue() const;
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 admin_access.h   admin_access.h 
skipping to change at line 26 skipping to change at line 26
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
namespace mongo { namespace mongo {
/* /*
* An AdminAccess is an interface class used to determine if certain us ers have * An AdminAccess is an interface class used to determine if certain us ers have
* priviledges to a given resource. * privileges to a given resource.
* *
*/ */
class AdminAccess { class AdminAccess {
public: public:
virtual ~AdminAccess() { } virtual ~AdminAccess() { }
/** @return if there are any priviledge users. This should not /** @return if there are any priviledge users. This should not
* block for long and throw if can't get a lock if needed. * block for long and throw if can't get a lock if needed.
*/ */
virtual bool haveAdminUsers() const = 0; virtual bool haveAdminUsers() const = 0;
/** @return priviledged user with this name. This should not block /** @return privileged user with this name. This should not block
* for long and throw if can't get a lock if needed * for long and throw if can't get a lock if needed
*/ */
virtual BSONObj getAdminUser( const string& username ) const = 0; virtual BSONObj getAdminUser( const string& username ) const = 0;
}; };
class NoAdminAccess : public AdminAccess { class NoAdminAccess : public AdminAccess {
public: public:
virtual ~NoAdminAccess() { } virtual ~NoAdminAccess() { }
virtual bool haveAdminUsers() const { return false; } virtual bool haveAdminUsers() const { return false; }
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 alignedbuilder.h   alignedbuilder.h 
skipping to change at line 21 skipping to change at line 21
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include "../bson/stringdata.h" #include "mongo/base/string_data.h"
namespace mongo { namespace mongo {
/** a page-aligned BufBuilder. */ /** a page-aligned BufBuilder. */
class AlignedBuilder { class AlignedBuilder {
public: public:
AlignedBuilder(unsigned init_size); AlignedBuilder(unsigned init_size);
~AlignedBuilder() { kill(); } ~AlignedBuilder() { kill(); }
/** reset with a hint as to the upcoming needed size specified */ /** reset with a hint as to the upcoming needed size specified */
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 assert_util.h   assert_util.h 
skipping to change at line 98 skipping to change at line 98
/** Most mongo exceptions inherit from this; this is commonly caught in most threads */ /** Most mongo exceptions inherit from this; this is commonly caught in most threads */
class DBException : public std::exception { class DBException : public std::exception {
public: public:
DBException( const ExceptionInfo& ei ) : _ei(ei) { traceIfNeeded(*t his); } DBException( const ExceptionInfo& ei ) : _ei(ei) { traceIfNeeded(*t his); }
DBException( const char * msg , int code ) : _ei(msg,code) { traceI fNeeded(*this); } DBException( const char * msg , int code ) : _ei(msg,code) { traceI fNeeded(*this); }
DBException( const std::string& msg , int code ) : _ei(msg,code) { traceIfNeeded(*this); } DBException( const std::string& msg , int code ) : _ei(msg,code) { traceIfNeeded(*this); }
virtual ~DBException() throw() { } virtual ~DBException() throw() { }
virtual const char* what() const throw() { return _ei.msg.c_str(); } virtual const char* what() const throw() { return _ei.msg.c_str(); }
virtual int getCode() const { return _ei.code; } virtual int getCode() const { return _ei.code; }
virtual void appendPrefix( std::stringstream& ss ) const { } virtual void appendPrefix( std::stringstream& ss ) const { }
virtual void addContext( const std::string& str ) { virtual void addContext( const std::string& str ) {
_ei.msg = str + causedBy( _ei.msg ); _ei.msg = str + causedBy( _ei.msg );
} }
// context when applicable. otherwise ""
std::string _shard;
virtual std::string toString() const; virtual std::string toString() const;
const ExceptionInfo& getInfo() const { return _ei; } const ExceptionInfo& getInfo() const { return _ei; }
private: private:
static void traceIfNeeded( const DBException& e ); static void traceIfNeeded( const DBException& e );
public: public:
static bool traceExceptions; static bool traceExceptions;
protected: protected:
ExceptionInfo _ei; ExceptionInfo _ei;
skipping to change at line 220 skipping to change at line 222
#endif #endif
// some special ids that we want to duplicate // some special ids that we want to duplicate
// > 10000 asserts // > 10000 asserts
// < 10000 UserException // < 10000 UserException
enum { ASSERT_ID_DUPKEY = 11000 }; enum { ASSERT_ID_DUPKEY = 11000 };
/* throws a uassertion with an appropriate msg */ /* throws a uassertion with an appropriate msg */
MONGO_COMPILER_NORETURN void streamNotGood( int code , std::string msg , std::ios& myios ); MONGO_COMPILER_NORETURN void streamNotGood( int code, const std::string & msg, std::ios& myios );
inline void assertStreamGood(unsigned msgid, std::string msg, std::ios& myios) { inline void assertStreamGood(unsigned msgid, const std::string& msg, st d::ios& myios) {
if( !myios.good() ) streamNotGood(msgid, msg, myios); if( !myios.good() ) streamNotGood(msgid, msg, myios);
} }
std::string demangleName( const std::type_info& typeinfo ); std::string demangleName( const std::type_info& typeinfo );
} // namespace mongo } // namespace mongo
#define MONGO_ASSERT_ON_EXCEPTION( expression ) \ #define MONGO_ASSERT_ON_EXCEPTION( expression ) \
try { \ try { \
expression; \ expression; \
 End of changes. 4 change blocks. 
3 lines changed or deleted 5 lines changed or added


 atomic_intrinsics_win32.h   atomic_intrinsics_win32.h 
skipping to change at line 24 skipping to change at line 24
*/ */
/** /**
* Implementation of the AtomicIntrinsics<T>::* operations for Windows syst ems. * Implementation of the AtomicIntrinsics<T>::* operations for Windows syst ems.
*/ */
#pragma once #pragma once
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include "mongo/platform/windows_basic.h"
namespace mongo { namespace mongo {
/** /**
* Default instantiation of AtomicIntrinsics<>, for unsupported types. * Default instantiation of AtomicIntrinsics<>, for unsupported types.
*/ */
template <typename T, typename _IsTSupported=void> template <typename T, typename _IsTSupported=void>
class AtomicIntrinsics { class AtomicIntrinsics {
private: private:
AtomicIntrinsics(); AtomicIntrinsics();
~AtomicIntrinsics(); ~AtomicIntrinsics();
 End of changes. 1 change blocks. 
0 lines changed or deleted 2 lines changed or added


 authentication_table.h   authentication_table.h 
skipping to change at line 49 skipping to change at line 49
const Auth::Level& level ); const Auth::Level& level );
void addAuth( const std::string& dbname , const Auth& auth ); void addAuth( const std::string& dbname , const Auth& auth );
void removeAuth( const std::string& dbname ); void removeAuth( const std::string& dbname );
void clearAuth(); void clearAuth();
Auth getAuthForDb( const std::string& dbname ) const; Auth getAuthForDb( const std::string& dbname ) const;
// Takes the authentication state from the given BSONObj, replcacin g whatever state it had. // Takes the authentication state from the given BSONObj, replacing whatever state it had.
void setFromBSON( const BSONObj& obj ); void setFromBSON( const BSONObj& obj );
BSONObj toBSON() const; BSONObj toBSON() const;
BSONObj copyCommandObjAddingAuth( const BSONObj& cmdObj ) const; BSONObj copyCommandObjAddingAuth( const BSONObj& cmdObj ) const;
static const AuthenticationTable& getInternalSecurityAuthentication Table(); static const AuthenticationTable& getInternalSecurityAuthentication Table();
// Only used once at startup to setup the authentication table. // Only used once at startup to setup the authentication table.
static AuthenticationTable& getMutableInternalSecurityAuthenticatio nTable(); static AuthenticationTable& getMutableInternalSecurityAuthenticatio nTable();
static const string fieldName; static const string fieldName;
private: private:
bool _shouldSendInternalSecurityTable() const;
typedef map<std::string,Auth> DBAuthMap; typedef map<std::string,Auth> DBAuthMap;
DBAuthMap _dbs; // dbname -> auth DBAuthMap _dbs; // dbname -> auth
}; };
} }
 End of changes. 2 change blocks. 
4 lines changed or deleted 1 lines changed or added


 balancer_policy.h   balancer_policy.h 
skipping to change at line 65 skipping to change at line 65
ShardInfo( long long maxSize, long long currSize, ShardInfo( long long maxSize, long long currSize,
bool draining, bool opsQueued, bool draining, bool opsQueued,
const set<string>& tags = set<string>() ); const set<string>& tags = set<string>() );
void addTag( const string& tag ); void addTag( const string& tag );
/** @return true if we have the tag OR if the tag is "" */ /** @return true if we have the tag OR if the tag is "" */
bool hasTag( const string& tag ) const; bool hasTag( const string& tag ) const;
/** /**
* @return true if a shard cannot receive any new chunks bacause it reache 'shardLimits'. * @return true if a shard cannot receive any new chunks because it reaches 'shardLimits'.
* Expects the optional fields "maxSize", can in size in MB, and "u sedSize", currently used size * Expects the optional fields "maxSize", can in size in MB, and "u sedSize", currently used size
* in MB, on 'shardLimits'. * in MB, on 'shardLimits'.
*/ */
bool isSizeMaxed() const; bool isSizeMaxed() const;
/** /**
* @return true if 'shardLimist' contains a field "draining". Expec ts the optional field * @return true if 'shardLimist' contains a field "draining". Expec ts the optional field
* "isDraining" on 'shrdLimits'. * "isDraining" on 'shrdLimits'.
*/ */
bool isDraining() const { return _draining; } bool isDraining() const { return _draining; }
/** /**
* @return true if a shard currently has operations in any of its w riteback queues * @return true if a shard currently has operations in any of its w riteback queues
*/ */
bool hasOpsQueued() const { return _hasOpsQueued; } bool hasOpsQueued() const { return _hasOpsQueued; }
long long getMaxSize() const { return _maxSize; }
long long getCurrSize() const { return _currSize; }
string toString() const; string toString() const;
private: private:
long long _maxSize; long long _maxSize;
long long _currSize; long long _currSize;
bool _draining; bool _draining;
bool _hasOpsQueued; bool _hasOpsQueued;
set<string> _tags; set<string> _tags;
}; };
 End of changes. 2 change blocks. 
5 lines changed or deleted 1 lines changed or added


 basic.h   basic.h 
// basic.h // basic.h
/*
* Copyright 2010 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once #pragma once
#ifdef _WIN32 #ifdef _WIN32
#include "windows_basic.h" #include "windows_basic.h"
#endif #endif
#if defined(__linux__) #if defined(__linux__)
#include <cstring> #include <cstring>
 End of changes. 1 change blocks. 
0 lines changed or deleted 17 lines changed or added


 bits.h   bits.h 
skipping to change at line 29 skipping to change at line 29
// figure out if we're on a 64 or 32 bit system // figure out if we're on a 64 or 32 bit system
#if defined(__x86_64__) || defined(__amd64__) || defined(_WIN64) #if defined(__x86_64__) || defined(__amd64__) || defined(_WIN64)
#define MONGO_PLATFORM_64 #define MONGO_PLATFORM_64
#elif defined(__i386__) || defined(_WIN32) #elif defined(__i386__) || defined(_WIN32)
#define MONGO_PLATFORM_32 #define MONGO_PLATFORM_32
#else #else
#error "unknown platform" #error "unknown platform"
#endif #endif
namespace mongo {
// defined here so can test on linux
inline int mongo_firstBitSet( unsigned long long v ) {
if ( v == 0 )
return 0;
for ( int i = 0; i<8; i++ ) {
unsigned long long x = ( v >> ( 8 * i ) ) & 0xFF;
if ( x == 0 )
continue;
for ( int j = 0; j < 8; j++ ) {
if ( ( x >> j ) & 0x1 )
return ( i * 8 ) + j + 1;
}
}
return 0;
}
}
#if defined(__linux__)
#define firstBitSet ffsll
#define MONGO_SYSTEM_FFS 1
#elif defined(__MACH__) && defined(MONGO_PLATFORM_64)
#define firstBitSet ffsl
#define MONGO_SYSTEM_FFS 1
#else
#define firstBitSet mongo::mongo_firstBitSet
#endif
 End of changes. 1 change blocks. 
0 lines changed or deleted 0 lines changed or added


 bson-inl.h   bson-inl.h 
skipping to change at line 210 skipping to change at line 210
r = j.next(); r = j.next();
if ( l.eoo() ) if ( l.eoo() )
return r.eoo(); return r.eoo();
} while( l == r ); } while( l == r );
return false; return false;
} }
inline NOINLINE_DECL void BSONObj::_assertInvalid() const { inline NOINLINE_DECL void BSONObj::_assertInvalid() const {
StringBuilder ss; StringBuilder ss;
int os = objsize(); int os = objsize();
ss << "Invalid BSONObj size: " << os << " (0x" << toHex( &os, 4 ) < ss << "BSONObj size: " << os << " (0x" << toHex( &os, 4 ) << ") is
< ')'; invalid. "
<< "Size must be between 0 and " << BSONObjMaxInternalSize
<< "(" << ( BSONObjMaxInternalSize/(1024*1024) ) << "MB)";
try { try {
BSONElement e = firstElement(); BSONElement e = firstElement();
ss << " first element: " << e.toString(); ss << " First element: " << e.toString();
} }
catch ( ... ) { } catch ( ... ) { }
massert( 10334 , ss.str() , 0 ); massert( 10334 , ss.str() , 0 );
} }
/* the idea with NOINLINE_DECL here is to keep this from inlining in th e /* the idea with NOINLINE_DECL here is to keep this from inlining in th e
getOwned() method. the presumption being that is better. getOwned() method. the presumption being that is better.
*/ */
inline NOINLINE_DECL BSONObj BSONObj::copy() const { inline NOINLINE_DECL BSONObj BSONObj::copy() const {
Holder *h = (Holder*) malloc(objsize() + sizeof(unsigned)); Holder *h = (Holder*) malloc(objsize() + sizeof(unsigned));
skipping to change at line 916 skipping to change at line 918
inline void BSONElement::Val(BSONObj& v) const { v = Obj(); } inline void BSONElement::Val(BSONObj& v) const { v = Obj(); }
template<typename T> template<typename T>
inline BSONFieldValue<BSONObj> BSONField<T>::query( const char * q , co nst T& t ) const { inline BSONFieldValue<BSONObj> BSONField<T>::query( const char * q , co nst T& t ) const {
BSONObjBuilder b; BSONObjBuilder b;
b.append( q , t ); b.append( q , t );
return BSONFieldValue<BSONObj>( _name , b.obj() ); return BSONFieldValue<BSONObj>( _name , b.obj() );
} }
// used by jsonString() // used by jsonString()
inline std::string escape( std::string s , bool escape_slash=false) { inline std::string escape( const std::string& s , bool escape_slash=fal se) {
StringBuilder ret; StringBuilder ret;
for ( std::string::iterator i = s.begin(); i != s.end(); ++i ) { for ( std::string::const_iterator i = s.begin(); i != s.end(); ++i ) {
switch ( *i ) { switch ( *i ) {
case '"': case '"':
ret << "\\\""; ret << "\\\"";
break; break;
case '\\': case '\\':
ret << "\\\\"; ret << "\\\\";
break; break;
case '/': case '/':
ret << (escape_slash ? "\\/" : "/"); ret << (escape_slash ? "\\/" : "/");
break; break;
 End of changes. 4 change blocks. 
5 lines changed or deleted 7 lines changed or added


 bson.h   bson.h 
skipping to change at line 87 skipping to change at line 87
if(!expr) { if(!expr) {
throw bson::assertion( 0 , "assertion failure in bson library" ); throw bson::assertion( 0 , "assertion failure in bson library" );
} }
} }
#endif #endif
#if !defined(uassert) #if !defined(uassert)
MONGO_COMPILER_NORETURN inline void uasserted(int msgid, const std::str ing &s) { MONGO_COMPILER_NORETURN inline void uasserted(int msgid, const std::str ing &s) {
throw bson::assertion( msgid , s ); throw bson::assertion( msgid , s );
} }
inline void uassert(unsigned msgid, std::string msg, bool expr) { inline void uassert(unsigned msgid, const std::string& msg, bool expr) {
if( !expr ) if( !expr )
uasserted( msgid , msg ); uasserted( msgid , msg );
} }
MONGO_COMPILER_NORETURN inline void msgasserted(int msgid, const char * msg) { MONGO_COMPILER_NORETURN inline void msgasserted(int msgid, const char * msg) {
throw bson::assertion( msgid , msg ); throw bson::assertion( msgid , msg );
} }
MONGO_COMPILER_NORETURN inline void msgasserted(int msgid, const std::s tring &msg) { MONGO_COMPILER_NORETURN inline void msgasserted(int msgid, const std::s tring &msg) {
msgasserted(msgid, msg.c_str()); msgasserted(msgid, msg.c_str());
} }
inline void massert(int msgid, std::string msg, bool expr) { inline void massert(int msgid, const std::string& msg, bool expr) {
if(!expr) { if(!expr) {
std::cout << "assertion failure in bson library: " << msgid << ' ' << msg << std::endl; std::cout << "assertion failure in bson library: " << msgid << ' ' << msg << std::endl;
throw bson::assertion( msgid , msg ); throw bson::assertion( msgid , msg );
} }
} }
#endif #endif
} }
#include "mongo/bson/bsonelement.h" #include "mongo/bson/bsonelement.h"
#include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobj.h"
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 bson_builder_base.h   bson_builder_base.h 
skipping to change at line 18 skipping to change at line 18
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#pragma once #pragma once
#include "mongo/bson/stringdata.h" #include "mongo/base/string_data.h"
#include "mongo/bson/util/builder.h" #include "mongo/bson/util/builder.h"
namespace mongo { namespace mongo {
/* /*
* BSONBuilderBase contains the common interface between different type s of BSON builders. * BSONBuilderBase contains the common interface between different type s of BSON builders.
* *
* Currently, this interface is not comprehensive. But we should work t oward that goal. If * Currently, this interface is not comprehensive. But we should work t oward that goal. If
* you are maintaining the class, please make sure that all Builders be have coherently. * you are maintaining the class, please make sure that all Builders be have coherently.
*/ */
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 bson_db.h   bson_db.h 
/** @file bson_db.h /** @file bson_db.h */
This file contains the implementation of BSON-related methods that are
required
by the MongoDB database server.
Normally, for standalone BSON usage, you do not want this file - it wil
l tend to
pull in some other files from the MongoDB project. Thus, bson.h (the ma
in file
one would use) does not include this file.
*/
/* Copyright 2009 10gen Inc. /* Copyright 2009 10gen Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/*
This file contains the implementation of BSON-related methods that are
required
by the MongoDB database server.
Normally, for standalone BSON usage, you do not want this file - it wil
l tend to
pull in some other files from the MongoDB project. Thus, bson.h (the ma
in file
one would use) does not include this file.
*/
#pragma once #pragma once
#include "../util/optime.h" #include "../util/optime.h"
#include "../util/time_support.h" #include "../util/time_support.h"
namespace mongo { namespace mongo {
/** /**
Timestamps are a special BSON datatype that is used internally for repl ication. Timestamps are a special BSON datatype that is used internally for repl ication.
Append a timestamp element to the object being ebuilt. Append a timestamp element to the object being ebuilt.
 End of changes. 2 change blocks. 
12 lines changed or deleted 13 lines changed or added


 bsonelement.h   bsonelement.h 
skipping to change at line 20 skipping to change at line 20
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#pragma once #pragma once
#include <boost/cstdint.hpp>
#include <string.h> // strlen #include <string.h> // strlen
#include <string> #include <string>
#include <vector> #include <vector>
#include "mongo/bson/bsontypes.h" #include "mongo/bson/bsontypes.h"
#include "mongo/bson/oid.h" #include "mongo/bson/oid.h"
#include "mongo/platform/float_utils.h" #include "mongo/platform/float_utils.h"
namespace mongo { namespace mongo {
class OpTime; class OpTime;
skipping to change at line 242 skipping to change at line 241
/** Size (length) of a string element. /** Size (length) of a string element.
You must assure of type String first. You must assure of type String first.
@return string size including terminating null @return string size including terminating null
*/ */
int valuestrsize() const { int valuestrsize() const {
return *reinterpret_cast< const int* >( value() ); return *reinterpret_cast< const int* >( value() );
} }
// for objects the size *includes* the size of the size field // for objects the size *includes* the size of the size field
size_t objsize() const { int objsize() const {
return static_cast< const size_t >( *reinterpret_cast< const ui return *reinterpret_cast< const int* >( value() );
nt32_t* >( value() ) );
} }
/** Get a string's value. Also gives you start of the real data fo r an embedded object. /** Get a string's value. Also gives you start of the real data fo r an embedded object.
You must assure data is of an appropriate type first -- see als o valuestrsafe(). You must assure data is of an appropriate type first -- see als o valuestrsafe().
*/ */
const char * valuestr() const { const char * valuestr() const {
return value() + 4; return value() + 4;
} }
/** Get the string value of the element. If not a string returns " ". */ /** Get the string value of the element. If not a string returns " ". */
 End of changes. 2 change blocks. 
4 lines changed or deleted 2 lines changed or added


 bsonobj.h   bsonobj.h 
skipping to change at line 28 skipping to change at line 28
#pragma once #pragma once
#include <boost/intrusive_ptr.hpp> #include <boost/intrusive_ptr.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <set> #include <set>
#include <list> #include <list>
#include <string> #include <string>
#include <vector> #include <vector>
#include "mongo/bson/bsonelement.h" #include "mongo/bson/bsonelement.h"
#include "mongo/bson/stringdata.h" #include "mongo/base/string_data.h"
#include "mongo/bson/util/atomic_int.h" #include "mongo/bson/util/atomic_int.h"
#include "mongo/bson/util/builder.h" #include "mongo/bson/util/builder.h"
namespace mongo { namespace mongo {
typedef std::set< BSONElement, BSONElementCmpWithoutField > BSONElement Set; typedef std::set< BSONElement, BSONElementCmpWithoutField > BSONElement Set;
typedef std::multiset< BSONElement, BSONElementCmpWithoutField > BSONEl ementMSet; typedef std::multiset< BSONElement, BSONElementCmpWithoutField > BSONEl ementMSet;
/** /**
C++ representation of a "BSON" object -- that is, an extended JSON-s tyle C++ representation of a "BSON" object -- that is, an extended JSON-s tyle
skipping to change at line 334 skipping to change at line 334
bool equal(const BSONObj& r) const; bool equal(const BSONObj& r) const;
/** /**
* @param otherObj * @param otherObj
* @return true if 'this' is a prefix of otherObj- in other words i f * @return true if 'this' is a prefix of otherObj- in other words i f
* otherObj contains the same field names and field vals in the sam e * otherObj contains the same field names and field vals in the sam e
* order as 'this', plus optionally some additional elements. * order as 'this', plus optionally some additional elements.
*/ */
bool isPrefixOf( const BSONObj& otherObj ) const; bool isPrefixOf( const BSONObj& otherObj ) const;
/**
* @param otherObj
* @return returns true if the list of field names in 'this' is a p
refix
* of the list of field names in otherObj. Similar to 'isPrefixOf'
,
* but ignores the field values and only looks at field names.
*/
bool isFieldNamePrefixOf( const BSONObj& otherObj ) const;
/** This is "shallow equality" -- ints and doubles won't match. fo r a /** This is "shallow equality" -- ints and doubles won't match. fo r a
deep equality test use woCompare (which is slower). deep equality test use woCompare (which is slower).
*/ */
bool binaryEqual(const BSONObj& r) const { bool binaryEqual(const BSONObj& r) const {
int os = objsize(); int os = objsize();
if ( os == r.objsize() ) { if ( os == r.objsize() ) {
return (os == 0 || memcmp(objdata(),r.objdata(),os)==0); return (os == 0 || memcmp(objdata(),r.objdata(),os)==0);
} }
return false; return false;
} }
 End of changes. 2 change blocks. 
1 lines changed or deleted 11 lines changed or added


 bsonobjbuilder.h   bsonobjbuilder.h 
skipping to change at line 33 skipping to change at line 33
#pragma once #pragma once
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <cmath> #include <cmath>
#include <limits> #include <limits>
#include "mongo/bson/bsonelement.h" #include "mongo/bson/bsonelement.h"
#include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobj.h"
#include "mongo/bson/bsonmisc.h" #include "mongo/bson/bsonmisc.h"
#include "mongo/bson/bson_builder_base.h" #include "mongo/bson/bson_builder_base.h"
#include "mongo/bson/bson_field.h"
#if defined(_DEBUG) && defined(MONGO_EXPOSE_MACROS) #if defined(_DEBUG) && defined(MONGO_EXPOSE_MACROS)
#include "mongo/util/log.h" #include "mongo/util/log.h"
#endif #endif
namespace mongo { namespace mongo {
#if defined(_WIN32) #if defined(_WIN32)
// warning: 'this' : used in base member initializer list // warning: 'this' : used in base member initializer list
#pragma warning( disable : 4355 ) #pragma warning( disable : 4355 )
#endif #endif
template<typename T>
class BSONFieldValue {
public:
BSONFieldValue( const std::string& name , const T& t ) {
_name = name;
_t = t;
}
const T& value() const { return _t; }
const std::string& name() const { return _name; }
private:
std::string _name;
T _t;
};
template<typename T>
class BSONField {
public:
BSONField( const std::string& name , const std::string& longName=""
)
: _name(name), _longName(longName) {}
const std::string& name() const { return _name; }
operator std::string() const { return _name; }
BSONFieldValue<T> make( const T& t ) const {
return BSONFieldValue<T>( _name , t );
}
BSONFieldValue<BSONObj> gt( const T& t ) const { return query( "$gt
" , t ); }
BSONFieldValue<BSONObj> lt( const T& t ) const { return query( "$lt
" , t ); }
BSONFieldValue<BSONObj> query( const char * q , const T& t ) const;
BSONFieldValue<T> operator()( const T& t ) const {
return BSONFieldValue<T>( _name , t );
}
private:
std::string _name;
std::string _longName;
};
/** Utility for creating a BSONObj. /** Utility for creating a BSONObj.
See also the BSON() and BSON_ARRAY() macros. See also the BSON() and BSON_ARRAY() macros.
*/ */
class BSONObjBuilder : public BSONBuilderBase, private boost::noncopyab le { class BSONObjBuilder : public BSONBuilderBase, private boost::noncopyab le {
public: public:
/** @param initsize this is just a hint as to the final size of the object */ /** @param initsize this is just a hint as to the final size of the object */
BSONObjBuilder(int initsize=512) : _b(_buf), _buf(initsize + sizeof (unsigned)), _offset( sizeof(unsigned) ), _s( this ) , _tracker(0) , _doneC alled(false) { BSONObjBuilder(int initsize=512) : _b(_buf), _buf(initsize + sizeof (unsigned)), _offset( sizeof(unsigned) ), _s( this ) , _tracker(0) , _doneC alled(false) {
_b.appendNum((unsigned)0); // ref-count _b.appendNum((unsigned)0); // ref-count
_b.skip(4); /*leave room for size field and ref-count*/ _b.skip(4); /*leave room for size field and ref-count*/
} }
 End of changes. 2 change blocks. 
45 lines changed or deleted 1 lines changed or added


 bsonobjiterator.h   bsonobjiterator.h 
skipping to change at line 64 skipping to change at line 64
/** @return true if more elements exist to be enumerated. */ /** @return true if more elements exist to be enumerated. */
bool more() { return _pos < _theend; } bool more() { return _pos < _theend; }
/** @return true if more elements exist to be enumerated INCLUDING the EOO element which is always at the end. */ /** @return true if more elements exist to be enumerated INCLUDING the EOO element which is always at the end. */
bool moreWithEOO() { return _pos <= _theend; } bool moreWithEOO() { return _pos <= _theend; }
/** @return the next element in the object. For the final element, element.eoo() will be true. */ /** @return the next element in the object. For the final element, element.eoo() will be true. */
BSONElement next( bool checkEnd ) { BSONElement next( bool checkEnd ) {
verify( _pos <= _theend ); verify( _pos <= _theend );
BSONElement e( _pos, checkEnd ? (int)(_theend + 1 - _pos) : -1
); int maxLen = -1;
_pos += e.size( checkEnd ? (int)(_theend + 1 - _pos) : -1 ); if ( checkEnd ) {
maxLen = _theend + 1 - _pos;
verify( maxLen > 0 );
}
BSONElement e( _pos, maxLen );
int esize = e.size( maxLen );
massert( 16446, "BSONElement has bad size", esize > 0 );
_pos += esize;
return e; return e;
} }
BSONElement next() { BSONElement next() {
verify( _pos <= _theend ); verify( _pos <= _theend );
BSONElement e(_pos); BSONElement e(_pos);
_pos += e.size(); _pos += e.size();
return e; return e;
} }
void operator++() { next(); } void operator++() { next(); }
void operator++(int) { next(); } void operator++(int) { next(); }
 End of changes. 1 change blocks. 
3 lines changed or deleted 12 lines changed or added


 btree.h   btree.h 
skipping to change at line 407 skipping to change at line 407
* - If key cannot fit in the bucket, the bucket will be packed an d * - If key cannot fit in the bucket, the bucket will be packed an d
* the function will return false. * the function will return false.
* Although this function is marked const, it modifies the underlyi ng * Although this function is marked const, it modifies the underlyi ng
* btree representation through an optimized write intent mechanism . * btree representation through an optimized write intent mechanism .
*/ */
bool basicInsert(const DiskLoc thisLoc, int &keypos, const DiskLoc recordLoc, const Key& key, const Ordering &order) const; bool basicInsert(const DiskLoc thisLoc, int &keypos, const DiskLoc recordLoc, const Key& key, const Ordering &order) const;
/** /**
* Preconditions: * Preconditions:
* - key / recordLoc are > all existing keys * - key / recordLoc are > all existing keys
* - The keys in prevChild and their descendents are between all e xisting * - The keys in prevChild and their descendants are between all e xisting
* keys and 'key'. * keys and 'key'.
* Postconditions: * Postconditions:
* - If there is space for key without packing, it is inserted as the * - If there is space for key without packing, it is inserted as the
* last key with specified prevChild and true is returned. * last key with specified prevChild and true is returned.
* Importantly, nextChild is not updated! * Importantly, nextChild is not updated!
* - Otherwise false is returned and there is no change. * - Otherwise false is returned and there is no change.
*/ */
bool _pushBack(const DiskLoc recordLoc, const Key& key, const Order ing &order, const DiskLoc prevChild); bool _pushBack(const DiskLoc recordLoc, const Key& key, const Order ing &order, const DiskLoc prevChild);
void pushBack(const DiskLoc recordLoc, const Key& key, const Orderi ng &order, const DiskLoc prevChild) { void pushBack(const DiskLoc recordLoc, const Key& key, const Orderi ng &order, const DiskLoc prevChild) {
bool ok = _pushBack( recordLoc , key , order , prevChild ); bool ok = _pushBack( recordLoc , key , order , prevChild );
skipping to change at line 610 skipping to change at line 610
* pointer to. The pointer is cleared or removed explicitly, then the data * pointer to. The pointer is cleared or removed explicitly, then the data
* it pointed to is cleaned up with a helper function. * it pointed to is cleaned up with a helper function.
* *
* TODO It might make sense to put some of these functions in a class * TODO It might make sense to put some of these functions in a class
* representing a full btree instead of a single btree bucket. That wo uld * representing a full btree instead of a single btree bucket. That wo uld
* allow us to use the const qualifier in a manner more consistent with * allow us to use the const qualifier in a manner more consistent with
* standard usage. Right now the interface is for both a node and a tr ee, * standard usage. Right now the interface is for both a node and a tr ee,
* so assignment of const is sometimes nonideal. * so assignment of const is sometimes nonideal.
* *
* TODO There are several cases in which the 'this' pointer is invalida ted * TODO There are several cases in which the 'this' pointer is invalida ted
* as a result of deallocation. A seperate class representing a btree would * as a result of deallocation. A separate class representing a btree would
* alleviate some fragile cases where the implementation must currently * alleviate some fragile cases where the implementation must currently
* behave correctly if the 'this' pointer is suddenly invalidated by a * behave correctly if the 'this' pointer is suddenly invalidated by a
* callee. * callee.
*/ */
template< class V > template< class V >
class BtreeBucket : public BucketBasics<V> { class BtreeBucket : public BucketBasics<V> {
friend class BtreeCursor; friend class BtreeCursor;
friend struct IndexInsertionContinuationImpl<V>; friend struct IndexInsertionContinuationImpl<V>;
public: public:
// make compiler happy: // make compiler happy:
skipping to change at line 1099 skipping to change at line 1099
virtual BSONObj current() { return BSONObj::make(_current()); } virtual BSONObj current() { return BSONObj::make(_current()); }
virtual string toString(); virtual string toString();
BSONObj prettyKey( const BSONObj &key ) const { BSONObj prettyKey( const BSONObj &key ) const {
return key.replaceFieldNames( indexDetails.keyPattern() ).clien tReadable(); return key.replaceFieldNames( indexDetails.keyPattern() ).clien tReadable();
} }
virtual BSONObj prettyIndexBounds() const; virtual BSONObj prettyIndexBounds() const;
virtual CoveredIndexMatcher *matcher() const { return _matcher.get( ); } virtual CoveredIndexMatcher *matcher() const { return _matcher.get( ); }
virtual shared_ptr< CoveredIndexMatcher > matcherPtr() const { retu rn _matcher; }
virtual void setMatcher( shared_ptr< CoveredIndexMatcher > matcher ) { _matcher = matcher; } virtual void setMatcher( shared_ptr< CoveredIndexMatcher > matcher ) { _matcher = matcher; }
virtual const Projection::KeyOnly *keyFieldsOnly() const { return _ keyFieldsOnly.get(); } virtual const Projection::KeyOnly *keyFieldsOnly() const { return _ keyFieldsOnly.get(); }
virtual void setKeyFieldsOnly( const shared_ptr<Projection::KeyOnly > &keyFieldsOnly ) { virtual void setKeyFieldsOnly( const shared_ptr<Projection::KeyOnly > &keyFieldsOnly ) {
_keyFieldsOnly = keyFieldsOnly; _keyFieldsOnly = keyFieldsOnly;
} }
virtual long long nscanned() { return _nscanned; } virtual long long nscanned() { return _nscanned; }
 End of changes. 3 change blocks. 
3 lines changed or deleted 2 lines changed or added


 btreebuilder.h   btreebuilder.h 
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "btree.h" #include "btree.h"
namespace mongo { namespace mongo {
/** /**
* build btree from the bottom up * build btree from the bottom up
*/ */
template< class V > template< class V >
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 builder.h   builder.h 
skipping to change at line 28 skipping to change at line 28
#pragma once #pragma once
#include <cfloat> #include <cfloat>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
#include <string.h> #include <string.h>
#include "mongo/bson/inline_decls.h" #include "mongo/bson/inline_decls.h"
#include "mongo/bson/stringdata.h" #include "mongo/base/string_data.h"
namespace mongo { namespace mongo {
/* Accessing unaligned doubles on ARM generates an alignment trap and a borts with SIGBUS on Linux. /* Accessing unaligned doubles on ARM generates an alignment trap and a borts with SIGBUS on Linux.
Wrapping the double in a packed struct forces gcc to generate code t hat works with unaligned values too. Wrapping the double in a packed struct forces gcc to generate code t hat works with unaligned values too.
The generated code for other architectures (which already allow unal igned accesses) is the same as if The generated code for other architectures (which already allow unal igned accesses) is the same as if
there was a direct pointer access. there was a direct pointer access.
*/ */
struct PackedDouble { struct PackedDouble {
double d; double d;
} PACKED_DECL; } PACKED_DECL;
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 checksum.h   checksum.h 
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "mongo/pch.h" #include "mongo/pch.h"
namespace mongo { namespace mongo {
/** a simple, rather dumb, but very fast checksum. see perftests.cpp f or unit tests. */ /** a simple, rather dumb, but very fast checksum. see perftests.cpp f or unit tests. */
struct Checksum { struct Checksum {
union { union {
unsigned char bytes[16]; unsigned char bytes[16];
unsigned long long words[2]; unsigned long long words[2];
}; };
// if you change this you must bump dur::CurrentVersion // if you change this you must bump dur::CurrentVersion
void gen(const void *buf, unsigned len) { void gen(const void *buf, unsigned len) {
 End of changes. 3 change blocks. 
0 lines changed or deleted 20 lines changed or added


 chunk.h   chunk.h 
skipping to change at line 80 skipping to change at line 80
// chunk boundary support // chunk boundary support
// //
const BSONObj& getMin() const { return _min; } const BSONObj& getMin() const { return _min; }
const BSONObj& getMax() const { return _max; } const BSONObj& getMax() const { return _max; }
// if min/max key is pos/neg infinity // if min/max key is pos/neg infinity
bool minIsInf() const; bool minIsInf() const;
bool maxIsInf() const; bool maxIsInf() const;
bool contains( const BSONObj& obj ) const; // Returns true if this chunk contains the given point, and false o
therwise
//
// Note: this function takes an extracted *key*, not an original do
cument
// (the point may be computed by, say, hashing a given field or pro
jecting
// to a subset of fields).
bool containsPoint( const BSONObj& point ) const;
string genID() const; string genID() const;
static string genID( const string& ns , const BSONObj& min ); static string genID( const string& ns , const BSONObj& min );
// //
// chunk version support // chunk version support
// //
void appendShortVersion( const char * name , BSONObjBuilder& b ) co nst; void appendShortVersion( const char * name , BSONObjBuilder& b ) co nst;
ShardChunkVersion getLastmod() const { return _lastmod; } ShardChunkVersion getLastmod() const { return _lastmod; }
void setLastmod( ShardChunkVersion v ) { _lastmod = v; } void setLastmod( ShardChunkVersion v ) { _lastmod = v; }
// //
// split support // split support
// //
long getBytesWritten() const { return _dataWritten; }
// Const since _dataWritten is mutable and a heuristic
// TODO: Split data tracking and chunk information
void setBytesWritten( long bytesWritten ) const { _dataWritten = by
tesWritten; }
/** /**
* if the amount of data written nears the max size of a shard * if the amount of data written nears the max size of a shard
* then we check the real size, and if its too big, we split * then we check the real size, and if its too big, we split
* @return if something was split * @return if something was split
*/ */
bool splitIfShould( long dataWritten ) const; bool splitIfShould( long dataWritten ) const;
/** /**
* Splits this chunk at a non-specificed split key to be chosen by the mongod holding this chunk. * Splits this chunk at a non-specificed split key to be chosen by the mongod holding this chunk.
* *
skipping to change at line 194 skipping to change at line 194
static int MaxObjectPerChunk; static int MaxObjectPerChunk;
static bool ShouldAutoSplit; static bool ShouldAutoSplit;
// //
// accessors and helpers // accessors and helpers
// //
string toString() const; string toString() const;
friend ostream& operator << (ostream& out, const Chunk& c) { return (out << c.toString()); } friend ostream& operator << (ostream& out, const Chunk& c) { return (out << c.toString()); }
// chunk equality is determined by comparing the min and max bounds
of the chunk
bool operator==(const Chunk& s) const; bool operator==(const Chunk& s) const;
bool operator!=(const Chunk& s) const { return ! ( *this == s ); } bool operator!=(const Chunk& s) const { return ! ( *this == s ); }
string getns() const; string getns() const;
const char * getNS() { return "config.chunks"; } const char * getNS() { return "config.chunks"; }
Shard getShard() const { return _shard; } Shard getShard() const { return _shard; }
const ChunkManager* getManager() const { return _manager; } const ChunkManager* getManager() const { return _manager; }
private: private:
skipping to change at line 220 skipping to change at line 222
Shard _shard; Shard _shard;
ShardChunkVersion _lastmod; ShardChunkVersion _lastmod;
mutable bool _jumbo; mutable bool _jumbo;
// transient stuff // transient stuff
mutable long _dataWritten; mutable long _dataWritten;
// methods, etc.. // methods, etc..
/** /** Returns the highest or lowest existing value in the shard-key s
pace.
* Warning: this assumes that the shard key is not "special"- that
is, the shardKeyPattern
* is simply an ordered list of ascending/descending fiel
d names. Examples:
* {a : 1, b : -1} is not special. {a : "hashed"} is.
*
* if sort 1, return lowest key * if sort 1, return lowest key
* if sort -1, return highest key * if sort -1, return highest key
* will return empty object if have none * will return empty object if have none
*/ */
BSONObj _getExtremeKey( int sort ) const; BSONObj _getExtremeKey( int sort ) const;
/** initializes _dataWritten with a random value so that a mongos r estart wouldn't cause delay in splitting */ /** initializes _dataWritten with a random value so that a mongos r estart wouldn't cause delay in splitting */
static long mkDataWritten(); static long mkDataWritten();
ShardKeyPattern skey() const; ShardKeyPattern skey() const;
skipping to change at line 242 skipping to change at line 248
class ChunkRange { class ChunkRange {
public: public:
const ChunkManager* getManager() const { return _manager; } const ChunkManager* getManager() const { return _manager; }
Shard getShard() const { return _shard; } Shard getShard() const { return _shard; }
const BSONObj& getMin() const { return _min; } const BSONObj& getMin() const { return _min; }
const BSONObj& getMax() const { return _max; } const BSONObj& getMax() const { return _max; }
// clones of Chunk methods // clones of Chunk methods
bool contains(const BSONObj& obj) const; // Returns true if this ChunkRange contains the given point, and fa
lse otherwise
//
// Note: this function takes an extracted *key*, not an original do
cument
// (the point may be computed by, say, hashing a given field or pro
jecting
// to a subset of fields).
bool containsPoint( const BSONObj& point ) const;
ChunkRange(ChunkMap::const_iterator begin, const ChunkMap::const_it erator end) ChunkRange(ChunkMap::const_iterator begin, const ChunkMap::const_it erator end)
: _manager(begin->second->getManager()) : _manager(begin->second->getManager())
, _shard(begin->second->getShard()) , _shard(begin->second->getShard())
, _min(begin->second->getMin()) , _min(begin->second->getMin())
, _max(boost::prior(end)->second->getMax()) { , _max(boost::prior(end)->second->getMax()) {
verify( begin != end ); verify( begin != end );
DEV while (begin != end) { DEV while (begin != end) {
verify(begin->second->getManager() == _manager); verify(begin->second->getManager() == _manager);
skipping to change at line 360 skipping to change at line 371
const vector<Shard>* initShards, const vector<Shard>* initShards,
vector<BSONObj>* splitPoints, vector<BSONObj>* splitPoints,
vector<Shard>* shards ) const; vector<Shard>* shards ) const;
// //
// Methods to use once loaded / created // Methods to use once loaded / created
// //
int numChunks() const { return _chunkMap.size(); } int numChunks() const { return _chunkMap.size(); }
ChunkPtr findChunk( const BSONObj& obj ) const; /** Given a document, returns the chunk which contains that documen
t.
* This works by extracting the shard key part of the given docume
nt, then
* calling findIntersectingChunk() on the extracted key.
*
* See also the description for findIntersectingChunk().
*/
ChunkPtr findChunkForDoc( const BSONObj& doc ) const;
/** Given a key that has been extracted from a document, returns th
e
* chunk that contains that key.
*
* For instance, to locate the chunk for document {a : "foo" , b :
"bar"}
* when the shard key is {a : "hashed"}, you can call
* findChunkForDoc() on {a : "foo" , b : "bar"}, or
* findIntersectingChunk() on {a : hash("foo") }
*/
ChunkPtr findIntersectingChunk( const BSONObj& point ) const;
ChunkPtr findChunkOnServer( const Shard& shard ) const; ChunkPtr findChunkOnServer( const Shard& shard ) const;
void getShardsForQuery( set<Shard>& shards , const BSONObj& query ) const; void getShardsForQuery( set<Shard>& shards , const BSONObj& query ) const;
void getAllShards( set<Shard>& all ) const; void getAllShards( set<Shard>& all ) const;
/** @param shards set to the shards covered by the interval [min, m ax], see SERVER-4791 */ /** @param shards set to the shards covered by the interval [min, m ax], see SERVER-4791 */
void getShardsForRange(set<Shard>& shards, const BSONObj& min, cons t BSONObj& max, bool fullKeyReq = true) const; void getShardsForRange(set<Shard>& shards, const BSONObj& min, cons t BSONObj& max, bool fullKeyReq = true) const;
ChunkMap getChunkMap() const { return _chunkMap; } ChunkMap getChunkMap() const { return _chunkMap; }
/** /**
skipping to change at line 525 skipping to change at line 553
struct chunk_lock { struct chunk_lock {
chunk_lock( const Chunk* c ){ chunk_lock( const Chunk* c ){
} }
Chunk _c; Chunk _c;
}; };
*/ */
inline string Chunk::genID() const { return genID(_manager->getns(), _m in); } inline string Chunk::genID() const { return genID(_manager->getns(), _m in); }
bool setShardVersion( DBClientBase & conn , const string& ns , ShardChu bool setShardVersion( DBClientBase & conn,
nkVersion version , bool authoritative , BSONObj& result ); const string& ns,
ShardChunkVersion version,
ChunkManagerPtr manager,
bool authoritative,
BSONObj& result );
} // namespace mongo } // namespace mongo
 End of changes. 7 change blocks. 
12 lines changed or deleted 57 lines changed or added


 chunk_diff.hpp   chunk_diff.hpp 
skipping to change at line 287 skipping to change at line 287
// //
// We don't want to send a giant $or query to the server, so ju st get all the chunks // We don't want to send a giant $or query to the server, so ju st get all the chunks
// //
queryB.append( "ns", _ns ); queryB.append( "ns", _ns );
} }
BSONObj query = queryB.obj(); BSONObj query = queryB.obj();
// // log() << "major version query from " << *_maxVersion << " and ov
// NOTE: IT IS IMPORTANT FOR CONSISTENCY THAT WE SORT BY ASC VERSIO er " << _maxShardVersions->size() << " shards is " << query << endl;
N, TO HANDLE
// CURSOR YIELDING BETWEEN CHUNKS BEING MIGRATED.
//
Query queryObj(query); return Query( query );
queryObj.sort(BSON( "lastmod" << 1 ));
LOG(2) << "major version query from " << *_maxVersion << " and over
"
<< _maxShardVersions->size() << " shards is " << queryObj <<
endl;
return queryObj;
} }
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
14 lines changed or deleted 3 lines changed or added


 client.h   client.h 
skipping to change at line 171 skipping to change at line 171
~GodScope(); ~GodScope();
}; };
//static void assureDatabaseIsOpen(const string& ns, string path=db path); //static void assureDatabaseIsOpen(const string& ns, string path=db path);
/** "read lock, and set my context, all in one operation" /** "read lock, and set my context, all in one operation"
* This handles (if not recursively locked) opening an unopened da tabase. * This handles (if not recursively locked) opening an unopened da tabase.
*/ */
class ReadContext : boost::noncopyable { class ReadContext : boost::noncopyable {
public: public:
ReadContext(const string& ns, string path=dbpath, bool doauth=t rue ); ReadContext(const std::string& ns, const std::string& path=dbpa th, bool doauth=true );
Context& ctx() { return *c.get(); } Context& ctx() { return *c.get(); }
private: private:
scoped_ptr<Lock::DBRead> lk; scoped_ptr<Lock::DBRead> lk;
scoped_ptr<Context> c; scoped_ptr<Context> c;
}; };
/* Set database we want to use, then, restores when we finish (are out of scope) /* Set database we want to use, then, restores when we finish (are out of scope)
Note this is also helpful if an exception happens as the state i f fixed up. Note this is also helpful if an exception happens as the state i f fixed up.
*/ */
class Context : boost::noncopyable { class Context : boost::noncopyable {
public: public:
/** this is probably what you want */ /** this is probably what you want */
Context(const string& ns, string path=dbpath, bool doauth=true, bool doVersion=true ); Context(const string& ns, const std::string& path=dbpath, bool doauth=true, bool doVersion=true );
/** note: this does not call finishInit -- i.e., does not call /** note: this does not call finishInit -- i.e., does not call
shardVersionOk() for example. shardVersionOk() for example.
see also: reset(). see also: reset().
*/ */
Context( string ns , Database * db, bool doauth=true ); Context( const std::string& ns , Database * db, bool doauth=tru e );
// used by ReadContext // used by ReadContext
Context(const string& path, const string& ns, Database *db, boo l doauth); Context(const string& path, const string& ns, Database *db, boo l doauth);
~Context(); ~Context();
Client* getClient() const { return _client; } Client* getClient() const { return _client; }
Database* db() const { return _db; } Database* db() const { return _db; }
const char * ns() const { return _ns.c_str(); } const char * ns() const { return _ns.c_str(); }
bool equals( const string& ns , const string& path=dbpath ) con st { return _ns == ns && _path == path; } bool equals( const string& ns , const string& path=dbpath ) con st { return _ns == ns && _path == path; }
skipping to change at line 240 skipping to change at line 240
bool _justCreated; bool _justCreated;
bool _doVersion; bool _doVersion;
const string _ns; const string _ns;
Database * _db; Database * _db;
Timer _timer; Timer _timer;
}; // class Client::Context }; // class Client::Context
class WriteContext : boost::noncopyable { class WriteContext : boost::noncopyable {
public: public:
WriteContext(const string& ns, string path=dbpath, bool doauth= true ); WriteContext(const string& ns, const std::string& path=dbpath, bool doauth=true );
Context& ctx() { return _c; } Context& ctx() { return _c; }
private: private:
Lock::DBWrite _lk; Lock::DBWrite _lk;
Context _c; Context _c;
}; };
}; // class Client }; // class Client
/** get the Client object for this thread. */ /** get the Client object for this thread. */
inline Client& cc() { inline Client& cc() {
 End of changes. 4 change blocks. 
4 lines changed or deleted 4 lines changed or added


 clientOnly-private.h   clientOnly-private.h 
/* Copyright 2012 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once #pragma once
namespace mongo { namespace mongo {
namespace shell_utils { namespace shell_utils {
extern mongo::mutex &mongoProgramOutputMutex; extern mongo::mutex &mongoProgramOutputMutex;
} }
} }
 End of changes. 1 change blocks. 
0 lines changed or deleted 16 lines changed or added


 client_common.h   client_common.h 
skipping to change at line 46 skipping to change at line 46
class ClientBasic : boost::noncopyable { class ClientBasic : boost::noncopyable {
public: public:
virtual ~ClientBasic(){} virtual ~ClientBasic(){}
virtual const AuthenticationInfo * getAuthenticationInfo() const = 0; virtual const AuthenticationInfo * getAuthenticationInfo() const = 0;
virtual AuthenticationInfo * getAuthenticationInfo() = 0; virtual AuthenticationInfo * getAuthenticationInfo() = 0;
virtual bool hasRemote() const = 0; virtual bool hasRemote() const = 0;
virtual HostAndPort getRemote() const = 0; virtual HostAndPort getRemote() const = 0;
static ClientBasic* getCurrent(); static ClientBasic* getCurrent();
static bool hasCurrent();
}; };
} }
 End of changes. 1 change blocks. 
2 lines changed or deleted 0 lines changed or added


 client_info.h   client_info.h 
skipping to change at line 101 skipping to change at line 101
BSONObjBuilder& result , BSONObjBuilder& result ,
string& errmsg, string& errmsg,
bool fromWriteBackListener = false ); bool fromWriteBackListener = false );
/** @return if its ok to auto split from this client */ /** @return if its ok to auto split from this client */
bool autoSplitOk() const { return _autoSplitOk && Chunk::ShouldAuto Split; } bool autoSplitOk() const { return _autoSplitOk && Chunk::ShouldAuto Split; }
void noAutoSplit() { _autoSplitOk = false; } void noAutoSplit() { _autoSplitOk = false; }
static ClientInfo * get(); static ClientInfo * get();
// Returns whether or not a ClientInfo for this thread has already
been created and stored
// in _tlInfo.
static bool exists();
const AuthenticationInfo* getAuthenticationInfo() const { return (A uthenticationInfo*)&_ai; } const AuthenticationInfo* getAuthenticationInfo() const { return (A uthenticationInfo*)&_ai; }
AuthenticationInfo* getAuthenticationInfo() { return (Authenticatio nInfo*)&_ai; } AuthenticationInfo* getAuthenticationInfo() { return (Authenticatio nInfo*)&_ai; }
bool isAdmin() { return _ai.isAuthorized( "admin" ); } bool isAdmin() { return _ai.isAuthorized( "admin" ); }
private: private:
AuthenticationInfo _ai; AuthenticationInfo _ai;
struct WBInfo { struct WBInfo {
WBInfo( const WriteBackListener::ConnectionIdent& c, OID o, boo WBInfo( const WriteBackListener::ConnectionIdent& c , OID o ) :
l fromLastOperation ) ident( c ) , id( o ) {}
: ident( c ), id( o ), fromLastOperation( fromLastOperation
) {}
WriteBackListener::ConnectionIdent ident; WriteBackListener::ConnectionIdent ident;
OID id; OID id;
bool fromLastOperation;
}; };
// for getLastError // for getLastError
void _addWriteBack( vector<WBInfo>& all , const BSONObj& o, bool fr void _addWriteBack( vector<WBInfo>& all , const BSONObj& o );
omLastOperation ); vector<BSONObj> _handleWriteBacks( vector<WBInfo>& all , bool fromW
vector<BSONObj> _handleWriteBacks( const vector<WBInfo>& all , bool riteBackListener );
fromWriteBackListener );
int _id; // unique client id int _id; // unique client id
HostAndPort _remote; // server:port of remote socket end HostAndPort _remote; // server:port of remote socket end
// we use _a and _b to store shards we've talked to on the current request and the previous // we use _a and _b to store shards we've talked to on the current request and the previous
// we use 2 so we can flip for getLastError type operations // we use 2 so we can flip for getLastError type operations
set<string> _a; // actual set for _cur or _prev set<string> _a; // actual set for _cur or _prev
set<string> _b; // " set<string> _b; // "
 End of changes. 4 change blocks. 
15 lines changed or deleted 5 lines changed or added


 clientcursor.h   clientcursor.h 
skipping to change at line 41 skipping to change at line 41
#include "cursor.h" #include "cursor.h"
#include "jsobj.h" #include "jsobj.h"
#include "../util/net/message.h" #include "../util/net/message.h"
#include "../util/net/listen.h" #include "../util/net/listen.h"
#include "../util/background.h" #include "../util/background.h"
#include "diskloc.h" #include "diskloc.h"
#include "dbhelpers.h" #include "dbhelpers.h"
#include "matcher.h" #include "matcher.h"
#include "projection.h" #include "projection.h"
#include "s/d_chunk_manager.h" #include "s/d_chunk_manager.h"
#include "mongo/db/keypattern.h"
namespace mongo { namespace mongo {
typedef boost::recursive_mutex::scoped_lock recursive_scoped_lock; typedef boost::recursive_mutex::scoped_lock recursive_scoped_lock;
typedef long long CursorId; /* passed to the client so it can send back on getMore */ typedef long long CursorId; /* passed to the client so it can send back on getMore */
static const CursorId INVALID_CURSOR_ID = -1; // But see SERVER-5726. static const CursorId INVALID_CURSOR_ID = -1; // But see SERVER-5726.
class Cursor; /* internal server cursor base class */ class Cursor; /* internal server cursor base class */
class ClientCursor; class ClientCursor;
class ParsedQuery; class ParsedQuery;
skipping to change at line 146 skipping to change at line 147
_id = c->_cursorid; _id = c->_cursorid;
} }
else { else {
_c = 0; _c = 0;
_id = INVALID_CURSOR_ID; _id = INVALID_CURSOR_ID;
} }
} }
~Holder() { ~Holder() {
DESTRUCTOR_GUARD ( reset(); ); DESTRUCTOR_GUARD ( reset(); );
} }
ClientCursor* get() { return _c; }
operator bool() { return _c; } operator bool() { return _c; }
ClientCursor * operator-> () { return _c; } ClientCursor * operator-> () { return _c; }
const ClientCursor * operator-> () const { return _c; } const ClientCursor * operator-> () const { return _c; }
/** Release ownership of the ClientCursor. */ /** Release ownership of the ClientCursor. */
void release() { void release() {
_c = 0; _c = 0;
_id = INVALID_CURSOR_ID; _id = INVALID_CURSOR_ID;
} }
private: private:
ClientCursor *_c; ClientCursor *_c;
skipping to change at line 294 skipping to change at line 294
BSONElement getFieldDotted( const string& name , BSONObj& holder , bool * fromKey = 0 ) ; BSONElement getFieldDotted( const string& name , BSONObj& holder , bool * fromKey = 0 ) ;
/** extract items from object which match a pattern object. /** extract items from object which match a pattern object.
* e.g., if pattern is { x : 1, y : 1 }, builds an object with * e.g., if pattern is { x : 1, y : 1 }, builds an object with
* x and y elements of this object, if they are present. * x and y elements of this object, if they are present.
* returns elements with original field names * returns elements with original field names
* NOTE: copied from BSONObj::extractFields * NOTE: copied from BSONObj::extractFields
*/ */
BSONObj extractFields(const BSONObj &pattern , bool fillWithNull = false) ; BSONObj extractFields(const BSONObj &pattern , bool fillWithNull = false) ;
/** Extract elements from the object this cursor currently points t
o, using the expression
* specified in KeyPattern. Will use a covered index if the one in
this cursor is usable.
* TODO: there are some cases where a covered index could be used
but is not, for instance
* if both this index and the keyPattern are {a : "hashed"}
*/
BSONObj extractKey( const KeyPattern& usingKeyPattern ) const;
void fillQueryResultFromObj( BufBuilder &b, const MatchDetails* det ails = NULL ) const; void fillQueryResultFromObj( BufBuilder &b, const MatchDetails* det ails = NULL ) const;
bool currentIsDup() { return _c->getsetdup( _c->currLoc() ); } bool currentIsDup() { return _c->getsetdup( _c->currLoc() ); }
bool currentMatches() { bool currentMatches() {
if ( ! _c->matcher() ) if ( ! _c->matcher() )
return true; return true;
return _c->matcher()->matchesCurrent( _c.get() ); return _c->matcher()->matchesCurrent( _c.get() );
} }
void setChunkManager( ShardChunkManagerPtr manager ){ _chunkManager = manager; } void setChunkManager( ShardChunkManagerPtr manager ){ _chunkManager = manager; }
ShardChunkManagerPtr getChunkManager(){ return _chunkManager; } ShardChunkManagerPtr getChunkManager(){ return _chunkManager; }
private: private:
void setLastLoc_inlock(DiskLoc); void setLastLoc_inlock(DiskLoc);
static ClientCursor* find_inlock(CursorId id, bool warn = true) { static ClientCursor* find_inlock(CursorId id, bool warn = true) {
CCById::iterator it = clientCursorsById.find(id); CCById::iterator it = clientCursorsById.find(id);
if ( it == clientCursorsById.end() ) { if ( it == clientCursorsById.end() ) {
if ( warn ) if ( warn ) {
OCCASIONALLY out() << "ClientCursor::find(): cursor not OCCASIONALLY out() << "ClientCursor::find(): cursor not
found in map " << id << " (ok after a drop)\n"; found in map '" << id
<< "' (ok after a drop)" << endl;
}
return 0; return 0;
} }
return it->second; return it->second;
} }
/* call when cursor's location changes so that we can update the /* call when cursor's location changes so that we can update the
cursorsbylocation map. if you are locked and internally iterating , only cursorsbylocation map. if you are locked and internally iterating , only
need to call when you are ready to "unlock". need to call when you are ready to "unlock".
*/ */
void updateLocation(); void updateLocation();
skipping to change at line 384 skipping to change at line 393
static void idleTimeReport(unsigned millis); static void idleTimeReport(unsigned millis);
static void appendStats( BSONObjBuilder& result ); static void appendStats( BSONObjBuilder& result );
static unsigned numCursors() { return clientCursorsById.size(); } static unsigned numCursors() { return clientCursorsById.size(); }
static void informAboutToDeleteBucket(const DiskLoc& b); static void informAboutToDeleteBucket(const DiskLoc& b);
static void aboutToDelete(const DiskLoc& dl); static void aboutToDelete(const DiskLoc& dl);
static void find( const string& ns , set<CursorId>& all ); static void find( const string& ns , set<CursorId>& all );
private: // methods private: // methods
// cursors normally timeout after an inactivy period to prevent exc ess memory use // cursors normally timeout after an inactivity period to prevent e xcess memory use
// setting this prevents timeout of the cursor in question. // setting this prevents timeout of the cursor in question.
void noTimeout() { _pinValue++; } void noTimeout() { _pinValue++; }
CCByLoc& byLoc() { return _db->ccByLoc; } CCByLoc& byLoc() { return _db->ccByLoc; }
Record* _recordForYield( RecordNeeds need ); Record* _recordForYield( RecordNeeds need );
private: private:
CursorId _cursorid; CursorId _cursorid;
 End of changes. 5 change blocks. 
5 lines changed or deleted 17 lines changed or added


 cmdline.h   cmdline.h 
skipping to change at line 19 skipping to change at line 19
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include "mongo/pch.h" #include <string>
#include "jsobj.h" #include <vector>
#include "mongo/db/jsobj.h"
#include "mongo/util/net/listen.h"
namespace boost { namespace boost {
namespace program_options { namespace program_options {
class options_description; class options_description;
class positional_options_description; class positional_options_description;
class variables_map; class variables_map;
} }
} }
namespace mongo { namespace mongo {
skipping to change at line 43 skipping to change at line 46
class SSLManager; class SSLManager;
#endif #endif
/* command line options /* command line options
*/ */
/* concurrency: OK/READ */ /* concurrency: OK/READ */
struct CmdLine { struct CmdLine {
CmdLine(); CmdLine();
string binaryName; // mongod or mongos std::string binaryName; // mongod or mongos
string cwd; // cwd of when process started std::string cwd; // cwd of when process started
// this is suboptimal as someone could rename a binary. todo... // this is suboptimal as someone could rename a binary. todo...
bool isMongos() const { return binaryName == "mongos"; } bool isMongos() const { return binaryName == "mongos"; }
int port; // --port int port; // --port
enum { enum {
DefaultDBPort = 27017, DefaultDBPort = 27017,
ConfigServerPort = 27019, ConfigServerPort = 27019,
ShardServerPort = 27018 ShardServerPort = 27018
}; };
bool isDefaultPort() const { return port == DefaultDBPort; } bool isDefaultPort() const { return port == DefaultDBPort; }
string bind_ip; // --bind_ip std::string bind_ip; // --bind_ip
bool rest; // --rest bool rest; // --rest
bool jsonp; // --jsonp bool jsonp; // --jsonp
string _replSet; // --replSet[/<seedlist>] std::string _replSet; // --replSet[/<seedlist>]
string ourSetName() const { std::string ourSetName() const {
string setname; std::string setname;
size_t sl = _replSet.find('/'); size_t sl = _replSet.find('/');
if( sl == string::npos ) if( sl == std::string::npos )
return _replSet; return _replSet;
return _replSet.substr(0, sl); return _replSet.substr(0, sl);
} }
bool usingReplSets() const { return !_replSet.empty(); } bool usingReplSets() const { return !_replSet.empty(); }
string rsIndexPrefetch;// --indexPrefetch std::string rsIndexPrefetch;// --indexPrefetch
// for master/slave replication // for master/slave replication
string source; // --source std::string source; // --source
string only; // --only std::string only; // --only
bool quiet; // --quiet bool quiet; // --quiet
bool noTableScan; // --notablescan no table scans allowed bool noTableScan; // --notablescan no table scans allowed
bool prealloc; // --noprealloc no preallocation of data fil es bool prealloc; // --noprealloc no preallocation of data fil es
bool preallocj; // --nopreallocj no preallocation of journal files bool preallocj; // --nopreallocj no preallocation of journal files
bool smallfiles; // --smallfiles allocate smaller data files bool smallfiles; // --smallfiles allocate smaller data files
bool configsvr; // --configsvr bool configsvr; // --configsvr
bool quota; // --quota bool quota; // --quota
skipping to change at line 118 skipping to change at line 121
long long oplogSize; // --oplogSize long long oplogSize; // --oplogSize
int defaultProfile; // --profile int defaultProfile; // --profile
int slowMS; // --time in ms that is "slow" int slowMS; // --time in ms that is "slow"
int defaultLocalThresholdMillis; // --localThreshold in ms to co nsider a node local int defaultLocalThresholdMillis; // --localThreshold in ms to co nsider a node local
int pretouch; // --pretouch for replication application (e xperimental) int pretouch; // --pretouch for replication application (e xperimental)
bool moveParanoia; // for move chunk paranoia bool moveParanoia; // for move chunk paranoia
double syncdelay; // seconds between fsyncs double syncdelay; // seconds between fsyncs
bool noUnixSocket; // --nounixsocket bool noUnixSocket; // --nounixsocket
bool doFork; // --fork bool doFork; // --fork
string socket; // UNIX domain socket directory std::string socket; // UNIX domain socket directory
int maxConns; // Maximum number of simultaneous open conne
ctions.
std::string keyFile; // Path to keyfile, or empty if none.
std::string pidFile; // Path to pid file, or empty if none.
bool keyFile; std::string logpath; // Path to log file, if logging to a file; o
therwise, empty.
bool logAppend; // True if logging to a file in append mode.
bool logWithSyslog; // True if logging to syslog; must not be se
t if logpath is set.
#ifndef _WIN32 #ifndef _WIN32
pid_t parentProc; // --fork pid of initial process pid_t parentProc; // --fork pid of initial process
pid_t leaderProc; // --fork pid of leader process pid_t leaderProc; // --fork pid of leader process
#endif #endif
#ifdef MONGO_SSL #ifdef MONGO_SSL
bool sslOnNormalPorts; // --sslOnNormalPorts bool sslOnNormalPorts; // --sslOnNormalPorts
string sslPEMKeyFile; // --sslPEMKeyFile std::string sslPEMKeyFile; // --sslPEMKeyFile
string sslPEMKeyPassword; // --sslPEMKeyPassword std::string sslPEMKeyPassword; // --sslPEMKeyPassword
SSLManager* sslServerManager; // currently leaks on close SSLManager* sslServerManager; // currently leaks on close
#endif #endif
static void launchOk(); static void launchOk();
static void addGlobalOptions( boost::program_options::options_descr iption& general , static void addGlobalOptions( boost::program_options::options_descr iption& general ,
boost::program_options::options_descr iption& hidden , boost::program_options::options_descr iption& hidden ,
boost::program_options::options_descr iption& ssl_options ); boost::program_options::options_descr iption& ssl_options );
static void addWindowsOptions( boost::program_options::options_desc ription& windows , static void addWindowsOptions( boost::program_options::options_desc ription& windows ,
boost::program_options::options_desc ription& hidden ); boost::program_options::options_desc ription& hidden );
static void parseConfigFile( istream &f, stringstream &ss); static void parseConfigFile( istream &f, std::stringstream &ss);
/** /**
* @return true if should run program, false if should exit * @return true if should run program, false if should exit
*/ */
static bool store( int argc , char ** argv , static bool store( const std::vector<std::string>& argv,
boost::program_options::options_description& vis ible, boost::program_options::options_description& vis ible,
boost::program_options::options_description& hid den, boost::program_options::options_description& hid den,
boost::program_options::positional_options_descr iption& positional, boost::program_options::positional_options_descr iption& positional,
boost::program_options::variables_map &output ); boost::program_options::variables_map &output );
/**
* Blot out sensitive fields in the argv array.
*/
static void censor(int argc, char** argv);
static void censor(std::vector<std::string>* args);
static BSONArray getArgvArray();
static BSONObj getParsedOpts();
time_t started; time_t started;
}; };
// todo move to cmdline.cpp? // todo move to cmdline.cpp?
inline CmdLine::CmdLine() : inline CmdLine::CmdLine() :
port(DefaultDBPort), rest(false), jsonp(false), quiet(false), port(DefaultDBPort), rest(false), jsonp(false), quiet(false),
noTableScan(false), prealloc(true), preallocj(true), smallfiles(siz eof(int*) == 4), noTableScan(false), prealloc(true), preallocj(true), smallfiles(siz eof(int*) == 4),
configsvr(false), quota(false), quotaFiles(8), cpu(false), configsvr(false), quota(false), quotaFiles(8), cpu(false),
durOptions(0), objcheck(false), oplogSize(0), defaultProfile(0), durOptions(0), objcheck(false), oplogSize(0), defaultProfile(0),
slowMS(100), defaultLocalThresholdMillis(15), pretouch(0), movePara noia( true ), slowMS(100), defaultLocalThresholdMillis(15), pretouch(0), movePara noia( true ),
syncdelay(60), noUnixSocket(false), doFork(0), socket("/tmp") syncdelay(60), noUnixSocket(false), doFork(0), socket("/tmp"), maxC
onns(DEFAULT_MAX_CONN),
logAppend(false), logWithSyslog(false)
{ {
started = time(0); started = time(0);
journalCommitInterval = 0; // 0 means use default journalCommitInterval = 0; // 0 means use default
dur = false; dur = false;
#if defined(_DURABLEDEFAULTON) #if defined(_DURABLEDEFAULTON)
dur = true; dur = true;
#endif #endif
if( sizeof(void*) == 8 ) if( sizeof(void*) == 8 )
dur = true; dur = true;
skipping to change at line 187 skipping to change at line 207
#endif #endif
#ifdef MONGO_SSL #ifdef MONGO_SSL
sslOnNormalPorts = false; sslOnNormalPorts = false;
sslServerManager = 0; sslServerManager = 0;
#endif #endif
} }
extern CmdLine cmdLine; extern CmdLine cmdLine;
void setupLaunchSignals();
void setupCoreSignals();
string prettyHostName();
void printCommandLineOpts(); void printCommandLineOpts();
/** /**
* used for setParameter command * used for setParameter command
* so you can write validation code that lives with code using it * so you can write validation code that lives with code using it
* rather than all in the command place * rather than all in the command place
* also lets you have mongos or mongod specific code * also lets you have mongos or mongod specific code
* without pulling it all sorts of things * without pulling it all sorts of things
*/ */
class ParameterValidator { class ParameterValidator {
public: public:
ParameterValidator( const string& name ); ParameterValidator( const std::string& name );
virtual ~ParameterValidator() {} virtual ~ParameterValidator() {}
virtual bool isValid( BSONElement e , string& errmsg ) const = 0; virtual bool isValid( BSONElement e , std::string& errmsg ) const = 0;
static ParameterValidator * get( const string& name ); static ParameterValidator * get( const std::string& name );
private: private:
const string _name; const std::string _name;
}; };
} }
 End of changes. 19 change blocks. 
28 lines changed or deleted 47 lines changed or added


 collection.h   collection.h 
// @file collection.h // @file collection.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "namespace.h" #include "namespace.h"
namespace mongo { namespace mongo {
class Collection { class Collection {
public: public:
NamespaceDetails * const d; NamespaceDetails * const d;
NamespaceDetailsTransient * const nsd; NamespaceDetailsTransient * const nsd;
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 compress.h   compress.h 
// @file compress.h // @file compress.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include <string> #include <string>
namespace mongo { namespace mongo {
size_t compress(const char* input, size_t input_length, std::string* ou tput); size_t compress(const char* input, size_t input_length, std::string* ou tput);
bool uncompress(const char* compressed, size_t compressed_length, std:: string* uncompressed); bool uncompress(const char* compressed, size_t compressed_length, std:: string* uncompressed);
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 config.h   config.h 
skipping to change at line 166 skipping to change at line 166
* @return the correct for shard for the ns * @return the correct for shard for the ns
* if the namespace is sharded, will return NULL * if the namespace is sharded, will return NULL
*/ */
ShardPtr getShardIfExists( const string& ns ); ShardPtr getShardIfExists( const string& ns );
const Shard& getPrimary() const { const Shard& getPrimary() const {
uassert( 8041 , (string)"no primary shard configured for db: " + _name , _primary.ok() ); uassert( 8041 , (string)"no primary shard configured for db: " + _name , _primary.ok() );
return _primary; return _primary;
} }
void setPrimary( string s ); void setPrimary( const std::string& s );
bool load(); bool load();
bool reload(); bool reload();
bool dropDatabase( string& errmsg ); bool dropDatabase( string& errmsg );
// model stuff // model stuff
// lockless loading // lockless loading
void serialize(BSONObjBuilder& to); void serialize(BSONObjBuilder& to);
skipping to change at line 228 skipping to change at line 228
virtual string modelServer() { virtual string modelServer() {
uassert( 10190 , "ConfigServer not setup" , _primary.ok() ); uassert( 10190 , "ConfigServer not setup" , _primary.ok() );
return _primary.getConnString(); return _primary.getConnString();
} }
/** /**
call at startup, this will initiate connection to the grid db call at startup, this will initiate connection to the grid db
*/ */
bool init( vector<string> configHosts ); bool init( vector<string> configHosts );
bool init( string s ); bool init( const std::string& s );
bool allUp(); bool allUp();
bool allUp( string& errmsg ); bool allUp( string& errmsg );
int dbConfigVersion(); int dbConfigVersion();
int dbConfigVersion( DBClientBase& conn ); int dbConfigVersion( DBClientBase& conn );
void reloadSettings(); void reloadSettings();
/** /**
skipping to change at line 269 skipping to change at line 269
static int VERSION; static int VERSION;
/** /**
* check to see if all config servers have the same state * check to see if all config servers have the same state
* will try tries time to make sure not catching in a bad state * will try tries time to make sure not catching in a bad state
*/ */
bool checkConfigServersConsistent( string& errmsg , int tries = 4 ) const; bool checkConfigServersConsistent( string& errmsg , int tries = 4 ) const;
private: private:
string getHost( string name , bool withPort ); string getHost( const std::string& name , bool withPort );
vector<string> _config; vector<string> _config;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 3 change blocks. 
3 lines changed or deleted 3 lines changed or added


 connections.h   connections.h 
skipping to change at line 44 skipping to change at line 44
{ {
ScopedConn c("foo.acme.com:9999"); ScopedConn c("foo.acme.com:9999");
c->runCommand(...); c->runCommand(...);
} }
throws exception on connect error (but fine to try again later with a new throws exception on connect error (but fine to try again later with a new
scopedconn object for same host). scopedconn object for same host).
*/ */
class ScopedConn { class ScopedConn {
public: public:
// A flag to keep ScopedConns open when all other sockets are disco
nnected
static const unsigned keepOpen;
/** throws assertions if connect failure etc. */ /** throws assertions if connect failure etc. */
ScopedConn(string hostport); ScopedConn(const std::string& hostport);
~ScopedConn() { ~ScopedConn() {
// conLock releases... // conLock releases...
} }
void reconnect() { void reconnect() {
connInfo->cc.reset(new DBClientConnection(true, 0, 10)); connInfo->cc.reset(new DBClientConnection(true, 0, connInfo->ge tTimeout()));
connInfo->cc->_logLevel = 2; connInfo->cc->_logLevel = 2;
connInfo->connected = false; connInfo->connected = false;
connect(); connect();
} }
void setTimeout(time_t timeout) {
connInfo->setTimeout(timeout);
}
/* If we were to run a query and not exhaust the cursor, future use of the connection would be problematic. /* If we were to run a query and not exhaust the cursor, future use of the connection would be problematic.
So here what we do is wrapper known safe methods and not allow c ursor-style queries at all. This makes So here what we do is wrapper known safe methods and not allow c ursor-style queries at all. This makes
ScopedConn limited in functionality but very safe. More non-cur sor wrappers can be added here if needed. ScopedConn limited in functionality but very safe. More non-cur sor wrappers can be added here if needed.
*/ */
bool runCommand(const string &dbname, bool runCommand(const string &dbname,
const BSONObj& cmd, const BSONObj& cmd,
BSONObj &info, BSONObj &info,
int options=0, int options=0,
const AuthenticationTable* auth=NULL) { const AuthenticationTable* auth=NULL) {
return conn()->runCommand(dbname, cmd, info, options, auth); return conn()->runCommand(dbname, cmd, info, options, noauth ? NULL : auth);
} }
unsigned long long count(const string &ns) { unsigned long long count(const string &ns) {
return conn()->count(ns); return conn()->count(ns);
} }
BSONObj findOne(const string &ns, const Query& q, const BSONObj *fi eldsToReturn = 0, int queryOptions = 0) { BSONObj findOne(const string &ns, const Query& q, const BSONObj *fi eldsToReturn = 0, int queryOptions = 0) {
return conn()->findOne(ns, q, fieldsToReturn, queryOptions); return conn()->findOne(ns, q, fieldsToReturn, queryOptions);
} }
private: private:
auto_ptr<scoped_lock> connLock; auto_ptr<scoped_lock> connLock;
static mongo::mutex mapMutex; static mongo::mutex mapMutex;
struct ConnectionInfo { struct ConnectionInfo {
mongo::mutex lock; mongo::mutex lock;
scoped_ptr<DBClientConnection> cc; scoped_ptr<DBClientConnection> cc;
bool connected; bool connected;
ConnectionInfo() : lock("ConnectionInfo"), ConnectionInfo() : lock("ConnectionInfo"),
cc(new DBClientConnection(/*reconnect*/ true cc(new DBClientConnection(/*reconnect*/ true,
, 0, /*timeout*/ 10.0)), /*replicaSet*/ 0,
connected(false) { /*timeout*/ ReplSetConfig::DEFAUL
T_HB_TIMEOUT)),
connected(false) {
cc->_logLevel = 2; cc->_logLevel = 2;
} }
void tagPort() {
MessagingPort& mp = cc->port();
mp.tag |= ScopedConn::keepOpen;
}
void setTimeout(time_t timeout) {
_timeout = timeout;
cc->setSoTimeout(_timeout);
}
int getTimeout() {
return _timeout;
}
private:
int _timeout;
} *connInfo; } *connInfo;
typedef map<string,ScopedConn::ConnectionInfo*> M; typedef map<string,ScopedConn::ConnectionInfo*> M;
static M& _map; static M& _map;
scoped_ptr<DBClientConnection>& conn() { return connInfo->cc; } scoped_ptr<DBClientConnection>& conn() { return connInfo->cc; }
const string _hostport; const string _hostport;
// we should already be locked... // we should already be locked...
bool connect() { bool connect() {
string err; string err;
if (!connInfo->cc->connect(_hostport, err)) { if (!connInfo->cc->connect(_hostport, err)) {
log() << "couldn't connect to " << _hostport << ": " << err << rsLog; log() << "couldn't connect to " << _hostport << ": " << err << rsLog;
return false; return false;
} }
connInfo->connected = true; connInfo->connected = true;
connInfo->tagPort();
// if we cannot authenticate against a member, then either its ke y file // if we cannot authenticate against a member, then either its ke y file
// or our key file has to change. if our key file has to change, we'll // or our key file has to change. if our key file has to change, we'll
// be rebooting. if their file has to change, they'll be rebooted so the // be rebooting. if their file has to change, they'll be rebooted so the
// connection created above will go dead, reconnect, and reauth. // connection created above will go dead, reconnect, and reauth.
if (!noauth) { if (!noauth) {
if (!connInfo->cc->auth("local", if (!connInfo->cc->auth("local",
internalSecurity.user, internalSecurity.user,
internalSecurity.pwd, internalSecurity.pwd,
err, err,
skipping to change at line 122 skipping to change at line 149
return false; return false;
} }
connInfo->cc->setAuthenticationTable( connInfo->cc->setAuthenticationTable(
AuthenticationTable::getInternalSecurityAuthenticatio nTable() ); AuthenticationTable::getInternalSecurityAuthenticatio nTable() );
} }
return true; return true;
} }
}; };
inline ScopedConn::ScopedConn(string hostport) : _hostport(hostport) { inline ScopedConn::ScopedConn(const std::string& hostport) : _hostport( hostport) {
bool first = false; bool first = false;
{ {
scoped_lock lk(mapMutex); scoped_lock lk(mapMutex);
connInfo = _map[_hostport]; connInfo = _map[_hostport];
if( connInfo == 0 ) { if( connInfo == 0 ) {
connInfo = _map[_hostport] = new ConnectionInfo(); connInfo = _map[_hostport] = new ConnectionInfo();
first = true; first = true;
connLock.reset( new scoped_lock(connInfo->lock) ); connLock.reset( new scoped_lock(connInfo->lock) );
} }
} }
skipping to change at line 148 skipping to change at line 175
} }
connLock.reset( new scoped_lock(connInfo->lock) ); connLock.reset( new scoped_lock(connInfo->lock) );
if (connInfo->connected) { if (connInfo->connected) {
return; return;
} }
// Keep trying to connect if we're not yet connected // Keep trying to connect if we're not yet connected
connect(); connect();
} }
} }
 End of changes. 10 change blocks. 
8 lines changed or deleted 35 lines changed or added


 connpool.h   connpool.h 
skipping to change at line 102 skipping to change at line 102
virtual void onCreate( DBClientBase * conn ) {} virtual void onCreate( DBClientBase * conn ) {}
virtual void onHandedOut( DBClientBase * conn ) {} virtual void onHandedOut( DBClientBase * conn ) {}
virtual void onDestroy( DBClientBase * conn ) {} virtual void onDestroy( DBClientBase * conn ) {}
}; };
/** Database connection pool. /** Database connection pool.
Generally, use ScopedDbConnection and do not call these directly. Generally, use ScopedDbConnection and do not call these directly.
This class, so far, is suitable for use with unauthenticated connec tions. This class, so far, is suitable for use with unauthenticated connec tions.
Support for authenticated connections requires some adjustements: p lease Support for authenticated connections requires some adjustments: pl ease
request... request...
Usage: Usage:
{ {
ScopedDbConnection c("myserver"); ScopedDbConnection c("myserver");
c.conn()... c.conn()...
} }
*/ */
class DBConnectionPool : public PeriodicTask { class DBConnectionPool : public PeriodicTask {
skipping to change at line 155 skipping to change at line 155
virtual void taskDoWork(); virtual void taskDoWork();
private: private:
DBConnectionPool( DBConnectionPool& p ); DBConnectionPool( DBConnectionPool& p );
DBClientBase* _get( const string& ident , double socketTimeout ); DBClientBase* _get( const string& ident , double socketTimeout );
DBClientBase* _finishCreate( const string& ident , double socketTim eout, DBClientBase* conn ); DBClientBase* _finishCreate( const string& ident , double socketTim eout, DBClientBase* conn );
struct PoolKey { struct PoolKey {
PoolKey( string i , double t ) : ident( i ) , timeout( t ) {} PoolKey( const std::string& i , double t ) : ident( i ) , timeo ut( t ) {}
string ident; string ident;
double timeout; double timeout;
}; };
struct poolKeyCompare { struct poolKeyCompare {
bool operator()( const PoolKey& a , const PoolKey& b ) const; bool operator()( const PoolKey& a , const PoolKey& b ) const;
}; };
typedef map<PoolKey,PoolForHost,poolKeyCompare> PoolMap; // servern ame -> pool typedef map<PoolKey,PoolForHost,poolKeyCompare> PoolMap; // servern ame -> pool
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 constants.h   constants.h 
// constants.h // constants.h
/* Copyright 2012 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once #pragma once
namespace mongo { namespace mongo {
/* query results include a 32 result flag word consisting of these bits */ /* query results include a 32 result flag word consisting of these bits */
enum ResultFlagType { enum ResultFlagType {
/* returned, with zero results, when getMore is called but the curs or id /* returned, with zero results, when getMore is called but the curs or id
is not valid at the server. */ is not valid at the server. */
ResultFlag_CursorNotFound = 1, ResultFlag_CursorNotFound = 1,
/* { $err : ... } is being returned */ /* { $err : ... } is being returned */
ResultFlag_ErrSet = 2, ResultFlag_ErrSet = 2,
/* Have to update config from the server, usually $err is also set */ /* Have to update config from the server, usually $err is also set */
ResultFlag_ShardConfigStale = 4, ResultFlag_ShardConfigStale = 4,
/* for backward compatability: this let's us know the server suppor ts /* for backward compatibility: this let's us know the server suppor ts
the QueryOption_AwaitData option. if it doesn't, a repl slave cl ient should sleep the QueryOption_AwaitData option. if it doesn't, a repl slave cl ient should sleep
a little between getMore's. a little between getMore's.
*/ */
ResultFlag_AwaitCapable = 8 ResultFlag_AwaitCapable = 8
}; };
} }
 End of changes. 2 change blocks. 
1 lines changed or deleted 17 lines changed or added


 core.h   core.h 
skipping to change at line 23 skipping to change at line 23
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include "mongo/pch.h" #include "mongo/pch.h"
#include "../jsobj.h" #include "../jsobj.h"
#include "shapes.h"
#include <cmath> #include <cmath>
#ifndef M_PI #ifndef M_PI
# define M_PI 3.14159265358979323846 # define M_PI 3.14159265358979323846
#endif #endif
namespace mongo { namespace mongo {
class GeoBitSets { class GeoBitSets {
skipping to change at line 344 skipping to change at line 343
return *this; return *this;
} }
GeoHash operator+( const char * s ) const { GeoHash operator+( const char * s ) const {
GeoHash n = *this; GeoHash n = *this;
n+=s; n+=s;
return n; return n;
} }
GeoHash operator+( string s ) const { GeoHash operator+( const std::string& s ) const {
return operator+( s.c_str() ); return operator+( s.c_str() );
} }
void _fix() { void _fix() {
static long long FULL = 0xFFFFFFFFFFFFFFFFLL; static long long FULL = 0xFFFFFFFFFFFFFFFFLL;
long long mask = FULL << ( 64 - ( _bits * 2 ) ); long long mask = FULL << ( 64 - ( _bits * 2 ) );
_hash &= mask; _hash &= mask;
} }
void append( BSONObjBuilder& b , const char * name ) const { void append( BSONObjBuilder& b , const char * name ) const {
skipping to change at line 404 skipping to change at line 403
} }
class GeoConvert { class GeoConvert {
public: public:
virtual ~GeoConvert() {} virtual ~GeoConvert() {}
virtual void unhash( const GeoHash& h , double& x , double& y ) con st = 0; virtual void unhash( const GeoHash& h , double& x , double& y ) con st = 0;
virtual GeoHash hash( double x , double y ) const = 0; virtual GeoHash hash( double x , double y ) const = 0;
}; };
class Point {
public:
Point( const GeoConvert * g , const GeoHash& hash ) {
g->unhash( hash , _x , _y );
}
explicit Point( const BSONElement& e ) {
BSONObjIterator i(e.Obj());
_x = i.next().number();
_y = i.next().number();
}
explicit Point( const BSONObj& o ) {
BSONObjIterator i(o);
_x = i.next().number();
_y = i.next().number();
}
Point( double x , double y )
: _x( x ) , _y( y ) {
}
Point() : _x(0),_y(0) {
}
GeoHash hash( const GeoConvert * g ) {
return g->hash( _x , _y );
}
double distance( const Point& p ) const {
double a = _x - p._x;
double b = _y - p._y;
// Avoid numerical error if possible...
if( a == 0 ) return abs( _y - p._y );
if( b == 0 ) return abs( _x - p._x );
return sqrt( ( a * a ) + ( b * b ) );
}
/**
* Distance method that compares x or y coords when other direction
is zero,
* avoids numerical error when distances are very close to radius b
ut axis-aligned.
*
* An example of the problem is:
* (52.0 - 51.9999) - 0.0001 = 3.31965e-15 and 52.0 - 51.9999 > 0.0
001 in double arithmetic
* but:
* 51.9999 + 0.0001 <= 52.0
*
* This avoids some (but not all!) suprising results in $center que
ries where points are
* ( radius + center.x, center.y ) or vice-versa.
*/
bool distanceWithin( const Point& p, double radius ) const {
double a = _x - p._x;
double b = _y - p._y;
if( a == 0 ) {
//
// Note: For some, unknown reason, when a 32-bit g++ optim
izes this call, the sum is
// calculated imprecisely. We need to force the compiler t
o always evaluate it correctly,
// hence the weirdness.
//
// On some 32-bit linux machines, removing the volatile key
word or calculating the sum inline
// will make certain geo tests fail. Of course this check
will force volatile for all 32-bit systems,
// not just affected systems.
if( sizeof(void*) <= 4 ){
volatile double sum = _y > p._y ? p._y + radius : _y +
radius;
return _y > p._y ? sum >= _y : sum >= p._y;
}
else {
// Original math, correct for most systems
return _y > p._y ? p._y + radius >= _y : _y + radius >=
p._y;
}
}
if( b == 0 ) {
if( sizeof(void*) <= 4 ){
volatile double sum = _x > p._x ? p._x + radius : _x +
radius;
return _x > p._x ? sum >= _x : sum >= p._x;
}
else {
return _x > p._x ? p._x + radius >= _x : _x + radius >=
p._x;
}
}
return sqrt( ( a * a ) + ( b * b ) ) <= radius;
}
string toString() const {
StringBuilder buf;
buf << "(" << _x << "," << _y << ")";
return buf.str();
}
double _x;
double _y;
};
extern const double EARTH_RADIUS_KM; extern const double EARTH_RADIUS_KM;
extern const double EARTH_RADIUS_MILES; extern const double EARTH_RADIUS_MILES;
// Technically lat/long bounds, not really tied to earth radius. // Technically lat/long bounds, not really tied to earth radius.
inline void checkEarthBounds( Point p ) { inline void checkEarthBounds( Point p ) {
uassert( 14808, str::stream() << "point " << p.toString() << " must be in earth-like bounds of long : [-180, 180], lat : [-90, 90] ", uassert( 14808, str::stream() << "point " << p.toString() << " must be in earth-like bounds of long : [-180, 180], lat : [-90, 90] ",
p._x >= -180 && p._x <= 180 && p._y >= -90 && p._y <= 90 ) ; p._x >= -180 && p._x <= 180 && p._y >= -90 && p._y <= 90 ) ;
} }
inline double deg2rad(double deg) { return deg * (M_PI/180); } inline double deg2rad(double deg) { return deg * (M_PI/180); }
 End of changes. 3 change blocks. 
2 lines changed or deleted 112 lines changed or added


 curop-inl.h   curop-inl.h 
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "curop.h" #include "curop.h"
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 curop.h   curop.h 
skipping to change at line 21 skipping to change at line 21
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Lice nse * You should have received a copy of the GNU Affero General Public Lice nse
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include "namespace-inl.h" #include <vector>
#include "client.h"
#include "../bson/util/atomic_int.h" #include "mongo/bson/util/atomic_int.h"
#include "../util/concurrency/spin_lock.h" #include "mongo/db/client.h"
#include "../util/time_support.h" #include "mongo/db/namespace-inl.h"
#include "../util/net/hostandport.h" #include "mongo/util/concurrency/spin_lock.h"
#include "../util/progress_meter.h" #include "mongo/util/net/hostandport.h"
#include "mongo/util/progress_meter.h"
#include "mongo/util/time_support.h"
namespace mongo { namespace mongo {
class CurOp; class CurOp;
/* lifespan is different than CurOp because of recursives with DBDirect Client */ /* lifespan is different than CurOp because of recursives with DBDirect Client */
class OpDebug { class OpDebug {
public: public:
OpDebug() : ns(""){ reset(); } OpDebug() : ns(""){ reset(); }
void reset(); void reset();
string report( const CurOp& curop ) const; string report( const CurOp& curop ) const;
void append( const CurOp& curop, BSONObjBuilder& b ) const;
/**
* Appends stored data and information from curop to the builder.
*
* @param curop information about the current operation which will
be
* use to append data to the builder.
* @param builder the BSON builder to use for appending data. Data
can
* still be appended even if this method returns false.
* @param maxSize the maximum allowed combined size for the query o
bject
* and update object
*
* @return false if the sum of the sizes for the query object and u
pdate
* object exceeded maxSize
*/
bool append(const CurOp& curop, BSONObjBuilder& builder, size_t max
Size) const;
// ------------------- // -------------------
StringBuilder extra; // weird things we need to fix later StringBuilder extra; // weird things we need to fix later
// basic options // basic options
int op; int op;
bool iscommand; bool iscommand;
Namespace ns; Namespace ns;
BSONObj query; BSONObj query;
skipping to change at line 103 skipping to change at line 119
} }
void reset( int sz = 0 ) { void reset( int sz = 0 ) {
_lock.lock(); _lock.lock();
_reset( sz ); _reset( sz );
_lock.unlock(); _lock.unlock();
} }
void set( const BSONObj& o ) { void set( const BSONObj& o ) {
scoped_spinlock lk(_lock); scoped_spinlock lk(_lock);
size_t sz = o.objsize(); int sz = o.objsize();
if ( sz > sizeof(_buf) ) { if ( sz > (int) sizeof(_buf) ) {
_reset(TOO_BIG_SENTINEL); _reset(TOO_BIG_SENTINEL);
} }
else { else {
memcpy(_buf, o.objdata(), sz ); memcpy(_buf, o.objdata(), sz );
} }
} }
int size() const { return *_size; } int size() const { return *_size; }
bool have() const { return size() > 0; } bool have() const { return size() > 0; }
skipping to change at line 154 skipping to change at line 170
/* Current operation (for the current Client). /* Current operation (for the current Client).
an embedded member of Client class, and typically used from within t he mutex there. an embedded member of Client class, and typically used from within t he mutex there.
*/ */
class CurOp : boost::noncopyable { class CurOp : boost::noncopyable {
public: public:
CurOp( Client * client , CurOp * wrapped = 0 ); CurOp( Client * client , CurOp * wrapped = 0 );
~CurOp(); ~CurOp();
bool haveQuery() const { return _query.have(); } bool haveQuery() const { return _query.have(); }
BSONObj query() { return _query.get(); } BSONObj query() const { return _query.get(); }
void appendQuery( BSONObjBuilder& b , const StringData& name ) cons t { _query.append( b , name ); } void appendQuery( BSONObjBuilder& b , const StringData& name ) cons t { _query.append( b , name ); }
void ensureStarted(); void ensureStarted();
bool isStarted() const { return _start > 0; } bool isStarted() const { return _start > 0; }
void enter( Client::Context * context ); void enter( Client::Context * context );
void leave( Client::Context * context ); void leave( Client::Context * context );
void reset(); void reset();
void reset( const HostAndPort& remote, int op ); void reset( const HostAndPort& remote, int op );
void markCommand() { _command = true; } void markCommand() { _command = true; }
OpDebug& debug() { return _debug; } OpDebug& debug() { return _debug; }
skipping to change at line 209 skipping to change at line 225
int elapsedSeconds() { return elapsedMillis() / 1000; } int elapsedSeconds() { return elapsedMillis() / 1000; }
void setQuery(const BSONObj& query) { _query.set( query ); } void setQuery(const BSONObj& query) { _query.set( query ); }
Client * getClient() const { return _client; } Client * getClient() const { return _client; }
BSONObj info(); BSONObj info();
BSONObj infoNoauth(); BSONObj infoNoauth();
string getRemoteString( bool includePort = true ) { return _remote. toString(includePort); } string getRemoteString( bool includePort = true ) { return _remote. toString(includePort); }
ProgressMeter& setMessage( const char * msg , unsigned long long pr ogressMeterTotal = 0 , int secondsBetween = 3 ); ProgressMeter& setMessage( const char * msg , unsigned long long pr ogressMeterTotal = 0 , int secondsBetween = 3 );
string getMessage() const { return _message.toString(); } string getMessage() const { return _message.toString(); }
ProgressMeter& getProgressMeter() { return _progressMeter; } ProgressMeter& getProgressMeter() { return _progressMeter; }
CurOp *parent() const { return _wrapped; } CurOp *parent() const { return _wrapped; }
void kill() { _killed = true; } void kill(bool* pNotifyFlag = NULL);
bool killed() const { return _killed; } bool killPending() const { return _killPending.load(); }
void yielded() { _numYields++; } void yielded() { _numYields++; }
int numYields() const { return _numYields; } int numYields() const { return _numYields; }
void suppressFromCurop() { _suppressFromCurop = true; } void suppressFromCurop() { _suppressFromCurop = true; }
long long getExpectedLatencyMs() const { return _expectedLatencyMs; } long long getExpectedLatencyMs() const { return _expectedLatencyMs; }
void setExpectedLatencyMs( long long latency ) { _expectedLatencyMs = latency; } void setExpectedLatencyMs( long long latency ) { _expectedLatencyMs = latency; }
void recordGlobalTime( long long micros ) const; void recordGlobalTime( long long micros ) const;
const LockStat& lockStat() const { return _lockStat; } const LockStat& lockStat() const { return _lockStat; }
LockStat& lockStat() { return _lockStat; } LockStat& lockStat() { return _lockStat; }
void setKillWaiterFlags();
private: private:
friend class Client; friend class Client;
void _reset(); void _reset();
static AtomicUInt _nextOpNum; static AtomicUInt _nextOpNum;
Client * _client; Client * _client;
CurOp * _wrapped; CurOp * _wrapped;
unsigned long long _start; unsigned long long _start;
unsigned long long _end; unsigned long long _end;
bool _active; bool _active;
skipping to change at line 243 skipping to change at line 261
int _op; int _op;
bool _command; bool _command;
int _dbprofile; // 0=off, 1=slow, 2=all int _dbprofile; // 0=off, 1=slow, 2=all
AtomicUInt _opNum; // todo: simple being "unsigned" m ay make more sense here AtomicUInt _opNum; // todo: simple being "unsigned" m ay make more sense here
char _ns[Namespace::MaxNsLen+2]; char _ns[Namespace::MaxNsLen+2];
HostAndPort _remote; // CAREFUL here with thread safety HostAndPort _remote; // CAREFUL here with thread safety
CachedBSONObj _query; // CachedBSONObj is thread safe CachedBSONObj _query; // CachedBSONObj is thread safe
OpDebug _debug; OpDebug _debug;
ThreadSafeString _message; ThreadSafeString _message;
ProgressMeter _progressMeter; ProgressMeter _progressMeter;
volatile bool _killed; AtomicInt32 _killPending;
int _numYields; int _numYields;
LockStat _lockStat; LockStat _lockStat;
// _notifyList is protected by the global killCurrentOp's mtx.
std::vector<bool*> _notifyList;
// this is how much "extra" time a query might take // this is how much "extra" time a query might take
// a writebacklisten for example will block for 30s // a writebacklisten for example will block for 30s
// so this should be 30000 in that case // so this should be 30000 in that case
long long _expectedLatencyMs; long long _expectedLatencyMs;
}; };
/* _globalKill: we are shutting down
otherwise kill attribute set on specified CurOp
this class does not handle races between interruptJs and the checkFo
rInterrupt functions - those must be
handled by the client of this class
*/
extern class KillCurrentOp {
public:
void killAll();
void kill(AtomicUInt i);
/** @return true if global interrupt and should terminate the opera
tion */
bool globalInterruptCheck() const { return _globalKill; }
/**
* @param heedMutex if true and have a write lock, won't kill op si
nce it might be unsafe
*/
void checkForInterrupt( bool heedMutex = true );
/** @return "" if not interrupted. otherwise, you should stop. */
const char *checkForInterruptNoAssert();
private:
void interruptJs( AtomicUInt *op );
volatile bool _globalKill;
} killCurrentOp;
} }
 End of changes. 10 change blocks. 
45 lines changed or deleted 39 lines changed or added


 cursor.h   cursor.h 
skipping to change at line 189 skipping to change at line 189
// The implementation may return different matchers depending on th e // The implementation may return different matchers depending on th e
// position of the cursor. If matcher() is nonzero at the start, // position of the cursor. If matcher() is nonzero at the start,
// matcher() should be checked each time advance() is called. // matcher() should be checked each time advance() is called.
// Implementations which generate their own matcher should return t his // Implementations which generate their own matcher should return t his
// to avoid a matcher being set manually. // to avoid a matcher being set manually.
// Note that the return values differ subtly here // Note that the return values differ subtly here
// Used when we want fast matcher lookup // Used when we want fast matcher lookup
virtual CoveredIndexMatcher *matcher() const { return 0; } virtual CoveredIndexMatcher *matcher() const { return 0; }
// Used when we need to share this matcher with someone else
virtual shared_ptr< CoveredIndexMatcher > matcherPtr() const { retu
rn shared_ptr< CoveredIndexMatcher >(); }
virtual bool currentMatches( MatchDetails *details = 0 ) { virtual bool currentMatches( MatchDetails *details = 0 ) {
return !matcher() || matcher()->matchesCurrent( this, details ) ; return !matcher() || matcher()->matchesCurrent( this, details ) ;
} }
// A convenience function for setting the value of matcher() manual ly // A convenience function for setting the value of matcher() manual ly
// so it may be accessed later. Implementations which must generat e // so it may be accessed later. Implementations which must generat e
// their own matcher() should assert here. // their own matcher() should assert here.
virtual void setMatcher( shared_ptr< CoveredIndexMatcher > matcher ) { virtual void setMatcher( shared_ptr< CoveredIndexMatcher > matcher ) {
massert( 13285, "manual matcher config not allowed", false ); massert( 13285, "manual matcher config not allowed", false );
skipping to change at line 267 skipping to change at line 265
if ( !curr.isNull() || !last.isNull() ) if ( !curr.isNull() || !last.isNull() )
tailable_ = true; tailable_ = true;
} }
virtual bool tailable() { return tailable_; } virtual bool tailable() { return tailable_; }
virtual bool getsetdup(DiskLoc loc) { return false; } virtual bool getsetdup(DiskLoc loc) { return false; }
virtual bool isMultiKey() const { return false; } virtual bool isMultiKey() const { return false; }
virtual bool modifiedKeys() const { return false; } virtual bool modifiedKeys() const { return false; }
virtual bool supportGetMore() { return true; } virtual bool supportGetMore() { return true; }
virtual bool supportYields() { return true; } virtual bool supportYields() { return true; }
virtual CoveredIndexMatcher *matcher() const { return _matcher.get( ); } virtual CoveredIndexMatcher *matcher() const { return _matcher.get( ); }
virtual shared_ptr< CoveredIndexMatcher > matcherPtr() const { retu rn _matcher; }
virtual void setMatcher( shared_ptr< CoveredIndexMatcher > matcher ) { _matcher = matcher; } virtual void setMatcher( shared_ptr< CoveredIndexMatcher > matcher ) { _matcher = matcher; }
virtual const Projection::KeyOnly *keyFieldsOnly() const { return _ keyFieldsOnly.get(); } virtual const Projection::KeyOnly *keyFieldsOnly() const { return _ keyFieldsOnly.get(); }
virtual void setKeyFieldsOnly( const shared_ptr<Projection::KeyOnly > &keyFieldsOnly ) { virtual void setKeyFieldsOnly( const shared_ptr<Projection::KeyOnly > &keyFieldsOnly ) {
_keyFieldsOnly = keyFieldsOnly; _keyFieldsOnly = keyFieldsOnly;
} }
virtual long long nscanned() { return _nscanned; } virtual long long nscanned() { return _nscanned; }
protected: protected:
DiskLoc curr, last; DiskLoc curr, last;
const AdvanceStrategy *s; const AdvanceStrategy *s;
 End of changes. 2 change blocks. 
4 lines changed or deleted 0 lines changed or added


 d_chunk_manager.h   d_chunk_manager.h 
skipping to change at line 65 skipping to change at line 65
* @param ns namespace for the collections whose chunks we're inter ested * @param ns namespace for the collections whose chunks we're inter ested
* @param shardName name of the shard that this chunk matcher shoul d track * @param shardName name of the shard that this chunk matcher shoul d track
* *
* This constructor throws if collection is dropped/malformed and o n connectivity errors * This constructor throws if collection is dropped/malformed and o n connectivity errors
*/ */
static ShardChunkManager* make( const string& configServer , const string& ns , const string& shardName, ShardChunkManagerPtr oldManager = Sha rdChunkManagerPtr() ); static ShardChunkManager* make( const string& configServer , const string& ns , const string& shardName, ShardChunkManagerPtr oldManager = Sha rdChunkManagerPtr() );
/** /**
* Same as the regular constructor but used in unittest (no access to configDB required). * Same as the regular constructor but used in unittest (no access to configDB required).
* *
* @param collectionDoc simulates config.collection's entry for one colleciton * @param collectionDoc simulates config.collection's entry for one collection
* @param chunksDocs simulates config.chunks' entries for one colle ction's shard * @param chunksDocs simulates config.chunks' entries for one colle ction's shard
*/ */
ShardChunkManager( const BSONObj& collectionDoc , const BSONArray& chunksDoc ); ShardChunkManager( const BSONObj& collectionDoc , const BSONArray& chunksDoc );
~ShardChunkManager() {} ~ShardChunkManager() {}
/** /**
* Generates a new manager based on 'this's state minus a given chu nk. * Generates a new manager based on 'this's state minus a given chu nk.
* *
* @param min max chunk boundaries for the chunk to subtract * @param min max chunk boundaries for the chunk to subtract
skipping to change at line 108 skipping to change at line 108
*/ */
ShardChunkManager* cloneSplit( const BSONObj& min , const BSONObj& max , const vector<BSONObj>& splitKeys , ShardChunkManager* cloneSplit( const BSONObj& min , const BSONObj& max , const vector<BSONObj>& splitKeys ,
const ShardChunkVersion& version ); const ShardChunkVersion& version );
/** /**
* Checks whether a document belongs to this shard. * Checks whether a document belongs to this shard.
* *
* @param obj document containing sharding keys (and, optionally, o ther attributes) * @param obj document containing sharding keys (and, optionally, o ther attributes)
* @return true if shards hold the object * @return true if shards hold the object
*/ */
bool belongsToMe( const BSONObj& obj ) const; bool belongsToMe( const BSONObj& doc ) const;
/** /**
* Checks whether a document belongs to this shard. * Checks whether the document currently pointed to by this cursor
belongs to this shard.
* This version of the function will use a covered index if there i
s one in the cursor.
* *
* @param obj document containing sharding keys (and, optionally, o ther attributes) * @param cc cursor pointing to an object
* @return true if shards hold the object * @return true if shards hold the object
*/ */
bool belongsToMe( ClientCursor* cc ) const; bool belongsToMe( ClientCursor* cc ) const;
/** /**
* Given a chunk's min key (or empty doc), gets the boundary of the chunk following that one (the first). * Given a chunk's min key (or empty doc), gets the boundary of the chunk following that one (the first).
* *
* @param lookupKey is the min key for a previously obtained chunk or the empty document * @param lookupKey is the min key for a previously obtained chunk or the empty document
* @param foundMin IN/OUT min for chunk following the one starting at lookupKey * @param foundMin IN/OUT min for chunk following the one starting at lookupKey
* @param foundMax IN/OUT max for the above chunk * @param foundMax IN/OUT max for the above chunk
skipping to change at line 140 skipping to change at line 141
ShardChunkVersion getVersion() const { return _version; } ShardChunkVersion getVersion() const { return _version; }
ShardChunkVersion getCollVersion() const { return _collVersion; } ShardChunkVersion getCollVersion() const { return _collVersion; }
BSONObj getKey() const { return _key.getOwned(); } BSONObj getKey() const { return _key.getOwned(); }
unsigned getNumChunks() const { return _chunksMap.size(); } unsigned getNumChunks() const { return _chunksMap.size(); }
string toString() const; string toString() const;
private: private:
void _init( const string& configServer , const string& ns , const s tring& shardName, ShardChunkManagerPtr oldManager = ShardChunkManagerPtr() ); void _init( const string& configServer , const string& ns , const s tring& shardName, ShardChunkManagerPtr oldManager = ShardChunkManagerPtr() );
/** /**
* @same as belongsToMe to but key has to be the shard key * @same as belongsToMe but point is the extracted shard key
*/ */
bool _belongsToMe( const BSONObj& key ) const; bool _belongsToMe( const BSONObj& point ) const;
ShardChunkVersion _collVersion; ShardChunkVersion _collVersion;
// highest ShardChunkVersion for which this ShardChunkManager's inf ormation is accurate // highest ShardChunkVersion for which this ShardChunkManager's inf ormation is accurate
ShardChunkVersion _version; ShardChunkVersion _version;
// key pattern for chunks under this range // key pattern for chunks under this range
BSONObj _key; BSONObj _key;
// a map from a min key into the chunk's (or range's) max boundary // a map from a min key into the chunk's (or range's) max boundary
typedef map< BSONObj, BSONObj , BSONObjCmp > RangeMap; typedef map< BSONObj, BSONObj , BSONObjCmp > RangeMap;
 End of changes. 6 change blocks. 
6 lines changed or deleted 9 lines changed or added


 d_concurrency.h   d_concurrency.h 
skipping to change at line 24 skipping to change at line 24
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
// only used by mongod, thus the name ('d') // only used by mongod, thus the name ('d')
// (also used by dbtests test binary, which is running mongod test code) // (also used by dbtests test binary, which is running mongod test code)
#pragma once #pragma once
#include "mongo/bson/stringdata.h" #include "mongo/base/string_data.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/lockstat.h" #include "mongo/db/lockstat.h"
#include "mongo/util/concurrency/mutex.h" #include "mongo/util/concurrency/mutex.h"
#include "mongo/util/concurrency/rwlock.h" #include "mongo/util/concurrency/rwlock.h"
namespace mongo { namespace mongo {
class WrapperForRWLock; class WrapperForRWLock;
class LockState; class LockState;
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 d_globals.h   d_globals.h 
// @file d_globals.h // @file d_globals.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// //
// these are global variables used in mongod ("d"). also used in test bina ry as that is effectively a variation on mongod code. // these are global variables used in mongod ("d"). also used in test bina ry as that is effectively a variation on mongod code.
// that is, these are not in mongos. // that is, these are not in mongos.
// //
#pragma once #pragma once
namespace mongo { namespace mongo {
class RWLockRecursive; class RWLockRecursive;
 End of changes. 1 change blocks. 
0 lines changed or deleted 19 lines changed or added


 d_logic.h   d_logic.h 
skipping to change at line 47 skipping to change at line 47
// -------------- // --------------
class ShardingState { class ShardingState {
public: public:
ShardingState(); ShardingState();
bool enabled() const { return _enabled; } bool enabled() const { return _enabled; }
const string& getConfigServer() const { return _configServer; } const string& getConfigServer() const { return _configServer; }
void enable( const string& server ); void enable( const string& server );
// Initialize sharding state and begin authenticating outgoing conn
ections and handling
// shard versions. If this is not run before sharded operations oc
cur auth will not work
// and versions will not be tracked.
static void initialize(const string& server);
void gotShardName( const string& name ); void gotShardName( const string& name );
void gotShardHost( string host ); void gotShardHost( string host );
string getShardName() { return _shardName; } string getShardName() { return _shardName; }
string getShardHost() { return _shardHost; } string getShardHost() { return _shardHost; }
/** Reverts back to a state where this mongod is not sharded. */ /** Reverts back to a state where this mongod is not sharded. */
void resetShardingState(); void resetShardingState();
// versioning support // versioning support
skipping to change at line 89 skipping to change at line 84
* @param ns the collection to be dropped * @param ns the collection to be dropped
*/ */
void resetVersion( const string& ns ); void resetVersion( const string& ns );
/** /**
* Requests to access a collection at a certain version. If the col lection's manager is not at that version it * Requests to access a collection at a certain version. If the col lection's manager is not at that version it
* will try to update itself to the newest version. The request is only granted if the version is the current or * will try to update itself to the newest version. The request is only granted if the version is the current or
* the newest one. * the newest one.
* *
* @param ns collection to be accessed * @param ns collection to be accessed
* @param version (IN) the client belive this collection is on and (OUT) the version the manager is actually in * @param version (IN) the client believe this collection is on and (OUT) the version the manager is actually in
* @return true if the access can be allowed at the provided versio n * @return true if the access can be allowed at the provided versio n
*/ */
bool trySetVersion( const string& ns , ConfigVersion& version ); bool trySetVersion( const string& ns , ConfigVersion& version );
void appendInfo( BSONObjBuilder& b ); void appendInfo( BSONObjBuilder& b );
// querying support // querying support
bool needShardChunkManager( const string& ns ) const; bool needShardChunkManager( const string& ns ) const;
ShardChunkManagerPtr getShardChunkManager( const string& ns ); ShardChunkManagerPtr getShardChunkManager( const string& ns );
skipping to change at line 171 skipping to change at line 166
// map from a namespace into the ensemble of chunk ranges that are stored in this mongod // map from a namespace into the ensemble of chunk ranges that are stored in this mongod
// a ShardChunkManager carries all state we need for a collection a t this shard, including its version information // a ShardChunkManager carries all state we need for a collection a t this shard, including its version information
typedef map<string,ShardChunkManagerPtr> ChunkManagersMap; typedef map<string,ShardChunkManagerPtr> ChunkManagersMap;
ChunkManagersMap _chunks; ChunkManagersMap _chunks;
}; };
extern ShardingState shardingState; extern ShardingState shardingState;
/** /**
* one per connection from mongos * one per connection from mongos
* holds version state for each namesapce * holds version state for each namespace
*/ */
class ShardedConnectionInfo { class ShardedConnectionInfo {
public: public:
ShardedConnectionInfo(); ShardedConnectionInfo();
const OID& getID() const { return _id; } const OID& getID() const { return _id; }
bool hasID() const { return _id.isSet(); } bool hasID() const { return _id.isSet(); }
void setID( const OID& id ); void setID( const OID& id );
const ConfigVersion getVersion( const string& ns ) const; const ConfigVersion getVersion( const string& ns ) const;
 End of changes. 3 change blocks. 
9 lines changed or deleted 2 lines changed or added


 d_writeback.h   d_writeback.h 
skipping to change at line 43 skipping to change at line 43
* The class is thread safe. * The class is thread safe.
*/ */
class WriteBackManager { class WriteBackManager {
public: public:
class QueueInfo : boost::noncopyable { class QueueInfo : boost::noncopyable {
public: public:
QueueInfo(){} QueueInfo(){}
BlockingQueue<BSONObj> queue; BlockingQueue<BSONObj> queue;
long long lastCall; // this is ellapsed millis since startup long long lastCall; // this is elapsed millis since startup
}; };
// a map from mongos's serverIDs to queues of "rejected" operations // a map from mongos's serverIDs to queues of "rejected" operations
// an operation is rejected if it targets data that does not live o n this shard anymore // an operation is rejected if it targets data that does not live o n this shard anymore
typedef map<string,shared_ptr<QueueInfo> > WriteBackQueuesMap; typedef map<string,shared_ptr<QueueInfo> > WriteBackQueuesMap;
public: public:
WriteBackManager(); WriteBackManager();
~WriteBackManager(); ~WriteBackManager();
/* /*
* @param remote server ID this operation came from * @param remote server ID this operation came from
* @param op the operation itself * @param op the operation itself
* *
* Enqueues operation 'op' in server 'remote's queue. The operation will be written back to * Enqueues operation 'op' in server 'remote's queue. The operation will be written back to
* remote at a later stage. * remote at a later stage.
*
* @return the writebackId generated
*/ */
OID queueWriteBack( const string& remote , BSONObjBuilder& opBuilde r ); void queueWriteBack( const string& remote , const BSONObj& op );
/* /*
* @param remote server ID * @param remote server ID
* @return the queue for operations that came from 'remote' * @return the queue for operations that came from 'remote'
* *
* Gets access to server 'remote's queue, which is synchronized. * Gets access to server 'remote's queue, which is synchronized.
*/ */
shared_ptr<QueueInfo> getWritebackQueue( const string& remote ); shared_ptr<QueueInfo> getWritebackQueue( const string& remote );
/* /*
skipping to change at line 91 skipping to change at line 89
void appendStats( BSONObjBuilder& b ) const; void appendStats( BSONObjBuilder& b ) const;
/** /**
* removes queues that have been idle * removes queues that have been idle
* @return if something was removed * @return if something was removed
*/ */
bool cleanupOldQueues(); bool cleanupOldQueues();
private: private:
// '_writebackQueueLock' protects only the map itself, since each q ueue is syncrhonized. // '_writebackQueueLock' protects only the map itself, since each q ueue is synchronized.
mutable mongo::mutex _writebackQueueLock; mutable mongo::mutex _writebackQueueLock;
WriteBackQueuesMap _writebackQueues; WriteBackQueuesMap _writebackQueues;
class Cleaner : public PeriodicTask { class Cleaner : public PeriodicTask {
public: public:
virtual string taskName() const { return "WriteBackManager::cle aner"; } virtual string taskName() const { return "WriteBackManager::cle aner"; }
virtual void taskDoWork(); virtual void taskDoWork();
}; };
Cleaner _cleaner; Cleaner _cleaner;
 End of changes. 4 change blocks. 
5 lines changed or deleted 3 lines changed or added


 databaseholder.h   databaseholder.h 
// @file databaseholder.h // @file databaseholder.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "mongo/db/database.h" #include "mongo/db/database.h"
#include "mongo/db/namespacestring.h" #include "mongo/db/namespacestring.h"
namespace mongo { namespace mongo {
/** /**
* path + dbname -> Database * path + dbname -> Database
*/ */
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 dbclient_rs.h   dbclient_rs.h 
skipping to change at line 41 skipping to change at line 41
class ReplicaSetMonitor; class ReplicaSetMonitor;
class TagSet; class TagSet;
typedef shared_ptr<ReplicaSetMonitor> ReplicaSetMonitorPtr; typedef shared_ptr<ReplicaSetMonitor> ReplicaSetMonitorPtr;
typedef pair<set<string>,set<int> > NodeDiff; typedef pair<set<string>,set<int> > NodeDiff;
/** /**
* manages state about a replica set for client * manages state about a replica set for client
* keeps tabs on whose master and what slaves are up * keeps tabs on whose master and what slaves are up
* can hand a slave to someone for SLAVE_OK * can hand a slave to someone for SLAVE_OK
* one instace per process per replica set * one instance per process per replica set
* TODO: we might be able to use a regular Node * to avoid _lock * TODO: we might be able to use a regular Node * to avoid _lock
*/ */
class ReplicaSetMonitor { class ReplicaSetMonitor {
public: public:
typedef boost::function1<void,const ReplicaSetMonitor*> ConfigChang eHook; typedef boost::function1<void,const ReplicaSetMonitor*> ConfigChang eHook;
/** /**
* Data structure for keeping track of the states of individual rep lica * Data structure for keeping track of the states of individual rep lica
* members. This class is not thread-safe so proper measures should be taken * members. This class is not thread-safe so proper measures should be taken
skipping to change at line 150 skipping to change at line 150
* @param preference the read mode to use * @param preference the read mode to use
* @param tags the tags used for filtering nodes * @param tags the tags used for filtering nodes
* @param localThresholdMillis the exclusive upper bound of ping ti me to be * @param localThresholdMillis the exclusive upper bound of ping ti me to be
* considered as a local node. Local nodes are favored over non -local * considered as a local node. Local nodes are favored over non -local
* nodes if multiple nodes matches the other criteria. * nodes if multiple nodes matches the other criteria.
* @param lastHost the host used in the last successful request. Th is is used for * @param lastHost the host used in the last successful request. Th is is used for
* selecting a different node as much as possible, by doing a s imple round * selecting a different node as much as possible, by doing a s imple round
* robin, starting from the node next to this lastHost. This wi ll be overwritten * robin, starting from the node next to this lastHost. This wi ll be overwritten
* with the newly chosen host if not empty, not primary and whe n preference * with the newly chosen host if not empty, not primary and whe n preference
* is not Nearest. * is not Nearest.
* @param isPrimarySelected out parameter that is set to true if th
e returned host
* is a primary. Cannot be NULL and valid only if returned host
is not empty.
* *
* @return the host object of the node selected. If none of the nod es are * @return the host object of the node selected. If none of the nod es are
* eligible, returns an empty host. * eligible, returns an empty host.
*/ */
static HostAndPort selectNode(const std::vector<Node>& nodes, static HostAndPort selectNode(const std::vector<Node>& nodes,
ReadPreference preference, ReadPreference preference,
TagSet* tags, TagSet* tags,
int localThresholdMillis, int localThresholdMillis,
HostAndPort* lastHost, HostAndPort* lastHost);
bool* isPrimarySelected);
/** /**
* Selects the right node given the nodes to pick from and the pref erence. This * Selects the right node given the nodes to pick from and the pref erence. This
* will also attempt to refresh the local view of the replica set c onfiguration * will also attempt to refresh the local view of the replica set c onfiguration
* if the primary node needs to be returned but is not currently av ailable (except * if the primary node needs to be returned but is not currently av ailable (except
* for ReadPrefrence_Nearest). * for ReadPrefrence_Nearest).
* *
* @param preference the read mode to use. * @param preference the read mode to use
* @param tags the tags used for filtering nodes. * @param tags the tags used for filtering nodes
* @param isPrimarySelected out parameter that is set to true if th
e returned host
* is a primary. Cannot be NULL and valid only if returned host
is not empty.
* *
* @return the host object of the node selected. If none of the nod es are * @return the host object of the node selected. If none of the nod es are
* eligible, returns an empty host. * eligible, returns an empty host.
*/ */
HostAndPort selectAndCheckNode(ReadPreference preference, HostAndPort selectAndCheckNode(ReadPreference preference,
TagSet* tags, TagSet* tags);
bool* isPrimarySelected);
/** /**
* Creates a new ReplicaSetMonitor, if it doesn't already exist. * Creates a new ReplicaSetMonitor, if it doesn't already exist.
*/ */
static void createIfNeeded( const string& name , const vector<HostA ndPort>& servers ); static void createIfNeeded( const string& name , const vector<HostA ndPort>& servers );
/** /**
* gets a cached Monitor per name. If the monitor is not found and createFromSeed is false, * gets a cached Monitor per name. If the monitor is not found and createFromSeed is false,
* it will return none. If createFromSeed is true, it will try to l ook up the last known * it will return none. If createFromSeed is true, it will try to l ook up the last known
* servers list for this set and will create a new monitor using th at as the seed list. * servers list for this set and will create a new monitor using th at as the seed list.
skipping to change at line 563 skipping to change at line 557
* operation. * operation.
*/ */
static const size_t MAX_RETRY; static const size_t MAX_RETRY;
// Throws a DBException if the monitor doesn't exist and there isn' t a cached seed to use. // Throws a DBException if the monitor doesn't exist and there isn' t a cached seed to use.
ReplicaSetMonitorPtr _getMonitor() const; ReplicaSetMonitorPtr _getMonitor() const;
string _setName; string _setName;
HostAndPort _masterHost; HostAndPort _masterHost;
// Note: reason why this is a shared_ptr is because we want _lastSl scoped_ptr<DBClientConnection> _master;
aveOkConn to
// keep a reference of the _master connection when it selected a pr
imary node.
// This is because the primary connection is special in mongos - it
is the only
// connection that is versioned.
// WARNING: do not assign this variable (which will increment the i
nternal ref
// counter) to any other variable other than _lastSlaveOkConn.
boost::shared_ptr<DBClientConnection> _master;
// Last used host in a slaveOk query (can be a primary) // Last used host in a slaveOk query (can be a primary)
HostAndPort _lastSlaveOkHost; HostAndPort _lastSlaveOkHost;
// Last used connection in a slaveOk query (can be a primary) // Last used connection in a slaveOk query (can be a primary)
boost::shared_ptr<DBClientConnection> _lastSlaveOkConn; scoped_ptr<DBClientConnection> _lastSlaveOkConn;
double _so_timeout; double _so_timeout;
/** /**
* for storing authentication info * for storing authentication info
* fields are exactly for DBClientConnection::auth * fields are exactly for DBClientConnection::auth
*/ */
struct AuthInfo { struct AuthInfo {
// Default constructor provided only to make it compatible with std::map::operator[] // Default constructor provided only to make it compatible with std::map::operator[]
AuthInfo(): digestPassword(false) { } AuthInfo(): digestPassword(false) { }
 End of changes. 7 change blocks. 
27 lines changed or deleted 7 lines changed or added


 dbclientinterface.h   dbclientinterface.h 
skipping to change at line 28 skipping to change at line 28
* limitations under the License. * limitations under the License.
*/ */
#pragma once #pragma once
#include "mongo/pch.h" #include "mongo/pch.h"
#include "mongo/client/authlevel.h" #include "mongo/client/authlevel.h"
#include "mongo/client/authentication_table.h" #include "mongo/client/authentication_table.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/util/net/message.h" #include "mongo/util/net/message.h"
#include "mongo/util/net/message_port.h" #include "mongo/util/net/message_port.h"
namespace mongo { namespace mongo {
/** the query field 'options' can have these bits set: */ /** the query field 'options' can have these bits set: */
enum QueryOptions { enum QueryOptions {
/** Tailable means cursor is not closed when the last data is retri eved. rather, the cursor marks /** Tailable means cursor is not closed when the last data is retri eved. rather, the cursor marks
the final object's position. you can resume using the cursor la ter, from where it was located, the final object's position. you can resume using the cursor la ter, from where it was located,
if more data were received. Set on dbQuery and dbGetMore. if more data were received. Set on dbQuery and dbGetMore.
skipping to change at line 60 skipping to change at line 59
// findingStart mode is used to find the first operation of interes t when // findingStart mode is used to find the first operation of interes t when
// we are scanning through a repl log. For efficiency in the commo n case, // we are scanning through a repl log. For efficiency in the commo n case,
// where the first operation of interest is closer to the tail than the head, // where the first operation of interest is closer to the tail than the head,
// we start from the tail of the log and work backwards until we fi nd the // we start from the tail of the log and work backwards until we fi nd the
// first operation of interest. Then we scan forward from that fir st operation, // first operation of interest. Then we scan forward from that fir st operation,
// actually returning results to the client. During the findingSta rt phase, // actually returning results to the client. During the findingSta rt phase,
// we release the db mutex occasionally to avoid blocking the db pr ocess for // we release the db mutex occasionally to avoid blocking the db pr ocess for
// an extended period of time. // an extended period of time.
QueryOption_OplogReplay = 1 << 3, QueryOption_OplogReplay = 1 << 3,
/** The server normally times out idle cursors after an inactivy pe riod to prevent excess memory uses /** The server normally times out idle cursors after an inactivity period to prevent excess memory uses
Set this option to prevent that. Set this option to prevent that.
*/ */
QueryOption_NoCursorTimeout = 1 << 4, QueryOption_NoCursorTimeout = 1 << 4,
/** Use with QueryOption_CursorTailable. If we are at the end of t he data, block for a while rather /** Use with QueryOption_CursorTailable. If we are at the end of t he data, block for a while rather
than returning no data. After a timeout period, we do return as normal. than returning no data. After a timeout period, we do return as normal.
*/ */
QueryOption_AwaitData = 1 << 5, QueryOption_AwaitData = 1 << 5,
/** Stream the data down full blast in multiple "more" packages, on the assumption that the client /** Stream the data down full blast in multiple "more" packages, on the assumption that the client
skipping to change at line 250 skipping to change at line 249
string toString() const { return _string; } string toString() const { return _string; }
DBClientBase* connect( string& errmsg, double socketTimeout = 0 ) c onst; DBClientBase* connect( string& errmsg, double socketTimeout = 0 ) c onst;
string getSetName() const { return _setName; } string getSetName() const { return _setName; }
vector<HostAndPort> getServers() const { return _servers; } vector<HostAndPort> getServers() const { return _servers; }
ConnectionType type() const { return _type; } ConnectionType type() const { return _type; }
/**
* This returns true if this and other point to the same logical en
tity.
* For single nodes, thats the same address.
* For replica sets, thats just the same replica set name.
* For pair (deprecated) or sync cluster connections, that's the sa
me hosts in any ordering.
*/
bool sameLogicalEndpoint( const ConnectionString& other ) const;
static ConnectionString parse( const string& url , string& errmsg ) ; static ConnectionString parse( const string& url , string& errmsg ) ;
static string typeToString( ConnectionType type ); static string typeToString( ConnectionType type );
// //
// Allow overriding the default connection behavior // Allow overriding the default connection behavior
// This is needed for some tests, which otherwise would fail becaus e they are unable to contact // This is needed for some tests, which otherwise would fail becaus e they are unable to contact
// the correct servers. // the correct servers.
// //
skipping to change at line 864 skipping to change at line 855
/** Create an index if it does not already exist. /** Create an index if it does not already exist.
ensureIndex calls are remembered so it is safe/fast to call thi s function many ensureIndex calls are remembered so it is safe/fast to call thi s function many
times in your code. times in your code.
@param ns collection to be indexed @param ns collection to be indexed
@param keys the "key pattern" for the index. e.g., { name : 1 } @param keys the "key pattern" for the index. e.g., { name : 1 }
@param unique if true, indicates that key uniqueness should be e nforced for this index @param unique if true, indicates that key uniqueness should be e nforced for this index
@param name if not specified, it will be created from the keys a utomatically (which is recommended) @param name if not specified, it will be created from the keys a utomatically (which is recommended)
@param cache if set to false, the index cache for the connection won't remember this call @param cache if set to false, the index cache for the connection won't remember this call
@param background build index in the background (see mongodb doc s/wiki for details) @param background build index in the background (see mongodb doc s/wiki for details)
@param v index version. leave at default value. (unit tests set this parameter.) @param v index version. leave at default value. (unit tests set this parameter.)
@param ttl. The value of how many seconds before data should be removed from a collection.
@return whether or not sent message to db. @return whether or not sent message to db.
should be true on first call, false on subsequent unless reset IndexCache was called should be true on first call, false on subsequent unless reset IndexCache was called
*/ */
virtual bool ensureIndex( const string &ns , BSONObj keys , bool un virtual bool ensureIndex( const string &ns,
ique = false, const string &name = "", BSONObj keys,
bool cache = true, bool background = fals bool unique = false,
e, int v = -1 ); const string &name = "",
bool cache = true,
bool background = false,
int v = -1,
int ttl = 0 );
/** /**
clears the index cache, so the subsequent call to ensureIndex fo r any index will go to the server clears the index cache, so the subsequent call to ensureIndex fo r any index will go to the server
*/ */
virtual void resetIndexCache(); virtual void resetIndexCache();
virtual auto_ptr<DBClientCursor> getIndexes( const string &ns ); virtual auto_ptr<DBClientCursor> getIndexes( const string &ns );
virtual void dropIndex( const string& ns , BSONObj keys ); virtual void dropIndex( const string& ns , BSONObj keys );
virtual void dropIndex( const string& ns , const string& indexName ); virtual void dropIndex( const string& ns , const string& indexName );
skipping to change at line 930 skipping to change at line 927
bool _haveCachedAvailableOptions; bool _haveCachedAvailableOptions;
AuthenticationTable _authTable; AuthenticationTable _authTable;
bool _hasAuthentication; bool _hasAuthentication;
}; };
/** /**
abstract class that implements the core db operations abstract class that implements the core db operations
*/ */
class DBClientBase : public DBClientWithCommands, public DBConnector { class DBClientBase : public DBClientWithCommands, public DBConnector {
protected: protected:
static AtomicInt64 ConnectionIdSequence;
long long _connectionId; // unique connection id for this connectio
n
WriteConcern _writeConcern; WriteConcern _writeConcern;
public: public:
DBClientBase() { DBClientBase() {
_writeConcern = W_NORMAL; _writeConcern = W_NORMAL;
_connectionId = ConnectionIdSequence.fetchAndAdd(1);
} }
long long getConnectionId() const { return _connectionId; }
WriteConcern getWriteConcern() const { return _writeConcern; } WriteConcern getWriteConcern() const { return _writeConcern; }
void setWriteConcern( WriteConcern w ) { _writeConcern = w; } void setWriteConcern( WriteConcern w ) { _writeConcern = w; }
/** send a query to the database. /** send a query to the database.
@param ns namespace to query, format is <dbname>.<collectname>[.<c ollectname>]* @param ns namespace to query, format is <dbname>.<collectname>[.<c ollectname>]*
@param query query to perform on the collection. this is a BSONOb j (binary JSON) @param query query to perform on the collection. this is a BSONOb j (binary JSON)
You may format as You may format as
{ query: { ... }, orderby: { ... } } { query: { ... }, orderby: { ... } }
to specify a sort order. to specify a sort order.
@param nToReturn n to return (i.e., limit). 0 = unlimited @param nToReturn n to return (i.e., limit). 0 = unlimited
skipping to change at line 1148 skipping to change at line 1141
string getServerAddress() const { return _serverString; } string getServerAddress() const { return _serverString; }
virtual void killCursor( long long cursorID ); virtual void killCursor( long long cursorID );
virtual bool callRead( Message& toSend , Message& response ) { retu rn call( toSend , response ); } virtual bool callRead( Message& toSend , Message& response ) { retu rn call( toSend , response ); }
virtual void say( Message &toSend, bool isRetry = false , string * actualServer = 0 ); virtual void say( Message &toSend, bool isRetry = false , string * actualServer = 0 );
virtual bool recv( Message& m ); virtual bool recv( Message& m );
virtual void checkResponse( const char *data, int nReturned, bool* retry = NULL, string* host = NULL ); virtual void checkResponse( const char *data, int nReturned, bool* retry = NULL, string* host = NULL );
virtual bool call( Message &toSend, Message &response, bool assertO k = true , string * actualServer = 0 ); virtual bool call( Message &toSend, Message &response, bool assertO k = true , string * actualServer = 0 );
virtual ConnectionString::ConnectionType type() const { return Conn ectionString::MASTER; } virtual ConnectionString::ConnectionType type() const { return Conn ectionString::MASTER; }
void setSoTimeout(double to) { _so_timeout = to; } void setSoTimeout(double timeout);
double getSoTimeout() const { return _so_timeout; } double getSoTimeout() const { return _so_timeout; }
virtual bool lazySupported() const { return true; } virtual bool lazySupported() const { return true; }
static int getNumConnections() { static int getNumConnections() {
return _numConnections; return _numConnections;
} }
static void setLazyKillCursor( bool lazy ) { _lazyKillCursor = lazy ; } static void setLazyKillCursor( bool lazy ) { _lazyKillCursor = lazy ; }
static bool getLazyKillCursor() { return _lazyKillCursor; } static bool getLazyKillCursor() { return _lazyKillCursor; }
 End of changes. 10 change blocks. 
24 lines changed or deleted 12 lines changed or added


 dblogger.h   dblogger.h 
skipping to change at line 28 skipping to change at line 28
#pragma once #pragma once
namespace mongo { namespace mongo {
/** helper to log (and read log) of a capped collection in the database */ /** helper to log (and read log) of a capped collection in the database */
class DBLogger { class DBLogger {
bool _inited; bool _inited;
public: public:
const string _ns; const string _ns;
DBLogger(string ns) : _inited(false), _ns(ns) { } DBLogger(const std::string& ns) : _inited(false), _ns(ns) { }
}; };
} }
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 dbmessage.h   dbmessage.h 
skipping to change at line 266 skipping to change at line 266
void replyToQuery(int queryResultFlags, void replyToQuery(int queryResultFlags,
AbstractMessagingPort* p, Message& requestMsg, AbstractMessagingPort* p, Message& requestMsg,
void *data, int size, void *data, int size,
int nReturned, int startingFrom = 0, int nReturned, int startingFrom = 0,
long long cursorId = 0 long long cursorId = 0
); );
/* object reply helper. */ /* object reply helper. */
void replyToQuery(int queryResultFlags, void replyToQuery(int queryResultFlags,
AbstractMessagingPort* p, Message& requestMsg, AbstractMessagingPort* p, Message& requestMsg,
BSONObj& responseObj); const BSONObj& responseObj);
/* helper to do a reply using a DbResponse object */ /* helper to do a reply using a DbResponse object */
void replyToQuery( int queryResultFlags, Message& m, DbResponse& dbresp onse, BSONObj obj ); void replyToQuery( int queryResultFlags, Message& m, DbResponse& dbresp onse, BSONObj obj );
/** /**
* Helper method for setting up a response object. * Helper method for setting up a response object.
* *
* @param queryResultFlags The flags to set to the response object. * @param queryResultFlags The flags to set to the response object.
* @param response The object to be used for building the response. The internal buffer of * @param response The object to be used for building the response. The internal buffer of
* this object will contain the raw data from resultObj after a suc cessful call. * this object will contain the raw data from resultObj after a suc cessful call.
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 dbwebserver.h   dbwebserver.h 
skipping to change at line 42 skipping to change at line 42
class DbWebHandler : public Prioritizable { class DbWebHandler : public Prioritizable {
public: public:
DbWebHandler( const string& name , double priority , bool requiresR EST ); DbWebHandler( const string& name , double priority , bool requiresR EST );
virtual ~DbWebHandler() {} virtual ~DbWebHandler() {}
virtual bool handles( const string& url ) const { return url == _de faultUrl; } virtual bool handles( const string& url ) const { return url == _de faultUrl; }
virtual bool requiresREST( const string& url ) const { return _requ iresREST; } virtual bool requiresREST( const string& url ) const { return _requ iresREST; }
virtual void handle( const char *rq, // the full request virtual void handle( const char *rq, // the full request
string url, const std::string& url,
BSONObj params, BSONObj params,
// set these and return them: // set these and return them:
string& responseMsg, string& responseMsg,
int& responseCode, int& responseCode,
vector<string>& headers, // if completely empt y, content-type: text/html will be added vector<string>& headers, // if completely empt y, content-type: text/html will be added
const SockAddr &from const SockAddr &from
) = 0; ) = 0;
string toString() const { return _toString; } string toString() const { return _toString; }
static DbWebHandler * findHandler( const string& url ); static DbWebHandler * findHandler( const string& url );
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 diskloc.h   diskloc.h 
skipping to change at line 43 skipping to change at line 43
class DiskLoc; class DiskLoc;
template< class Version > class BtreeBucket; template< class Version > class BtreeBucket;
#pragma pack(1) #pragma pack(1)
/** represents a disk location/offset on disk in a database. 64 bits. /** represents a disk location/offset on disk in a database. 64 bits.
it is assumed these will be passed around by value a lot so don't d o anything to make them large it is assumed these will be passed around by value a lot so don't d o anything to make them large
(such as adding a virtual function) (such as adding a virtual function)
*/ */
class DiskLoc { class DiskLoc {
int _a; // this will be volume, file #, etsc. but is a logical value could be anything depending on storage engine int _a; // this will be volume, file #, etc. but is a logical v alue could be anything depending on storage engine
int ofs; int ofs;
public: public:
enum SentinelValues { enum SentinelValues {
/* note NullOfs is different. todo clean up. see refs to NullO fs in code - use is valid but outside DiskLoc context so confusing as-is. * / /* note NullOfs is different. todo clean up. see refs to NullO fs in code - use is valid but outside DiskLoc context so confusing as-is. * /
NullOfs = -1, NullOfs = -1,
MaxFiles=16000 // thus a limit of about 32TB of data per db MaxFiles=16000 // thus a limit of about 32TB of data per db
}; };
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 distlock.h   distlock.h 
skipping to change at line 64 skipping to change at line 64
TimeNotFoundException( const char * msg , int code ) : LockExceptio n( msg, code ) {} TimeNotFoundException( const char * msg , int code ) : LockExceptio n( msg, code ) {}
TimeNotFoundException( const string& msg, int code ) : LockExceptio n( msg, code ) {} TimeNotFoundException( const string& msg, int code ) : LockExceptio n( msg, code ) {}
virtual ~TimeNotFoundException() throw() { } virtual ~TimeNotFoundException() throw() { }
}; };
/** /**
* The distributed lock is a configdb backed way of synchronizing syste m-wide tasks. A task must be identified by a * The distributed lock is a configdb backed way of synchronizing syste m-wide tasks. A task must be identified by a
* unique name across the system (e.g., "balancer"). A lock is taken by writing a document in the configdb's locks * unique name across the system (e.g., "balancer"). A lock is taken by writing a document in the configdb's locks
* collection with that name. * collection with that name.
* *
* To be maintained, each taken lock needs to be revalidaded ("pinged") within a pre-established amount of time. This * To be maintained, each taken lock needs to be revalidated ("pinged") within a pre-established amount of time. This
* class does this maintenance automatically once a DistributedLock obj ect was constructed. * class does this maintenance automatically once a DistributedLock obj ect was constructed.
*/ */
class DistributedLock { class DistributedLock {
public: public:
static LabeledLevel logLvl; static LabeledLevel logLvl;
struct PingData { struct PingData {
PingData( const string& _id , Date_t _lastPing , Date_t _remote , OID _ts ) PingData( const string& _id , Date_t _lastPing , Date_t _remote , OID _ts )
skipping to change at line 221 skipping to change at line 221
// Make sure the lock ownership passes to this object, // Make sure the lock ownership passes to this object,
// so we only unlock once. // so we only unlock once.
((dist_lock_try&) that)._got = false; ((dist_lock_try&) that)._got = false;
((dist_lock_try&) that)._lock = NULL; ((dist_lock_try&) that)._lock = NULL;
((dist_lock_try&) that)._other = BSONObj(); ((dist_lock_try&) that)._other = BSONObj();
return *this; return *this;
} }
dist_lock_try( DistributedLock * lock , string why ) dist_lock_try( DistributedLock * lock , const std::string& why )
: _lock(lock), _why(why) { : _lock(lock), _why(why) {
_got = _lock->lock_try( why , false , &_other ); _got = _lock->lock_try( why , false , &_other );
} }
~dist_lock_try() { ~dist_lock_try() {
if ( _got ) { if ( _got ) {
verify( ! _other.isEmpty() ); verify( ! _other.isEmpty() );
_lock->unlock( &_other ); _lock->unlock( &_other );
} }
} }
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 document.h   document.h 
skipping to change at line 88 skipping to change at line 88
@param fieldName the name of the field @param fieldName the name of the field
@return point to the requested field @return point to the requested field
*/ */
intrusive_ptr<const Value> getValue(const string &fieldName); intrusive_ptr<const Value> getValue(const string &fieldName);
/* /*
Add the given field to the Document. Add the given field to the Document.
BSON documents' fields are ordered; the new Field will be BSON documents' fields are ordered; the new Field will be
appened to the current list of fields. appended to the current list of fields.
It is an error to add a field that has the same name as another It is an error to add a field that has the same name as another
field. field.
*/ */
void addField(const string &fieldName, void addField(const string &fieldName,
const intrusive_ptr<const Value> &pValue); const intrusive_ptr<const Value> &pValue);
/* /*
Set the given field to be at the specified position in the Set the given field to be at the specified position in the
Document. This will replace any field that is currently in that Document. This will replace any field that is currently in that
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 document_source.h   document_source.h 
skipping to change at line 622 skipping to change at line 622
Accumulators become fields in the Documents that result from Accumulators become fields in the Documents that result from
grouping. Each unique group document must have it's own grouping. Each unique group document must have it's own
accumulator; the accumulator factory is used to create that. accumulator; the accumulator factory is used to create that.
@param fieldName the name the accumulator result will have in the @param fieldName the name the accumulator result will have in the
result documents result documents
@param pAccumulatorFactory used to create the accumulator for the @param pAccumulatorFactory used to create the accumulator for the
group field group field
*/ */
void addAccumulator(string fieldName, void addAccumulator(const std::string& fieldName,
intrusive_ptr<Accumulator> (*pAccumulatorFactor y)( intrusive_ptr<Accumulator> (*pAccumulatorFactor y)(
const intrusive_ptr<ExpressionContext> &), const intrusive_ptr<ExpressionContext> &),
const intrusive_ptr<Expression> &pExpression); const intrusive_ptr<Expression> &pExpression);
/** /**
Create a grouping DocumentSource from BSON. Create a grouping DocumentSource from BSON.
This is a convenience method that uses the above, and operates on This is a convenience method that uses the above, and operates on
a BSONElement that has been deteremined to be an Object with an a BSONElement that has been deteremined to be an Object with an
element named $group. element named $group.
skipping to change at line 955 skipping to change at line 955
}; };
typedef vector<intrusive_ptr<Document> > VectorType; typedef vector<intrusive_ptr<Document> > VectorType;
VectorType documents; VectorType documents;
VectorType::iterator docIterator; VectorType::iterator docIterator;
intrusive_ptr<Document> pCurrent; intrusive_ptr<Document> pCurrent;
}; };
class DocumentSourceLimit : class DocumentSourceLimit :
public SplittableDocumentSource { public DocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceLimit(); virtual ~DocumentSourceLimit();
virtual bool eof(); virtual bool eof();
virtual bool advance(); virtual bool advance();
virtual intrusive_ptr<Document> getCurrent(); virtual intrusive_ptr<Document> getCurrent();
virtual const char *getSourceName() const; virtual const char *getSourceName() const;
virtual bool coalesce(const intrusive_ptr<DocumentSource> &pNextSou rce); virtual bool coalesce(const intrusive_ptr<DocumentSource> &pNextSou rce);
virtual GetDepsReturn getDependencies(set<string>& deps) const { virtual GetDepsReturn getDependencies(set<string>& deps) const {
skipping to change at line 978 skipping to change at line 978
/** /**
Create a new limiting DocumentSource. Create a new limiting DocumentSource.
@param pExpCtx the expression context for the pipeline @param pExpCtx the expression context for the pipeline
@returns the DocumentSource @returns the DocumentSource
*/ */
static intrusive_ptr<DocumentSourceLimit> create( static intrusive_ptr<DocumentSourceLimit> create(
const intrusive_ptr<ExpressionContext> &pExpCtx); const intrusive_ptr<ExpressionContext> &pExpCtx);
// Virtuals for SplittableDocumentSource
// Need to run on rounter. Running on shard as well is an optimizat
ion.
virtual intrusive_ptr<DocumentSource> getShardSource() { return thi
s; }
virtual intrusive_ptr<DocumentSource> getRouterSource() { return th
is; }
long long getLimit() const { return limit; }
void setLimit(long long newLimit) { limit = newLimit; }
/** /**
Create a limiting DocumentSource from BSON. Create a limiting DocumentSource from BSON.
This is a convenience method that uses the above, and operates on This is a convenience method that uses the above, and operates on
a BSONElement that has been deteremined to be an Object with an a BSONElement that has been deteremined to be an Object with an
element named $limit. element named $limit.
@param pBsonElement the BSONELement that defines the limit @param pBsonElement the BSONELement that defines the limit
@param pExpCtx the expression context @param pExpCtx the expression context
@returns the grouping DocumentSource @returns the grouping DocumentSource
skipping to change at line 1017 skipping to change at line 1009
private: private:
DocumentSourceLimit( DocumentSourceLimit(
const intrusive_ptr<ExpressionContext> &pExpCtx); const intrusive_ptr<ExpressionContext> &pExpCtx);
long long limit; long long limit;
long long count; long long count;
intrusive_ptr<Document> pCurrent; intrusive_ptr<Document> pCurrent;
}; };
class DocumentSourceSkip : class DocumentSourceSkip :
public SplittableDocumentSource { public DocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceSkip(); virtual ~DocumentSourceSkip();
virtual bool eof(); virtual bool eof();
virtual bool advance(); virtual bool advance();
virtual intrusive_ptr<Document> getCurrent(); virtual intrusive_ptr<Document> getCurrent();
virtual const char *getSourceName() const; virtual const char *getSourceName() const;
virtual bool coalesce(const intrusive_ptr<DocumentSource> &pNextSou rce); virtual bool coalesce(const intrusive_ptr<DocumentSource> &pNextSou rce);
virtual GetDepsReturn getDependencies(set<string>& deps) const { virtual GetDepsReturn getDependencies(set<string>& deps) const {
skipping to change at line 1040 skipping to change at line 1032
/** /**
Create a new skipping DocumentSource. Create a new skipping DocumentSource.
@param pExpCtx the expression context @param pExpCtx the expression context
@returns the DocumentSource @returns the DocumentSource
*/ */
static intrusive_ptr<DocumentSourceSkip> create( static intrusive_ptr<DocumentSourceSkip> create(
const intrusive_ptr<ExpressionContext> &pExpCtx); const intrusive_ptr<ExpressionContext> &pExpCtx);
// Virtuals for SplittableDocumentSource
// Need to run on rounter. Can't run on shards.
virtual intrusive_ptr<DocumentSource> getShardSource() { return NUL
L; }
virtual intrusive_ptr<DocumentSource> getRouterSource() { return th
is; }
long long getSkip() const { return skip; }
void setSkip(long long newSkip) { skip = newSkip; }
/** /**
Create a skipping DocumentSource from BSON. Create a skipping DocumentSource from BSON.
This is a convenience method that uses the above, and operates on This is a convenience method that uses the above, and operates on
a BSONElement that has been deteremined to be an Object with an a BSONElement that has been deteremined to be an Object with an
element named $skip. element named $skip.
@param pBsonElement the BSONELement that defines the skip @param pBsonElement the BSONELement that defines the skip
@param pExpCtx the expression context @param pExpCtx the expression context
@returns the grouping DocumentSource @returns the grouping DocumentSource
 End of changes. 5 change blocks. 
24 lines changed or deleted 3 lines changed or added


 dur.h   dur.h 
// @file dur.h durability support // @file dur.h durability support
/**
* Copyright (C) 2009 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "diskloc.h" #include "diskloc.h"
#include "mongommf.h" #include "mongommf.h"
namespace mongo { namespace mongo {
class NamespaceDetails; class NamespaceDetails;
void mongoAbort(const char *msg); void mongoAbort(const char *msg);
skipping to change at line 37 skipping to change at line 53
class DurableInterface : boost::noncopyable { class DurableInterface : boost::noncopyable {
public: public:
virtual ~DurableInterface() { log() << "ERROR warning ~DurableI nterface not intended to be called" << endl; } virtual ~DurableInterface() { log() << "ERROR warning ~DurableI nterface not intended to be called" << endl; }
/** Declare that a file has been created /** Declare that a file has been created
Normally writes are applied only after journaling, for safe ty. But here the file Normally writes are applied only after journaling, for safe ty. But here the file
is created first, and the journal will just replay the crea tion if the create didn't is created first, and the journal will just replay the crea tion if the create didn't
happen because of crashing. happen because of crashing.
*/ */
virtual void createdFile(string filename, unsigned long long le n) = 0; virtual void createdFile(const std::string& filename, unsigned long long len) = 0;
/** Declarations of write intent. /** Declarations of write intent.
Use these methods to declare "i'm about to write to x and i t should be logged for redo." Use these methods to declare "i'm about to write to x and i t should be logged for redo."
Failure to call writing...() is checked in _DEBUG mode by u sing a read only mapped view Failure to call writing...() is checked in _DEBUG mode by u sing a read only mapped view
(i.e., you'll segfault if the code is covered in that situa tion). The _DEBUG check doesn't (i.e., you'll segfault if the code is covered in that situa tion). The _DEBUG check doesn't
verify that your length is correct though. verify that your length is correct though.
*/ */
skipping to change at line 98 skipping to change at line 114
Do not use this. Use commitIfNeeded() instead. Do not use this. Use commitIfNeeded() instead.
@return true if --dur is on. @return true if --dur is on.
@return false if --dur is off. (in which case there is acti on) @return false if --dur is off. (in which case there is acti on)
*/ */
virtual bool commitNow() = 0; virtual bool commitNow() = 0;
/** Commit if enough bytes have been modified. Current threshol d is 50MB /** Commit if enough bytes have been modified. Current threshol d is 50MB
The idea is that long running write operations that dont yi eld The idea is that long running write operations that don't y ield
(like creating an index or update with $atomic) can call th is (like creating an index or update with $atomic) can call th is
whenever the db is in a sane state and it will prevent comm its whenever the db is in a sane state and it will prevent comm its
from growing too large. from growing too large.
@return true if commited @return true if commited
*/ */
virtual bool commitIfNeeded(bool force=false) = 0; virtual bool commitIfNeeded(bool force=false) = 0;
/** @return true if time to commit but does NOT do a commit */ /** @return true if time to commit but does NOT do a commit */
virtual bool aCommitIsNeeded() const = 0; virtual bool aCommitIsNeeded() const = 0;
skipping to change at line 171 skipping to change at line 187
// these need to be able to enable/disable Durability // these need to be able to enable/disable Durability
friend void startup(); friend void startup();
friend class TempDisableDurability; friend class TempDisableDurability;
}; // class DurableInterface }; // class DurableInterface
class NonDurableImpl : public DurableInterface { class NonDurableImpl : public DurableInterface {
void* writingPtr(void *x, unsigned len); void* writingPtr(void *x, unsigned len);
void* writingAtOffset(void *buf, unsigned ofs, unsigned len) { return buf; } void* writingAtOffset(void *buf, unsigned ofs, unsigned len) { return buf; }
void* writingRangesAtOffsets(void *buf, const vector< pair< lon g long, unsigned > > &ranges) { return buf; } void* writingRangesAtOffsets(void *buf, const vector< pair< lon g long, unsigned > > &ranges) { return buf; }
void declareWriteIntent(void *, unsigned); void declareWriteIntent(void *, unsigned);
void createdFile(string filename, unsigned long long len) { } void createdFile(const std::string& filename, unsigned long lon g len) { }
bool awaitCommit() { return false; } bool awaitCommit() { return false; }
bool commitNow() { return false; } bool commitNow() { return false; }
bool commitIfNeeded(bool) { return false; } bool commitIfNeeded(bool) { return false; }
bool aCommitIsNeeded() const { return false; } bool aCommitIsNeeded() const { return false; }
void syncDataAndTruncateJournal() {} void syncDataAndTruncateJournal() {}
}; };
class DurableImpl : public DurableInterface { class DurableImpl : public DurableInterface {
bool _aCommitIsNeeded(); bool _aCommitIsNeeded();
void* writingPtr(void *x, unsigned len); void* writingPtr(void *x, unsigned len);
void* writingAtOffset(void *buf, unsigned ofs, unsigned len); void* writingAtOffset(void *buf, unsigned ofs, unsigned len);
void* writingRangesAtOffsets(void *buf, const vector< pair< lon g long, unsigned > > &ranges); void* writingRangesAtOffsets(void *buf, const vector< pair< lon g long, unsigned > > &ranges);
void declareWriteIntent(void *, unsigned); void declareWriteIntent(void *, unsigned);
void createdFile(string filename, unsigned long long len); void createdFile(const std::string& filename, unsigned long lon g len);
bool awaitCommit(); bool awaitCommit();
bool commitNow(); bool commitNow();
bool aCommitIsNeeded() const; bool aCommitIsNeeded() const;
bool commitIfNeeded(bool); bool commitIfNeeded(bool);
void syncDataAndTruncateJournal(); void syncDataAndTruncateJournal();
}; };
} // namespace dur } // namespace dur
inline dur::DurableInterface& getDur() { return dur::DurableInterface:: getDur(); } inline dur::DurableInterface& getDur() { return dur::DurableInterface:: getDur(); }
 End of changes. 5 change blocks. 
4 lines changed or deleted 22 lines changed or added


 dur_recover.h   dur_recover.h 
// @file dur.h durability support // @file dur.h durability support
/**
* Copyright (C) 2009 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "dur_journalformat.h" #include <boost/filesystem/operations.hpp>
#include "../util/concurrency/mutex.h" #include <list>
#include "../util/file.h"
#include "mongo/db/dur_journalformat.h"
#include "mongo/util/concurrency/mutex.h"
#include "mongo/util/file.h"
namespace mongo { namespace mongo {
class MongoMMF; class MongoMMF;
namespace dur { namespace dur {
struct ParsedJournalEntry; struct ParsedJournalEntry;
/** call go() to execute a recovery from existing journal files. /** call go() to execute a recovery from existing journal files.
*/ */
class RecoveryJob : boost::noncopyable { class RecoveryJob : boost::noncopyable {
static class Last {
public:
Last();
MongoMMF* newEntry(const ParsedJournalEntry&, RecoveryJob&)
;
private:
MongoMMF *mmf;
string dbName;
int fileNo;
} last;
public: public:
RecoveryJob() : _lastDataSyncedFromLastRun(0), RecoveryJob() : _lastDataSyncedFromLastRun(0),
_mx("recovery"), _recovering(false) { _lastSeqMentionedInCo nsoleLog = 1; } _mx("recovery"), _recovering(false) { _lastSeqMentionedInCo nsoleLog = 1; }
void go(vector<boost::filesystem::path>& files); void go(vector<boost::filesystem::path>& files);
~RecoveryJob(); ~RecoveryJob();
/** @param data data between header and footer. compressed if r ecovering. */ /** @param data data between header and footer. compressed if r ecovering. */
void processSection(const JSectHeader *h, const void *data, uns igned len, const JSectFooter *f); void processSection(const JSectHeader *h, const void *data, uns igned len, const JSectFooter *f);
void close(); // locks and calls _close() void close(); // locks and calls _close()
static RecoveryJob & get() { return _instance; } static RecoveryJob & get() { return _instance; }
private: private:
void write(const ParsedJournalEntry& entry, MongoMMF* mmf); // void write(Last& last, const ParsedJournalEntry& entry); // act
actually writes to the file ually writes to the file
void applyEntry(const ParsedJournalEntry& entry, bool apply, bo void applyEntry(Last& last, const ParsedJournalEntry& entry, bo
ol dump, MongoMMF* mmf); ol apply, bool dump);
void applyEntries(const vector<ParsedJournalEntry> &entries); void applyEntries(const vector<ParsedJournalEntry> &entries);
bool processFileBuffer(const void *, unsigned len); bool processFileBuffer(const void *, unsigned len);
bool processFile(boost::filesystem::path journalfile); bool processFile(boost::filesystem::path journalfile);
void _close(); // doesn't lock void _close(); // doesn't lock
MongoMMF* getMongoMMF(const ParsedJournalEntry& entry); MongoMMF* getMongoMMF(const ParsedJournalEntry& entry);
list<boost::shared_ptr<MongoMMF> > _mmfs; list<boost::shared_ptr<MongoMMF> > _mmfs;
unsigned long long _lastDataSyncedFromLastRun; unsigned long long _lastDataSyncedFromLastRun;
unsigned long long _lastSeqMentionedInConsoleLog; unsigned long long _lastSeqMentionedInConsoleLog;
 End of changes. 4 change blocks. 
7 lines changed or deleted 38 lines changed or added


 dur_stats.h   dur_stats.h 
// @file dur_stats.h // @file dur_stats.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace mongo { namespace mongo {
namespace dur { namespace dur {
/** journaling stats. the model here is that the commit thread is the only writer, and that reads are /** journaling stats. the model here is that the commit thread is the only writer, and that reads are
uncommon (from a serverStatus command and such). Thus, there s hould not be multicore chatter overhead. uncommon (from a serverStatus command and such). Thus, there s hould not be multicore chatter overhead.
*/ */
struct Stats { struct Stats {
Stats(); Stats();
void rotate(); void rotate();
BSONObj asObj(); BSONObj asObj();
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 durop.h   durop.h 
skipping to change at line 81 skipping to change at line 81
private: private:
const unsigned _opcode; const unsigned _opcode;
}; };
/** indicates creation of a new file */ /** indicates creation of a new file */
class FileCreatedOp : public DurOp { class FileCreatedOp : public DurOp {
public: public:
FileCreatedOp(BufReader& log); FileCreatedOp(BufReader& log);
/** param f filename to create with path */ /** param f filename to create with path */
FileCreatedOp(string f, unsigned long long l); FileCreatedOp(const std::string& f, unsigned long long l);
virtual void replay(); virtual void replay();
virtual string toString(); virtual string toString();
virtual bool needFilesClosed(); virtual bool needFilesClosed();
protected: protected:
virtual void _serialize(AlignedBuilder& ab); virtual void _serialize(AlignedBuilder& ab);
private: private:
RelativePath _p; RelativePath _p;
unsigned long long _len; // size of file, not length of name unsigned long long _len; // size of file, not length of name
}; };
/** record drop of a database */ /** record drop of a database */
class DropDbOp : public DurOp { class DropDbOp : public DurOp {
public: public:
DropDbOp(BufReader& log); DropDbOp(BufReader& log);
DropDbOp(string db) : DropDbOp(const std::string& db) :
DurOp(JEntry::OpCode_DropDb), _db(db) { } DurOp(JEntry::OpCode_DropDb), _db(db) { }
virtual void replay(); virtual void replay();
virtual string toString() { return string("DropDbOp ") + _db; } virtual string toString() { return string("DropDbOp ") + _db; }
virtual bool needFilesClosed() { return true; } virtual bool needFilesClosed() { return true; }
protected: protected:
virtual void _serialize(AlignedBuilder& ab); virtual void _serialize(AlignedBuilder& ab);
private: private:
string _db; string _db;
}; };
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 engine.h   engine.h 
skipping to change at line 215 skipping to change at line 215
static void setCheckInterruptCallback( const char * ( *func )() ) { _checkInterruptCallback = func; } static void setCheckInterruptCallback( const char * ( *func )() ) { _checkInterruptCallback = func; }
static bool haveCheckInterruptCallback() { return _checkInterruptCa llback; } static bool haveCheckInterruptCallback() { return _checkInterruptCa llback; }
static const char * checkInterrupt() { static const char * checkInterrupt() {
return _checkInterruptCallback ? _checkInterruptCallback() : "" ; return _checkInterruptCallback ? _checkInterruptCallback() : "" ;
} }
static bool interrupted() { static bool interrupted() {
const char *r = checkInterrupt(); const char *r = checkInterrupt();
return r && r[ 0 ]; return r && r[ 0 ];
} }
static std::string getInterpreterVersionString();
protected: protected:
virtual Scope * createScope() = 0; virtual Scope * createScope() = 0;
private: private:
void ( *_scopeInitCallback )( Scope & ); void ( *_scopeInitCallback )( Scope & );
static void ( *_connectCallback )( DBClientWithCommands & ); static void ( *_connectCallback )( DBClientWithCommands & );
static const char * ( *_checkInterruptCallback )(); static const char * ( *_checkInterruptCallback )();
static unsigned ( *_getInterruptSpecCallback )(); static unsigned ( *_getInterruptSpecCallback )();
}; };
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 lines changed or added


 expression.h   expression.h 
skipping to change at line 64 skipping to change at line 64
virtual intrusive_ptr<Expression> optimize() = 0; virtual intrusive_ptr<Expression> optimize() = 0;
/** /**
Add this expression's field dependencies to the set Add this expression's field dependencies to the set
Expressions are trees, so this is often recursive. Expressions are trees, so this is often recursive.
@param deps output parameter @param deps output parameter
@param path path to self if all ancestors are ExpressionObjects. @param path path to self if all ancestors are ExpressionObjects.
Top-level ExpressionObject gets pointer to empty vec tor. Top-level ExpressionObject gets pointer to empty vec tor.
If any other Expression is an ancestor {a:1} object If any other Expression is an ancestor, or in other
aren't allowed, so they get NULL cases
where {a:1} inclusion objects aren't allowed, they g
et
NULL.
*/ */
virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const = 0; virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const = 0;
/** simple expressions are just inclusion exclusion as supported by ExpressionObject */ /** simple expressions are just inclusion exclusion as supported by ExpressionObject */
virtual bool isSimple() { return false; } virtual bool isSimple() { return false; }
/* /*
Evaluate the Expression using the given document as input. Evaluate the Expression using the given document as input.
@returns the computed value @returns the computed value
skipping to change at line 97 skipping to change at line 97
substituted inline. substituted inline.
@param pBuilder the builder to add the expression to @param pBuilder the builder to add the expression to
@param fieldName the name the object should be given @param fieldName the name the object should be given
@param requireExpression specify true if the value must appear @param requireExpression specify true if the value must appear
as an expression; this is used by DocumentSources like as an expression; this is used by DocumentSources like
$project which distinguish between field inclusion and virtual $project which distinguish between field inclusion and virtual
field specification; See ExpressionConstant. field specification; See ExpressionConstant.
*/ */
virtual void addToBsonObj( virtual void addToBsonObj(
BSONObjBuilder *pBuilder, string fieldName, BSONObjBuilder *pBuilder, const std::string& fieldName,
bool requireExpression) const = 0; bool requireExpression) const = 0;
/* /*
Add the Expression (and any descendant Expressions) into a BSON Add the Expression (and any descendant Expressions) into a BSON
array that is under construction. array that is under construction.
Unevaluated Expressions always materialize as objects. Evaluatio n Unevaluated Expressions always materialize as objects. Evaluatio n
may produce a scalar or another object, either of which will be may produce a scalar or another object, either of which will be
substituted inline. substituted inline.
skipping to change at line 224 skipping to change at line 224
typedef vector<intrusive_ptr<Expression> > ExpressionVector; typedef vector<intrusive_ptr<Expression> > ExpressionVector;
}; };
class ExpressionNary : class ExpressionNary :
public Expression { public Expression {
public: public:
// virtuals from Expression // virtuals from Expression
virtual intrusive_ptr<Expression> optimize(); virtual intrusive_ptr<Expression> optimize();
virtual void addToBsonObj( virtual void addToBsonObj(
BSONObjBuilder *pBuilder, string fieldName, BSONObjBuilder *pBuilder, const std::string& fieldName,
bool requireExpression) const; bool requireExpression) const;
virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const; virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const;
virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const; virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const;
/* /*
Add an operand to the n-ary expression. Add an operand to the n-ary expression.
@param pExpression the expression to add @param pExpression the expression to add
*/ */
virtual void addOperand(const intrusive_ptr<Expression> &pExpressio n); virtual void addOperand(const intrusive_ptr<Expression> &pExpressio n);
skipping to change at line 365 skipping to change at line 365
class ExpressionCoerceToBool : class ExpressionCoerceToBool :
public Expression { public Expression {
public: public:
// virtuals from ExpressionNary // virtuals from ExpressionNary
virtual ~ExpressionCoerceToBool(); virtual ~ExpressionCoerceToBool();
virtual intrusive_ptr<Expression> optimize(); virtual intrusive_ptr<Expression> optimize();
virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const; virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const;
virtual intrusive_ptr<const Value> evaluate( virtual intrusive_ptr<const Value> evaluate(
const intrusive_ptr<Document> &pDocument) const; const intrusive_ptr<Document> &pDocument) const;
virtual void addToBsonObj( virtual void addToBsonObj(
BSONObjBuilder *pBuilder, string fieldName, BSONObjBuilder *pBuilder, const std::string& fieldName,
bool requireExpression) const; bool requireExpression) const;
virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const; virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const;
static intrusive_ptr<ExpressionCoerceToBool> create( static intrusive_ptr<ExpressionCoerceToBool> create(
const intrusive_ptr<Expression> &pExpression); const intrusive_ptr<Expression> &pExpression);
private: private:
ExpressionCoerceToBool(const intrusive_ptr<Expression> &pExpression ); ExpressionCoerceToBool(const intrusive_ptr<Expression> &pExpression );
intrusive_ptr<Expression> pExpression; intrusive_ptr<Expression> pExpression;
skipping to change at line 394 skipping to change at line 394
virtual intrusive_ptr<const Value> evaluate( virtual intrusive_ptr<const Value> evaluate(
const intrusive_ptr<Document> &pDocument) const; const intrusive_ptr<Document> &pDocument) const;
virtual const char *getOpName() const; virtual const char *getOpName() const;
virtual void addOperand(const intrusive_ptr<Expression> &pExpressio n); virtual void addOperand(const intrusive_ptr<Expression> &pExpressio n);
/* /*
Shorthands for creating various comparisons expressions. Shorthands for creating various comparisons expressions.
Provide for conformance with the uniform function pointer signatu re Provide for conformance with the uniform function pointer signatu re
required for parsing. required for parsing.
These create a particular comparision operand, without any These create a particular comparison operand, without any
operands. Those must be added via ExpressionNary::addOperand(). operands. Those must be added via ExpressionNary::addOperand().
*/ */
static intrusive_ptr<ExpressionNary> createCmp(); static intrusive_ptr<ExpressionNary> createCmp();
static intrusive_ptr<ExpressionNary> createEq(); static intrusive_ptr<ExpressionNary> createEq();
static intrusive_ptr<ExpressionNary> createNe(); static intrusive_ptr<ExpressionNary> createNe();
static intrusive_ptr<ExpressionNary> createGt(); static intrusive_ptr<ExpressionNary> createGt();
static intrusive_ptr<ExpressionNary> createGte(); static intrusive_ptr<ExpressionNary> createGte();
static intrusive_ptr<ExpressionNary> createLt(); static intrusive_ptr<ExpressionNary> createLt();
static intrusive_ptr<ExpressionNary> createLte(); static intrusive_ptr<ExpressionNary> createLte();
skipping to change at line 439 skipping to change at line 439
public Expression { public Expression {
public: public:
// virtuals from Expression // virtuals from Expression
virtual ~ExpressionConstant(); virtual ~ExpressionConstant();
virtual intrusive_ptr<Expression> optimize(); virtual intrusive_ptr<Expression> optimize();
virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const; virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const;
virtual intrusive_ptr<const Value> evaluate( virtual intrusive_ptr<const Value> evaluate(
const intrusive_ptr<Document> &pDocument) const; const intrusive_ptr<Document> &pDocument) const;
virtual const char *getOpName() const; virtual const char *getOpName() const;
virtual void addToBsonObj( virtual void addToBsonObj(
BSONObjBuilder *pBuilder, string fieldName, BSONObjBuilder *pBuilder, const std::string& fieldName,
bool requireExpression) const; bool requireExpression) const;
virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const; virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const;
static intrusive_ptr<ExpressionConstant> createFromBsonElement( static intrusive_ptr<ExpressionConstant> createFromBsonElement(
BSONElement *pBsonElement); BSONElement *pBsonElement);
static intrusive_ptr<ExpressionConstant> create( static intrusive_ptr<ExpressionConstant> create(
const intrusive_ptr<const Value> &pValue); const intrusive_ptr<const Value> &pValue);
/* /*
Get the constant value represented by this Expression. Get the constant value represented by this Expression.
skipping to change at line 536 skipping to change at line 536
class ExpressionFieldPath : class ExpressionFieldPath :
public Expression { public Expression {
public: public:
// virtuals from Expression // virtuals from Expression
virtual ~ExpressionFieldPath(); virtual ~ExpressionFieldPath();
virtual intrusive_ptr<Expression> optimize(); virtual intrusive_ptr<Expression> optimize();
virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const; virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const;
virtual intrusive_ptr<const Value> evaluate( virtual intrusive_ptr<const Value> evaluate(
const intrusive_ptr<Document> &pDocument) const; const intrusive_ptr<Document> &pDocument) const;
virtual void addToBsonObj( virtual void addToBsonObj(
BSONObjBuilder *pBuilder, string fieldName, BSONObjBuilder *pBuilder, const std::string& fieldName,
bool requireExpression) const; bool requireExpression) const;
virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const; virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const;
/* /*
Create a field path expression. Create a field path expression.
Evaluation will extract the value associated with the given field Evaluation will extract the value associated with the given field
path from the source document. path from the source document.
@param fieldPath the field path string, without any leading docum ent @param fieldPath the field path string, without any leading docum ent
skipping to change at line 605 skipping to change at line 605
class ExpressionFieldRange : class ExpressionFieldRange :
public Expression { public Expression {
public: public:
// virtuals from expression // virtuals from expression
virtual ~ExpressionFieldRange(); virtual ~ExpressionFieldRange();
virtual intrusive_ptr<Expression> optimize(); virtual intrusive_ptr<Expression> optimize();
virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const; virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const;
virtual intrusive_ptr<const Value> evaluate( virtual intrusive_ptr<const Value> evaluate(
const intrusive_ptr<Document> &pDocument) const; const intrusive_ptr<Document> &pDocument) const;
virtual void addToBsonObj( virtual void addToBsonObj(
BSONObjBuilder *pBuilder, string fieldName, BSONObjBuilder *pBuilder, const std::string& fieldName,
bool requireExpression) const; bool requireExpression) const;
virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const; virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const;
virtual void toMatcherBson(BSONObjBuilder *pBuilder) const; virtual void toMatcherBson(BSONObjBuilder *pBuilder) const;
/* /*
Create a field range expression. Create a field range expression.
Field ranges are meant to match up with classic Matcher semantics , Field ranges are meant to match up with classic Matcher semantics ,
and therefore are conjunctions. For example, these appear in and therefore are conjunctions. For example, these appear in
mongo shell predicates in one of these forms: mongo shell predicates in one of these forms:
skipping to change at line 814 skipping to change at line 814
}; };
class ExpressionObject : class ExpressionObject :
public Expression { public Expression {
public: public:
// virtuals from Expression // virtuals from Expression
virtual ~ExpressionObject(); virtual ~ExpressionObject();
virtual intrusive_ptr<Expression> optimize(); virtual intrusive_ptr<Expression> optimize();
virtual bool isSimple(); virtual bool isSimple();
virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const; virtual void addDependencies(set<string>& deps, vector<string>* pat h=NULL) const;
/** Only evaluates non inclusion expressions. For inclusions, use addToDocument(). */
virtual intrusive_ptr<const Value> evaluate( virtual intrusive_ptr<const Value> evaluate(
const intrusive_ptr<Document> &pDocument) const; const intrusive_ptr<Document> &pDocument) const;
virtual void addToBsonObj( virtual void addToBsonObj(
BSONObjBuilder *pBuilder, string fieldName, BSONObjBuilder *pBuilder, const std::string& fieldName,
bool requireExpression) const; bool requireExpression) const;
virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const; virtual void addToBsonArray(BSONArrayBuilder *pBuilder) const;
/* /*
evaluate(), but return a Document instead of a Value-wrapped evaluate(), but return a Document instead of a Value-wrapped
Document. Document.
@param pDocument the input Document @param pDocument the input Document
@returns the result document @returns the result document
*/ */
 End of changes. 10 change blocks. 
11 lines changed or deleted 14 lines changed or added


 extsort.h   extsort.h 
skipping to change at line 65 skipping to change at line 65
IndexInterface& _i; IndexInterface& _i;
const Ordering _order; const Ordering _order;
}; };
static IndexInterface *extSortIdxInterface; static IndexInterface *extSortIdxInterface;
static Ordering extSortOrder; static Ordering extSortOrder;
static int extSortComp( const void *lv, const void *rv ); static int extSortComp( const void *lv, const void *rv );
class FileIterator : boost::noncopyable { class FileIterator : boost::noncopyable {
public: public:
FileIterator( string file ); FileIterator( const std::string& file );
~FileIterator(); ~FileIterator();
bool more(); bool more();
Data next(); Data next();
private: private:
bool _read( char* buf, long long count ); bool _read( char* buf, long long count );
int _file; int _file;
unsigned long long _length; unsigned long long _length;
unsigned long long _readSoFar; unsigned long long _readSoFar;
}; };
skipping to change at line 127 skipping to change at line 127
void hintNumObjects( long long numObjects ) { void hintNumObjects( long long numObjects ) {
if ( numObjects < _arraySize ) if ( numObjects < _arraySize )
_arraySize = (int)(numObjects + 100); _arraySize = (int)(numObjects + 100);
} }
private: private:
void _sortInMem(); void _sortInMem();
void sort( string file ); void sort( const std::string& file );
void finishMap(); void finishMap();
BSONObj _order; BSONObj _order;
long _maxFilesize; long _maxFilesize;
boost::filesystem::path _root; boost::filesystem::path _root;
int _arraySize; int _arraySize;
InMemory * _cur; InMemory * _cur;
long _curSizeSoFar; long _curSizeSoFar;
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 file_allocator.h   file_allocator.h 
skipping to change at line 58 skipping to change at line 58
* updated to match existing file size. * updated to match existing file size.
*/ */
void allocateAsap( const string &name, unsigned long long &size ); void allocateAsap( const string &name, unsigned long long &size );
void waitUntilFinished() const; void waitUntilFinished() const;
bool hasFailed() const; bool hasFailed() const;
static void ensureLength(int fd, long size); static void ensureLength(int fd, long size);
/** @return the singletone */ /** @return the singleton */
static FileAllocator * get(); static FileAllocator * get();
private: private:
FileAllocator(); FileAllocator();
void checkFailure(); void checkFailure();
// caller must hold pendingMutex_ lock. Returns size if allocated or // caller must hold pendingMutex_ lock. Returns size if allocated or
// allocation requested, -1 otherwise. // allocation requested, -1 otherwise.
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 fsync.h   fsync.h 
/** /**
* * Copyright (C) 2012 10gen Inc.
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License, version * This program is free software: you can redistribute it and/or modify
3, * it under the terms of the GNU Affero General Public License, version 3
* as published by the Free Software Foundation. ,
* * as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * This program is distributed in the hope that it will be useful,
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * but WITHOUT ANY WARRANTY; without even the implied warranty of
* GNU Affero General Public License for more details. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* * GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public Lice *
nse * You should have received a copy of the GNU Affero General Public Licen
* along with this program. If not, see <http://www.gnu.org/licenses/>. se
*/ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
namespace mongo { namespace mongo {
// Use this for blocking during an fsync-and-lock // Use this for blocking during an fsync-and-lock
extern SimpleMutex filesLockedFsync; extern SimpleMutex filesLockedFsync;
bool lockedForWriting(); bool lockedForWriting();
} }
 End of changes. 1 change blocks. 
15 lines changed or deleted 16 lines changed or added


 goodies.h   goodies.h 
skipping to change at line 85 skipping to change at line 85
#define MONGO_PRINTFL cout << __FILE__ ":" << __LINE__ << endl #define MONGO_PRINTFL cout << __FILE__ ":" << __LINE__ << endl
#define PRINTFL MONGO_PRINTFL #define PRINTFL MONGO_PRINTFL
#define MONGO_FLOG log() << __FILE__ ":" << __LINE__ << endl #define MONGO_FLOG log() << __FILE__ ":" << __LINE__ << endl
#define FLOG MONGO_FLOG #define FLOG MONGO_FLOG
inline bool startsWith(const char *str, const char *prefix) { inline bool startsWith(const char *str, const char *prefix) {
size_t l = strlen(prefix); size_t l = strlen(prefix);
if ( strlen(str) < l ) return false; if ( strlen(str) < l ) return false;
return strncmp(str, prefix, l) == 0; return strncmp(str, prefix, l) == 0;
} }
inline bool startsWith(string s, string p) { return startsWith(s.c_str( inline bool startsWith(const std::string& s, const std::string& p) {
), p.c_str()); } return startsWith(s.c_str(), p.c_str());
}
inline bool endsWith(const char *p, const char *suffix) { inline bool endsWith(const char *p, const char *suffix) {
size_t a = strlen(p); size_t a = strlen(p);
size_t b = strlen(suffix); size_t b = strlen(suffix);
if ( b > a ) return false; if ( b > a ) return false;
return strcmp(p + a - b, suffix) == 0; return strcmp(p + a - b, suffix) == 0;
} }
inline unsigned long swapEndian(unsigned long x) { inline unsigned long swapEndian(unsigned long x) {
return return
 End of changes. 1 change blocks. 
2 lines changed or deleted 3 lines changed or added


 grid.h   grid.h 
skipping to change at line 48 skipping to change at line 48
/** /**
* gets the config the db. * gets the config the db.
* will return an empty DBConfig if not in db already * will return an empty DBConfig if not in db already
*/ */
DBConfigPtr getDBConfig( string ns , bool create=true , const strin g& shardNameHint="" ); DBConfigPtr getDBConfig( string ns , bool create=true , const strin g& shardNameHint="" );
/** /**
* removes db entry. * removes db entry.
* on next getDBConfig call will fetch from db * on next getDBConfig call will fetch from db
*/ */
void removeDB( string db ); void removeDB( const std::string& db );
/** /**
* removes db entry - only this DBConfig object will be removed, * removes db entry - only this DBConfig object will be removed,
* other DBConfigs which may have been created in the meantime wil l not be harmed * other DBConfigs which may have been created in the meantime wil l not be harmed
* on next getDBConfig call will fetch from db * on next getDBConfig call will fetch from db
* *
* Using this method avoids race conditions where multiple threads detect a database * Using this method avoids race conditions where multiple threads detect a database
* reload has failed. * reload has failed.
* *
* Example : N threads receive version exceptions and dbConfig.rel oad(), while * Example : N threads receive version exceptions and dbConfig.rel oad(), while
skipping to change at line 79 skipping to change at line 79
*/ */
bool allowLocalHost() const; bool allowLocalHost() const;
/** /**
* @param whether to allow shards and config servers to use 'localh ost' in address * @param whether to allow shards and config servers to use 'localh ost' in address
*/ */
void setAllowLocalHost( bool allow ); void setAllowLocalHost( bool allow );
/** /**
* *
* addShard will create a new shard in the grid. It expects a mongo d process to be runing * addShard will create a new shard in the grid. It expects a mongo d process to be running
* on the provided address. Adding a shard that is a replica set is supported. * on the provided address. Adding a shard that is a replica set is supported.
* *
* @param name is an optional string with the name of the shard. if ommited, grid will * @param name is an optional string with the name of the shard. if omitted, grid will
* generate one and update the parameter. * generate one and update the parameter.
* @param servers is the connection string of the shard being added * @param servers is the connection string of the shard being added
* @param maxSize is the optional space quota in bytes. Zeros means there's no limitation to * @param maxSize is the optional space quota in bytes. Zeros means there's no limitation to
* space usage * space usage
* @param errMsg is the error description in case the operation fai led. * @param errMsg is the error description in case the operation fai led.
* @return true if shard was successfully added. * @return true if shard was successfully added.
*/ */
bool addShard( string* name , const ConnectionString& servers , lon g long maxSize , string& errMsg ); bool addShard( string* name , const ConnectionString& servers , lon g long maxSize , string& errMsg );
/** /**
skipping to change at line 109 skipping to change at line 109
*/ */
bool shouldBalance( const string& ns = "", BSONObj* balancerDocOut = 0 ) const; bool shouldBalance( const string& ns = "", BSONObj* balancerDocOut = 0 ) const;
/** /**
* *
* Obtain grid configuration and settings data. * Obtain grid configuration and settings data.
* *
* @param name identifies a particular type of configuration data. * @param name identifies a particular type of configuration data.
* @return a BSON object containing the requested data. * @return a BSON object containing the requested data.
*/ */
BSONObj getConfigSetting( string name ) const; BSONObj getConfigSetting( const std::string& name ) const;
unsigned long long getNextOpTime() const; unsigned long long getNextOpTime() const;
void flushConfig(); void flushConfig();
// exposed methods below are for testing only // exposed methods below are for testing only
/** /**
* @param balancerDoc bson that may contain a window of time for th e balancer to work * @param balancerDoc bson that may contain a window of time for th e balancer to work
* format { ... , activeWindow: { start: "8:30" , stop: "19: 00" } , ... } * format { ... , activeWindow: { start: "8:30" , stop: "19: 00" } , ... }
 End of changes. 4 change blocks. 
4 lines changed or deleted 4 lines changed or added


 hasher.h   hasher.h 
skipping to change at line 66 skipping to change at line 66
static Hasher* createHasher( HashSeed seed ) { static Hasher* createHasher( HashSeed seed ) {
return new Hasher( seed ); return new Hasher( seed );
} }
private: private:
HasherFactory(); HasherFactory();
}; };
class BSONElementHasher : private boost::noncopyable { class BSONElementHasher : private boost::noncopyable {
public: public:
/* The hash function we use can be given a seed, to effectively ran
domize it
* by choosing from among a family of hash functions. When it is no
t specified,
* use this.
*/
static const int DEFAULT_HASH_SEED = 0;
/* This computes a 64-bit hash of the value part of BSONElement "e" , /* This computes a 64-bit hash of the value part of BSONElement "e" ,
* preceded by the seed "seed". Squashes element (and any sub-elem ents) * preceded by the seed "seed". Squashes element (and any sub-elem ents)
* of the same canonical type, so hash({a:{b:4}}) will be the same * of the same canonical type, so hash({a:{b:4}}) will be the same
* as hash({a:{b:4.1}}). In particular, this squashes doubles to 64 -bit long * as hash({a:{b:4.1}}). In particular, this squashes doubles to 64 -bit long
* ints via truncation, so floating point values round towards 0 to the * ints via truncation, so floating point values round towards 0 to the
* nearest int representable as a 64-bit long. * nearest int representable as a 64-bit long.
* *
* This function is used in the computation of hashed indexes * This function is used in the computation of hashed indexes
* and hashed shard keys, and thus should not be changed unless * and hashed shard keys, and thus should not be changed unless
* the associated "getKeys" and "makeSingleKey" method in the * the associated "getKeys" and "makeSingleKey" method in the
 End of changes. 1 change blocks. 
0 lines changed or deleted 9 lines changed or added


 hashindex.h   hashindex.h 
skipping to change at line 22 skipping to change at line 22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "mongo/db/btree.h" #include "mongo/db/btree.h"
#include "mongo/db/hasher.h" #include "mongo/db/hasher.h"
#include "mongo/db/index.h" #include "mongo/db/index.h"
#include "mongo/db/keypattern.h"
#include "mongo/db/matcher.h" #include "mongo/db/matcher.h"
#include "mongo/db/namespace-inl.h" #include "mongo/db/namespace-inl.h"
#include "mongo/db/pdfile.h" #include "mongo/db/pdfile.h"
namespace mongo { namespace mongo {
/* This is an index where the keys are hashes of a given field. /* This is an index where the keys are hashes of a given field.
* *
* Optional arguments: * Optional arguments:
* "seed" : int (default = 0, a seed for the hash function) * "seed" : int (default = 0, a seed for the hash function)
skipping to change at line 113 skipping to change at line 114
/* Since the keys for this index are hashes, documents are not stor ed in order, /* Since the keys for this index are hashes, documents are not stor ed in order,
* thus we will need to perform scanAndOrder whenever the "order" i s non-empty. * thus we will need to perform scanAndOrder whenever the "order" i s non-empty.
*/ */
bool scanAndOrderRequired( const BSONObj& query , const BSONObj& or der ) const { bool scanAndOrderRequired( const BSONObj& query , const BSONObj& or der ) const {
return ! order.isEmpty(); return ! order.isEmpty();
} }
private: private:
string _hashedField; string _hashedField;
BSONObj _keyPattern; KeyPattern _keyPattern;
HashSeed _seed; //defaults to zero if not in the IndexSpec HashSeed _seed; //defaults to zero if not in the IndexSpec
HashVersion _hashVersion; //defaults to zero if not in the IndexSpe c HashVersion _hashVersion; //defaults to zero if not in the IndexSpe c
bool _isSparse; bool _isSparse;
}; };
} }
 End of changes. 2 change blocks. 
1 lines changed or deleted 2 lines changed or added


 hashtab.h   hashtab.h 
skipping to change at line 38 skipping to change at line 38
namespace mongo { namespace mongo {
#pragma pack(1) #pragma pack(1)
/* you should define: /* you should define:
int Key::hash() return > 0 always. int Key::hash() return > 0 always.
*/ */
template < template <class Key,class Type>
class Key,
class Type
>
class HashTable : boost::noncopyable { class HashTable : boost::noncopyable {
public: public:
const char *name; const char *name;
struct Node { struct Node {
int hash; int hash;
Key k; Key k;
Type value; Type value;
bool inUse() { bool inUse() {
return hash != 0; return hash != 0;
} }
 End of changes. 1 change blocks. 
4 lines changed or deleted 1 lines changed or added


 health.h   health.h 
skipping to change at line 24 skipping to change at line 24
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
namespace mongo { namespace mongo {
/* throws */ /* throws */
bool requestHeartbeat(string setname, string fromHost, string memberFul bool requestHeartbeat(const std::string& setname,
lName, BSONObj& result, int myConfigVersion, int& theirConfigVersion, bool const std::string& fromHost,
checkEmpty = false); const std::string& memberFullName,
BSONObj& result,
int myConfigVersion,
int& theirConfigVersion,
bool checkEmpty = false);
struct HealthOptions { struct HealthOptions {
HealthOptions() : HealthOptions() :
heartbeatSleepMillis(2000), heartbeatSleepMillis(2000),
heartbeatTimeoutMillis( 10000 ), heartbeatTimeoutMillis( 10000 ),
heartbeatConnRetries(2) heartbeatConnRetries(2)
{ } { }
bool isDefault() const { return *this == HealthOptions(); } bool isDefault() const { return *this == HealthOptions(); }
 End of changes. 1 change blocks. 
3 lines changed or deleted 7 lines changed or added


 hostandport.h   hostandport.h 
skipping to change at line 20 skipping to change at line 20
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#pragma once #pragma once
#include "mongo/db/cmdline.h" #include "sock.h"
#include "mongo/util/mongoutils/str.h" #include "../../db/cmdline.h"
#include "mongo/util/net/sock.h" #include "../mongoutils/str.h"
#include "mongo/bson/util/builder.h"
namespace mongo { namespace mongo {
using namespace mongoutils; using namespace mongoutils;
/** helper for manipulating host:port connection endpoints. /** helper for manipulating host:port connection endpoints.
*/ */
struct HostAndPort { struct HostAndPort {
HostAndPort() : _port(-1) { } HostAndPort() : _port(-1) { }
/** From a string hostname[:portnumber] /** From a string hostname[:portnumber]
Throws user assertion if bad config string or bad port #. Throws user assertion if bad config string or bad port #.
*/ */
HostAndPort(string s); HostAndPort(const std::string& s);
/** @param p port number. -1 is ok to use default. */ /** @param p port number. -1 is ok to use default. */
HostAndPort(string h, int p /*= -1*/) : _host(h), _port(p) { HostAndPort(const std::string& h, int p /*= -1*/) : _host(h), _port (p) {
verify( !str::startsWith(h, '#') ); verify( !str::startsWith(h, '#') );
} }
HostAndPort(const SockAddr& sock ) : _host( sock.getAddr() ) , _por t( sock.getPort() ) { } HostAndPort(const SockAddr& sock ) : _host( sock.getAddr() ) , _por t( sock.getPort() ) { }
static HostAndPort me(); static HostAndPort me();
bool operator<(const HostAndPort& r) const { bool operator<(const HostAndPort& r) const {
string h = host(); string h = host();
string rh = r.host(); string rh = r.host();
skipping to change at line 76 skipping to change at line 75
bool isLocalHost() const; bool isLocalHost() const;
/** /**
* @param includePort host:port if true, host otherwise * @param includePort host:port if true, host otherwise
*/ */
string toString( bool includePort=true ) const; string toString( bool includePort=true ) const;
operator string() const { return toString(); } operator string() const { return toString(); }
void append( StringBuilder& ss ) const;
bool empty() const { bool empty() const {
return _host.empty() && _port < 0; return _host.empty() && _port < 0;
} }
string host() const { string host() const {
return _host; return _host;
} }
int port() const { int port() const {
if (hasPort()) if (hasPort())
return _port; return _port;
return CmdLine::DefaultDBPort; return CmdLine::DefaultDBPort;
skipping to change at line 128 skipping to change at line 125
} }
} }
string h = getHostName(); string h = getHostName();
verify( !h.empty() ); verify( !h.empty() );
verify( h != "localhost" ); verify( h != "localhost" );
return HostAndPort(h, cmdLine.port); return HostAndPort(h, cmdLine.port);
} }
inline string HostAndPort::toString( bool includePort ) const { inline string HostAndPort::toString( bool includePort ) const {
if ( ! includePort ) string h = host();
return host();
StringBuilder ss;
append( ss );
return ss.str();
}
inline void HostAndPort::append( StringBuilder& ss ) const {
ss << host();
int p = port(); int p = port();
if ( ! includePort )
return h;
stringstream ss;
ss << h;
if ( p != -1 ) { if ( p != -1 ) {
ss << ':'; ss << ':';
#if defined(_DEBUG) #if defined(_DEBUG)
if( p >= 44000 && p < 44100 ) { if( p >= 44000 && p < 44100 ) {
log() << "warning: special debug port 44xxx used" << endl; log() << "warning: special debug port 44xxx used" << endl;
ss << p+1; ss << p+1;
} }
else else
ss << p; ss << p;
#else #else
ss << p; ss << p;
#endif #endif
} }
return ss.str();
} }
inline bool HostAndPort::isLocalHost() const { inline bool HostAndPort::isLocalHost() const {
string _host = host(); string _host = host();
return ( _host == "localhost" return ( _host == "localhost"
|| startsWith(_host.c_str(), "127.") || startsWith(_host.c_str(), "127.")
|| _host == "::1" || _host == "::1"
|| _host == "anonymous unix socket" || _host == "anonymous unix socket"
|| _host.c_str()[0] == '/' // unix socket || _host.c_str()[0] == '/' // unix socket
); );
skipping to change at line 183 skipping to change at line 175
_host = string(p,colon-p); _host = string(p,colon-p);
_port = port; _port = port;
} }
else { else {
// no port specified. // no port specified.
_host = p; _host = p;
_port = -1; _port = -1;
} }
} }
inline HostAndPort::HostAndPort(string s) { inline HostAndPort::HostAndPort(const std::string& s) {
init(s.c_str()); init(s.c_str());
} }
} }
 End of changes. 8 change blocks. 
21 lines changed or deleted 13 lines changed or added


 html.h   html.h 
// @file html.h // @file html.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
/* Things in the mongoutils namespace /* Things in the mongoutils namespace
(1) are not database specific, rather, true utilities (1) are not database specific, rather, true utilities
(2) are cross platform (2) are cross platform
(3) may require boost headers, but not libs (3) may require boost headers, but not libs
(4) are clean and easy to use in any c++ project without pulling in lots of other stuff (4) are clean and easy to use in any c++ project without pulling in lots of other stuff
*/ */
/* Copyright 2010 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sstream> #include <sstream>
namespace mongoutils { namespace mongoutils {
namespace html { namespace html {
using namespace std; using namespace std;
inline string _end() { return "</body></html>"; } inline string _end() { return "</body></html>"; }
inline string _table() { return "</table>\n\n"; } inline string _table() { return "</table>\n\n"; }
inline string _tr() { return "</tr>\n"; } inline string _tr() { return "</tr>\n"; }
inline string tr() { return "<tr>"; } inline string tr() { return "<tr>"; }
inline string tr(string a, string b) { inline string tr(const std::string& a, const std::string& b) {
stringstream ss; stringstream ss;
ss << "<tr><td>" << a << "</td><td>" << b << "</td></tr>\n"; ss << "<tr><td>" << a << "</td><td>" << b << "</td></tr>\n";
return ss.str(); return ss.str();
} }
template <class T> template <class T>
inline string td(T x) { inline string td(T x) {
stringstream ss; stringstream ss;
ss << "<td>" << x << "</td>"; ss << "<td>" << x << "</td>";
return ss.str(); return ss.str();
} }
inline string td(string x) { inline string td(const std::string& x) {
return "<td>" + x + "</td>"; return "<td>" + x + "</td>";
} }
inline string th(string x) { inline string th(const std::string& x) {
return "<th>" + x + "</th>"; return "<th>" + x + "</th>";
} }
inline void tablecell( stringstream& ss , bool b ) { inline void tablecell( stringstream& ss , bool b ) {
ss << "<td>" << (b ? "<b>X</b>" : "") << "</td>"; ss << "<td>" << (b ? "<b>X</b>" : "") << "</td>";
} }
template< typename T> template< typename T>
inline void tablecell( stringstream& ss , const T& t ) { inline void tablecell( stringstream& ss , const T& t ) {
ss << "<td>" << t << "</td>"; ss << "<td>" << t << "</td>";
skipping to change at line 83 skipping to change at line 84
ss << "<tr>"; ss << "<tr>";
while( *headers ) { while( *headers ) {
ss << "<th>" << *headers << "</th>"; ss << "<th>" << *headers << "</th>";
headers++; headers++;
} }
ss << "</tr>\n"; ss << "</tr>\n";
} }
return ss.str(); return ss.str();
} }
inline string start(string title) { inline string start(const std::string& title) {
stringstream ss; stringstream ss;
ss << "<html><head>\n<title>"; ss << "<html><head>\n<title>";
ss << title; ss << title;
ss << "</title>\n"; ss << "</title>\n";
ss << "<style type=\"text/css\" media=\"screen\">" ss << "<style type=\"text/css\" media=\"screen\">"
"body { font-family: helvetica, arial, san-serif }\n" "body { font-family: helvetica, arial, san-serif }\n"
"table { border-collapse:collapse; border-color:#999; margin -top:.5em }\n" "table { border-collapse:collapse; border-color:#999; margin -top:.5em }\n"
"th { background-color:#bbb; color:#000 }\n" "th { background-color:#bbb; color:#000 }\n"
"td,th { padding:.25em }\n" "td,th { padding:.25em }\n"
"</style>\n"; "</style>\n";
ss << "</head>\n<body>\n"; ss << "</head>\n<body>\n";
return ss.str(); return ss.str();
} }
inline string red(string contentHtml, bool color=true) { inline string red(const std::string& contentHtml, bool color=true) {
if( !color ) return contentHtml; if( !color ) return contentHtml;
stringstream ss; stringstream ss;
ss << "<span style=\"color:#A00;\">" << contentHtml << "</span> "; ss << "<span style=\"color:#A00;\">" << contentHtml << "</span> ";
return ss.str(); return ss.str();
} }
inline string grey(string contentHtml, bool color=true) { inline string grey(const std::string& contentHtml, bool color=true) {
if( !color ) return contentHtml; if( !color ) return contentHtml;
stringstream ss; stringstream ss;
ss << "<span style=\"color:#888;\">" << contentHtml << "</span> "; ss << "<span style=\"color:#888;\">" << contentHtml << "</span> ";
return ss.str(); return ss.str();
} }
inline string blue(string contentHtml, bool color=true) { inline string blue(const std::string& contentHtml, bool color=true) {
if( !color ) return contentHtml; if( !color ) return contentHtml;
stringstream ss; stringstream ss;
ss << "<span style=\"color:#00A;\">" << contentHtml << "</span> "; ss << "<span style=\"color:#00A;\">" << contentHtml << "</span> ";
return ss.str(); return ss.str();
} }
inline string yellow(string contentHtml, bool color=true) { inline string yellow(const std::string& contentHtml, bool color=tru e) {
if( !color ) return contentHtml; if( !color ) return contentHtml;
stringstream ss; stringstream ss;
ss << "<span style=\"color:#A80;\">" << contentHtml << "</span> "; ss << "<span style=\"color:#A80;\">" << contentHtml << "</span> ";
return ss.str(); return ss.str();
} }
inline string green(string contentHtml, bool color=true) { inline string green(const std::string& contentHtml, bool color=true ) {
if( !color ) return contentHtml; if( !color ) return contentHtml;
stringstream ss; stringstream ss;
ss << "<span style=\"color:#0A0;\">" << contentHtml << "</span> "; ss << "<span style=\"color:#0A0;\">" << contentHtml << "</span> ";
return ss.str(); return ss.str();
} }
inline string p(string contentHtml) { inline string p(const std::string& contentHtml) {
stringstream ss; stringstream ss;
ss << "<p>" << contentHtml << "</p>\n"; ss << "<p>" << contentHtml << "</p>\n";
return ss.str(); return ss.str();
} }
inline string h2(string contentHtml) { inline string h2(const std::string& contentHtml) {
stringstream ss; stringstream ss;
ss << "<h2>" << contentHtml << "</h2>\n"; ss << "<h2>" << contentHtml << "</h2>\n";
return ss.str(); return ss.str();
} }
/* does NOT escape the strings. */ /* does NOT escape the strings. */
inline string a(string href, string title="", string contentHtml = inline string a(const std::string& href,
"") { const std::string& title="",
const std::string& contentHtml = "") {
stringstream ss; stringstream ss;
ss << "<a"; ss << "<a";
if( !href.empty() ) ss << " href=\"" << href << '"'; if( !href.empty() ) ss << " href=\"" << href << '"';
if( !title.empty() ) ss << " title=\"" << title << '"'; if( !title.empty() ) ss << " title=\"" << title << '"';
ss << '>'; ss << '>';
if( !contentHtml.empty() ) { if( !contentHtml.empty() ) {
ss << contentHtml << "</a>"; ss << contentHtml << "</a>";
} }
return ss.str(); return ss.str();
} }
 End of changes. 14 change blocks. 
29 lines changed or deleted 32 lines changed or added


 httpclient.h   httpclient.h 
skipping to change at line 62 skipping to change at line 62
Headers _headers; Headers _headers;
string _body; string _body;
friend class HttpClient; friend class HttpClient;
}; };
/** /**
* @return response code * @return response code
*/ */
int get( string url , Result * result = 0 ); int get( const std::string& url , Result * result = 0 );
/** /**
* @return response code * @return response code
*/ */
int post( string url , string body , Result * result = 0 ); int post( const std::string& url , const std::string& body , Result * result = 0 );
private: private:
int _go( const char * command , string url , const char * body , Re sult * result ); int _go( const char * command , string url , const char * body , Re sult * result );
#ifdef MONGO_SSL #ifdef MONGO_SSL
void _checkSSLManager(); void _checkSSLManager();
scoped_ptr<SSLManager> _sslManager; scoped_ptr<SSLManager> _sslManager;
#endif #endif
}; };
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 index_update.h   index_update.h 
skipping to change at line 33 skipping to change at line 33
namespace mongo { namespace mongo {
class NamespaceDetails; class NamespaceDetails;
class Record; class Record;
// unindex all keys in index for this record. // unindex all keys in index for this record.
void unindexRecord(NamespaceDetails *d, Record *todelete, const DiskLoc & dl, bool noWarn = false); void unindexRecord(NamespaceDetails *d, Record *todelete, const DiskLoc & dl, bool noWarn = false);
// Build an index in the foreground // Build an index in the foreground
// If background is false, uses fast index builder // If background is false, uses fast index builder
// If background is true, uses background index builder; blocks until d one. // If background is true, uses background index builder; blocks until d one.
void buildAnIndex(string ns, NamespaceDetails *d, IndexDetails& idx, in void buildAnIndex(const std::string& ns,
t idxNo, bool background); NamespaceDetails *d,
IndexDetails& idx,
int idxNo,
bool background);
// add index keys for a newly inserted record // add index keys for a newly inserted record
// done in two steps/phases to allow potential deferal of write lock po rtion in the future // done in two steps/phases to allow potential deferal of write lock po rtion in the future
void indexRecordUsingTwoSteps(const char *ns, NamespaceDetails *d, BSON Obj obj, void indexRecordUsingTwoSteps(const char *ns, NamespaceDetails *d, BSON Obj obj,
DiskLoc loc, bool shouldBeUnlocked ); DiskLoc loc, bool shouldBeUnlocked );
// Given an object, populate "inserter" with information necessary to u pdate indexes. // Given an object, populate "inserter" with information necessary to u pdate indexes.
void fetchIndexInserters(BSONObjSet & /*out*/keys, void fetchIndexInserters(BSONObjSet & /*out*/keys,
IndexInterface::IndexInserter &inserter, IndexInterface::IndexInserter &inserter,
NamespaceDetails *d, NamespaceDetails *d,
 End of changes. 1 change blocks. 
2 lines changed or deleted 5 lines changed or added


 introspect.h   introspect.h 
skipping to change at line 32 skipping to change at line 32
#include "mongo/pch.h" #include "mongo/pch.h"
#include "jsobj.h" #include "jsobj.h"
#include "pdfile.h" #include "pdfile.h"
namespace mongo { namespace mongo {
/* --- profiling -------------------------------------------- /* --- profiling --------------------------------------------
do when database->profile is set do when database->profile is set
*/ */
void profile(const Client& c, int op, CurOp& currentOp); void profile( const Client& c , CurOp& currentOp );
/** /**
* Get (or create) the profile collection * Get (or create) the profile collection
* *
* @param db Database in which to create the profile collection * @param db Database in which to create the profile collection
* @param force Always create the collection if it does not exist * @param force Always create the collection if it does not exist
* @return NamespaceDetails for the newly created collection, or NULL on error * @return NamespaceDetails for the newly created collection, or NULL on error
**/ **/
NamespaceDetails* getOrCreateProfileCollection(Database *db, bool force = false); NamespaceDetails* getOrCreateProfileCollection(Database *db, bool force = false);
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 jsobj.h   jsobj.h 
skipping to change at line 43 skipping to change at line 43
#include "../util/optime.h" #include "../util/optime.h"
#include "../bson/bsontypes.h" #include "../bson/bsontypes.h"
#include "../bson/oid.h" #include "../bson/oid.h"
#include "../bson/bsonelement.h" #include "../bson/bsonelement.h"
#include "../bson/bsonobj.h" #include "../bson/bsonobj.h"
#include "../bson/bsonmisc.h" #include "../bson/bsonmisc.h"
#include "../bson/bsonobjbuilder.h" #include "../bson/bsonobjbuilder.h"
#include "../bson/bsonobjiterator.h" #include "../bson/bsonobjiterator.h"
#include "../bson/bson-inl.h" #include "../bson/bson-inl.h"
#include "../bson/ordering.h" #include "../bson/ordering.h"
#include "../bson/stringdata.h" #include "mongo/base/string_data.h"
#include "../bson/bson_db.h" #include "../bson/bson_db.h"
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 lasterror.h   lasterror.h 
skipping to change at line 32 skipping to change at line 32
namespace mongo { namespace mongo {
class BSONObjBuilder; class BSONObjBuilder;
class Message; class Message;
struct LastError { struct LastError {
int code; int code;
string msg; string msg;
enum UpdatedExistingType { NotUpdate, True, False } updatedExisting ; enum UpdatedExistingType { NotUpdate, True, False } updatedExisting ;
OID upsertedId; OID upsertedId;
OID writebackId; // this shouldn't get reset so that old GLE are ha ndled OID writebackId; // this shouldn't get reset so that old GLE are ha ndled
int writebackSince;
long long nObjects; long long nObjects;
int nPrev; int nPrev;
bool valid; bool valid;
bool disabled; bool disabled;
void writeback( OID& oid ) { void writeback( OID& oid ) {
reset( true ); reset( true );
writebackId = oid; writebackId = oid;
writebackSince = 0;
} }
void raiseError(int _code , const char *_msg) { void raiseError(int _code , const char *_msg) {
reset( true ); reset( true );
code = _code; code = _code;
msg = _msg; msg = _msg;
} }
void recordUpdate( bool _updateObjects , long long _nObjects , OID _upsertedId ) { void recordUpdate( bool _updateObjects , long long _nObjects , OID _upsertedId ) {
reset( true ); reset( true );
nObjects = _nObjects; nObjects = _nObjects;
updatedExisting = _updateObjects ? True : False; updatedExisting = _updateObjects ? True : False;
if ( _upsertedId.isSet() ) if ( _upsertedId.isSet() )
upsertedId = _upsertedId; upsertedId = _upsertedId;
} }
void recordDelete( long long nDeleted ) { void recordDelete( long long nDeleted ) {
reset( true ); reset( true );
nObjects = nDeleted; nObjects = nDeleted;
} }
LastError() { LastError() {
reset(); reset();
writebackSince = 0;
} }
void reset( bool _valid = false ) { void reset( bool _valid = false ) {
code = 0; code = 0;
msg.clear(); msg.clear();
updatedExisting = NotUpdate; updatedExisting = NotUpdate;
nObjects = 0; nObjects = 0;
nPrev = 1; nPrev = 1;
valid = _valid; valid = _valid;
disabled = false; disabled = false;
upsertedId.clear(); upsertedId.clear();
 End of changes. 3 change blocks. 
3 lines changed or deleted 0 lines changed or added


 list.h   list.h 
skipping to change at line 23 skipping to change at line 23
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
namespace mongo { namespace mongo {
/* DONT USE THIS. it was a dumb idea. /* DON'T USE THIS. it was a dumb idea.
this class uses a mutex for writes, but not for reads. this class uses a mutex for writes, but not for reads.
we can get fancier later... we can get fancier later...
struct Member : public List1<Member>::Base { struct Member : public List1<Member>::Base {
const char *host; const char *host;
int port; int port;
}; };
List1<Member> _members; List1<Member> _members;
_members.head()->next(); _members.head()->next();
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 listen.h   listen.h 
skipping to change at line 21 skipping to change at line 21
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#pragma once #pragma once
#include "sock.h" #include "sock.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/util/concurrency/ticketholder.h" #include "mongo/util/concurrency/ticketholder.h"
namespace mongo { namespace mongo {
const int DEFAULT_MAX_CONN = 20000; const int DEFAULT_MAX_CONN = 20000;
const int MAX_MAX_CONN = 20000; const int MAX_MAX_CONN = 20000;
class MessagingPort; class MessagingPort;
class Listener : boost::noncopyable { class Listener : boost::noncopyable {
skipping to change at line 97 skipping to change at line 98
/** /**
* @return true iff everything went ok * @return true iff everything went ok
*/ */
bool _setupSockets( const vector<SockAddr>& mine , vector<SOCKET>& socks ); bool _setupSockets( const vector<SockAddr>& mine , vector<SOCKET>& socks );
void _logListen( int port , bool ssl ); void _logListen( int port , bool ssl );
static const Listener* _timeTracker; static const Listener* _timeTracker;
virtual bool useUnixSockets() const { return false; } virtual bool useUnixSockets() const { return false; }
public:
/** the "next" connection number. every connection to this process
has a unique number */
static AtomicInt64 globalConnectionNumber;
/** keeps track of how many allowed connections there are and how m
any are being used*/
static TicketHolder globalTicketHolder;
/** makes sure user input is sane */
static void checkTicketNumbers();
}; };
/** /**
* keep track of elapsed time * keep track of elapsed time
* after a set amount of time, tells you to do something * after a set amount of time, tells you to do something
* only in this file because depends on Listener * only in this file because depends on Listener
*/ */
class ElapsedTracker { class ElapsedTracker {
public: public:
ElapsedTracker( int hitsBetweenMarks , int msBetweenMarks ) ElapsedTracker( int hitsBetweenMarks , int msBetweenMarks )
skipping to change at line 155 skipping to change at line 166
public: public:
ListeningSockets() ListeningSockets()
: _mutex("ListeningSockets") : _mutex("ListeningSockets")
, _sockets( new set<int>() ) , _sockets( new set<int>() )
, _socketPaths( new set<string>() ) , _socketPaths( new set<string>() )
{ } { }
void add( int sock ) { void add( int sock ) {
scoped_lock lk( _mutex ); scoped_lock lk( _mutex );
_sockets->insert( sock ); _sockets->insert( sock );
} }
void addPath( string path ) { void addPath( const std::string& path ) {
scoped_lock lk( _mutex ); scoped_lock lk( _mutex );
_socketPaths->insert( path ); _socketPaths->insert( path );
} }
void remove( int sock ) { void remove( int sock ) {
scoped_lock lk( _mutex ); scoped_lock lk( _mutex );
_sockets->erase( sock ); _sockets->erase( sock );
} }
void closeAll() { void closeAll() {
set<int>* sockets; set<int>* sockets;
set<string>* paths; set<string>* paths;
skipping to change at line 195 skipping to change at line 206
} }
} }
static ListeningSockets* get(); static ListeningSockets* get();
private: private:
mongo::mutex _mutex; mongo::mutex _mutex;
set<int>* _sockets; set<int>* _sockets;
set<string>* _socketPaths; // for unix domain sockets set<string>* _socketPaths; // for unix domain sockets
static ListeningSockets* _instance; static ListeningSockets* _instance;
}; };
extern TicketHolder connTicketHolder;
} }
 End of changes. 4 change blocks. 
3 lines changed or deleted 14 lines changed or added


 log.h   log.h 
skipping to change at line 41 skipping to change at line 41
#include "mongo/util/exit_code.h" #include "mongo/util/exit_code.h"
#ifndef _WIN32 #ifndef _WIN32
#include <syslog.h> #include <syslog.h>
#endif #endif
namespace mongo { namespace mongo {
enum ExitCode; enum ExitCode;
// using negative numbers so these are always less than ::mongo::loglev enum LogLevel { LL_DEBUG , LL_INFO , LL_NOTICE , LL_WARNING , LL_ERROR
el (see MONGO_LOG) , LL_SEVERE };
enum LogLevel { LL_DEBUG=-1000 , LL_INFO , LL_NOTICE , LL_WARNING , LL
_ERROR , LL_SEVERE };
inline const char * logLevelToString( LogLevel l ) { inline const char * logLevelToString( LogLevel l ) {
switch ( l ) { switch ( l ) {
case LL_DEBUG: case LL_DEBUG:
case LL_INFO: case LL_INFO:
case LL_NOTICE: case LL_NOTICE:
return ""; return "";
case LL_WARNING: case LL_WARNING:
return "warning" ; return "warning" ;
case LL_ERROR: case LL_ERROR:
skipping to change at line 98 skipping to change at line 97
LabeledLevel operator+( int i ) const { LabeledLevel operator+( int i ) const {
return LabeledLevel( _label, _level + i ); return LabeledLevel( _label, _level + i );
} }
LabeledLevel operator+( const char* label ) const { LabeledLevel operator+( const char* label ) const {
if( _label == "" ) if( _label == "" )
return LabeledLevel( label, _level ); return LabeledLevel( label, _level );
return LabeledLevel( _label + string("::") + label, _level ); return LabeledLevel( _label + string("::") + label, _level );
} }
LabeledLevel operator+( string& label ) const { LabeledLevel operator+( const std::string& label ) const {
return LabeledLevel( _label + string("::") + label, _level ); return LabeledLevel( _label + string("::") + label, _level );
} }
LabeledLevel operator-( int i ) const { LabeledLevel operator-( int i ) const {
return LabeledLevel( _label, _level - i ); return LabeledLevel( _label, _level - i );
} }
const string& getLabel() const { return _label; } const string& getLabel() const { return _label; }
int getLevel() const { return _level; } int getLevel() const { return _level; }
private: private:
string _label; string _label;
int _level; int _level;
}; };
inline bool operator<( const LabeledLevel& ll, const int i ) { return l
l.getLevel() < i; }
inline bool operator<( const int i, const LabeledLevel& ll ) { return i
< ll.getLevel(); }
inline bool operator>( const LabeledLevel& ll, const int i ) { return l
l.getLevel() > i; }
inline bool operator>( const int i, const LabeledLevel& ll ) { return i
> ll.getLevel(); }
inline bool operator<=( const LabeledLevel& ll, const int i ) { return
ll.getLevel() <= i; }
inline bool operator<=( const int i, const LabeledLevel& ll ) { return
i <= ll.getLevel(); }
inline bool operator>=( const LabeledLevel& ll, const int i ) { return
ll.getLevel() >= i; }
inline bool operator>=( const int i, const LabeledLevel& ll ) { return
i >= ll.getLevel(); }
inline bool operator==( const LabeledLevel& ll, const int i ) { return
ll.getLevel() == i; }
inline bool operator==( const int i, const LabeledLevel& ll ) { return
i == ll.getLevel(); }
class LazyString { class LazyString {
public: public:
virtual ~LazyString() {} virtual ~LazyString() {}
virtual string val() const = 0; virtual string val() const = 0;
}; };
// Utility class for stringifying object only when val() called. // Utility class for stringifying object only when val() called.
template< class T > template< class T >
class LazyStringImpl : public LazyString { class LazyStringImpl : public LazyString {
public: public:
skipping to change at line 344 skipping to change at line 332
globalTees->push_back( t ); globalTees->push_back( t );
} }
void removeGlobalTee( Tee * tee ); void removeGlobalTee( Tee * tee );
void indentInc(){ indent++; } void indentInc(){ indent++; }
void indentDec(){ indent--; } void indentDec(){ indent--; }
int getIndent() const { return indent; } int getIndent() const { return indent; }
private: private:
static boost::thread_specific_ptr<Logstream> tsp;
Logstream() { Logstream() {
indent = 0; indent = 0;
_init(); _init();
} }
void _init() { void _init() {
ss.str(""); ss.str("");
logLevel = LL_INFO; logLevel = LL_INFO;
} }
public: public:
static Logstream& get(); static Logstream& get();
skipping to change at line 390 skipping to change at line 379
set tlogLevel to -1 to suppress tlog() output in a test program. */ set tlogLevel to -1 to suppress tlog() output in a test program. */
Nullstream& tlog( int level = 0 ); Nullstream& tlog( int level = 0 );
// log if debug build or if at a certain level // log if debug build or if at a certain level
inline Nullstream& dlog( int level ) { inline Nullstream& dlog( int level ) {
if ( level <= logLevel || DEBUG_BUILD ) if ( level <= logLevel || DEBUG_BUILD )
return Logstream::get().prolog(); return Logstream::get().prolog();
return nullstream; return nullstream;
} }
#define MONGO_LOG(level) \ inline Nullstream& log( int level ) {
( MONGO_likely( ::mongo::logLevel < (level) ) ) \
? ::mongo::nullstream : ::mongo::logWithLevel(level)
#define LOG MONGO_LOG
inline Nullstream& log() {
return Logstream::get().prolog();
}
// Use MONGO_LOG() instead of this
inline Nullstream& logWithLevel( int level ) {
if ( level > logLevel ) if ( level > logLevel )
return nullstream; return nullstream;
return Logstream::get().prolog(); return Logstream::get().prolog();
} }
inline Nullstream& logWithLevel( LogLevel l ) { #define MONGO_LOG(level) if ( MONGO_likely(logLevel < (level)) ) { } else l
og( level )
#define LOG MONGO_LOG
inline Nullstream& log( LogLevel l ) {
return Logstream::get().prolog().setLogLevel( l ); return Logstream::get().prolog().setLogLevel( l );
} }
inline Nullstream& logWithLevel( const LabeledLevel& ll ) { inline Nullstream& log( const LabeledLevel& ll ) {
Nullstream& stream = logWithLevel( ll.getLevel() ); Nullstream& stream = log( ll.getLevel() );
if( ll.getLabel() != "" ) if( ll.getLabel() != "" )
stream << "[" << ll.getLabel() << "] "; stream << "[" << ll.getLabel() << "] ";
return stream; return stream;
} }
inline Nullstream& log() {
return Logstream::get().prolog();
}
inline Nullstream& error() { inline Nullstream& error() {
return logWithLevel( LL_ERROR ); return log( LL_ERROR );
} }
inline Nullstream& warning() { inline Nullstream& warning() {
return logWithLevel( LL_WARNING ); return log( LL_WARNING );
} }
/* default impl returns "" -- mongod overrides */ /* default impl returns "" -- mongod overrides */
extern const char * (*getcurns)(); extern const char * (*getcurns)();
inline Nullstream& problem( int level = 0 ) { inline Nullstream& problem( int level = 0 ) {
if ( level > logLevel ) if ( level > logLevel )
return nullstream; return nullstream;
Logstream& l = Logstream::get().prolog(); Logstream& l = Logstream::get().prolog();
l << ' ' << getcurns() << ' '; l << ' ' << getcurns() << ' ';
 End of changes. 10 change blocks. 
42 lines changed or deleted 18 lines changed or added


 logfile.h   logfile.h 
skipping to change at line 28 skipping to change at line 28
#pragma once #pragma once
namespace mongo { namespace mongo {
class LogFile { class LogFile {
public: public:
/** create the file and open. must not already exist. /** create the file and open. must not already exist.
throws UserAssertion on i/o error throws UserAssertion on i/o error
*/ */
LogFile(string name, bool readwrite = false); LogFile(const std::string& name, bool readwrite = false);
/** closes */ /** closes */
~LogFile(); ~LogFile();
/** append to file. does not return until sync'd. uses direct i/o when possible. /** append to file. does not return until sync'd. uses direct i/o when possible.
throws UserAssertion on an i/o error throws UserAssertion on an i/o error
note direct i/o may have alignment requirements note direct i/o may have alignment requirements
*/ */
void synchronousAppend(const void *buf, size_t len); void synchronousAppend(const void *buf, size_t len);
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 map_util.h   map_util.h 
skipping to change at line 20 skipping to change at line 20
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#pragma once #pragma once
#include <map>
namespace mongo { namespace mongo {
/* /*
* If "myMap" contains "key", returns "myMap[key]". Otherwise, returns "d efaultValue." * If "myMap" contains "key", returns "myMap[key]". Otherwise, returns "d efaultValue."
*/ */
template <typename K, typename V> template <typename M, typename K, typename V>
V mapFindWithDefault(const map<K,V>& myMap, const K& key, const V& defaultV V mapFindWithDefault(const M& myMap, const K& key, const V& defaultValue) {
alue) { typename M::const_iterator it = myMap.find(key);
typename std::map<K,V>::const_iterator it = myMap.find(key); if(it == myMap.end())
if(it == myMap.end()) return defaultValue;
return defaultValue; return it->second;
return it->second;
} }
} // end namespace } // end namespace
 End of changes. 2 change blocks. 
9 lines changed or deleted 6 lines changed or added


 mapsf.h   mapsf.h 
#pragma once #pragma once
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mongo/platform/unordered_map.h"
namespace mongo { namespace mongo {
/** Thread safe map. /** Thread safe map.
Be careful not to use this too much or it could make things slow; Be careful not to use this too much or it could make things slow;
if not a hot code path no problem. if not a hot code path no problem.
Examples: Examples:
mapsf<int,int> mp; mapsf<int,int> mp;
skipping to change at line 28 skipping to change at line 46
{ {
mapsf<int,int>::ref r(mp); mapsf<int,int>::ref r(mp);
r[9] = 1; r[9] = 1;
map<int,int>::iterator i = r.r.begin(); map<int,int>::iterator i = r.r.begin();
} }
*/ */
template< class K, class V > template< class K, class V >
struct mapsf : boost::noncopyable { struct mapsf : boost::noncopyable {
SimpleMutex m; SimpleMutex m;
map<K,V> val; unordered_map<K,V> val;
friend struct ref; friend struct ref;
public: public:
mapsf() : m("mapsf") { } mapsf() : m("mapsf") { }
void swap(map<K,V>& rhs) { void swap(unordered_map<K,V>& rhs) {
SimpleMutex::scoped_lock lk(m); SimpleMutex::scoped_lock lk(m);
val.swap(rhs); val.swap(rhs);
} }
bool empty() { bool empty() {
SimpleMutex::scoped_lock lk(m); SimpleMutex::scoped_lock lk(m);
return val.empty(); return val.empty();
} }
// safe as we pass by value: // safe as we pass by value:
V get(K k) { V get(K k) {
SimpleMutex::scoped_lock lk(m); SimpleMutex::scoped_lock lk(m);
typename map<K,V>::iterator i = val.find(k); typename unordered_map<K,V>::iterator i = val.find(k);
if( i == val.end() ) if( i == val.end() )
return V(); return V();
return i->second; return i->second;
} }
// think about deadlocks when using ref. the other methods // think about deadlocks when using ref. the other methods
// above will always be safe as they are "leaf" operations. // above will always be safe as they are "leaf" operations.
struct ref { struct ref {
SimpleMutex::scoped_lock lk; SimpleMutex::scoped_lock lk;
public: public:
map<K,V> &r; unordered_map<K,V> &r;
ref(mapsf<K,V> &m) : lk(m.m), r(m.val) { } ref(mapsf<K,V> &m) : lk(m.m), r(m.val) { }
V& operator[](const K& k) { return r[k]; } V& operator[](const K& k) { return r[k]; }
}; };
}; };
} }
 End of changes. 5 change blocks. 
4 lines changed or deleted 24 lines changed or added


 matcher.h   matcher.h 
skipping to change at line 25 skipping to change at line 25
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include "jsobj.h" #include "jsobj.h"
#include "pcrecpp.h" #include "pcrecpp.h"
#include "geo/shapes.h"
namespace mongo { namespace mongo {
class Cursor; class Cursor;
class CoveredIndexMatcher; class CoveredIndexMatcher;
class ElementMatcher; class ElementMatcher;
class Matcher; class Matcher;
class FieldRangeVector; class FieldRangeVector;
class RegexMatcher { class RegexMatcher {
public: public:
/**
* Maximum pattern size which pcre v8.3 can do matches correctly wi
th
* LINK_SIZE define macro set to 2 @ pcre's config.h (based on
* experiments)
*/
static const size_t MaxPatternSize = 32764;
const char *_fieldName; const char *_fieldName;
const char *_regex; const char *_regex;
const char *_flags; const char *_flags;
string _prefix; string _prefix;
shared_ptr< pcrecpp::RE > _re; shared_ptr< pcrecpp::RE > _re;
bool _isNot; bool _isNot;
RegexMatcher() : _isNot() {} RegexMatcher() : _isNot() {}
}; };
class GeoMatcher {
private:
GeoMatcher(const string& field) : _isBox(false), _isCircle(false),
_isPolygon(false),
_fieldName(field) {}
bool _isBox;
Box _box;
bool _isCircle;
Point _center;
double _radius;
bool _isPolygon;
Polygon _polygon;
string _fieldName;
public:
const string& getFieldName() const { return _fieldName; }
static GeoMatcher makeBox(const string& field, const BSONObj &min,
const BSONObj &max) {
GeoMatcher m(field);
m._isBox = true;
uassert(16470, "Malformed coord: " + min.toString(), pointFrom(
min, &m._box._min));
uassert(16471, "Malformed coord: " + max.toString(), pointFrom(
max, &m._box._max));
return m;
}
static GeoMatcher makeCircle(const string& field, const BSONObj &ce
nter, double rad) {
GeoMatcher m(field);
m._isCircle = true;
uassert(16472, "Malformed coord: " + center.toString(), pointFr
om(center, &m._center));
m._radius = rad;
return m;
}
static GeoMatcher makePolygon(const string& field, const BSONObj &p
oly) {
GeoMatcher m(field);
vector<Point> points;
m._isPolygon = true;
BSONObjIterator coordIt(poly);
while (coordIt.more()) {
BSONElement coord = coordIt.next();
const BSONObj& obj = coord.Obj();
Point p;
uassert(16480, "Malformed coord: " + obj.toString(), pointF
rom(obj, &p));
points.push_back(p);
}
m._polygon = Polygon(points);
return m;
}
bool containsPoint(Point p) const {
if (_isBox) {
return _box.inside(p, 0);
} else if (_isCircle) {
return _center.distance(p) <= _radius;
} else if (_isPolygon) {
return _polygon.contains(p);
} else {
return false;
}
}
string toString() const {
stringstream ss;
if (_isBox) {
ss << "GeoMatcher Box: " << _box.toString();
} else if (_isCircle) {
ss << "GeoMatcher Circle @ " << _center.toString() << " r =
" << _radius;
} else {
ss << "GeoMatcher UNKNOWN";
}
return ss.str();
}
static bool pointFrom(const BSONObj o, Point *p) {
BSONObjIterator i(o);
if (!i.more()) { return false; }
BSONElement xe = i.next();
if (!i.more()) { return false; }
BSONElement ye = i.next();
if (!xe.isNumber() || !ye.isNumber()) { return false; }
p->_x = xe.number();
p->_y = ye.number();
return true;
}
};
struct element_lt { struct element_lt {
bool operator()(const BSONElement& l, const BSONElement& r) const { bool operator()(const BSONElement& l, const BSONElement& r) const {
int x = (int) l.canonicalType() - (int) r.canonicalType(); int x = (int) l.canonicalType() - (int) r.canonicalType();
if ( x < 0 ) return true; if ( x < 0 ) return true;
else if ( x > 0 ) return false; else if ( x > 0 ) return false;
return compareElementValues(l,r) < 0; return compareElementValues(l,r) < 0;
} }
}; };
/** /**
skipping to change at line 358 skipping to change at line 276
bool _haveNeg; bool _haveNeg;
/* $atomic - if true, a multi document operation (some removes, upd ates) /* $atomic - if true, a multi document operation (some removes, upd ates)
should be done atomically. in that case, we do not yi eld - should be done atomically. in that case, we do not yi eld -
i.e. we stay locked the whole time. i.e. we stay locked the whole time.
http://dochub.mongodb.org/core/remove http://dochub.mongodb.org/core/remove
*/ */
bool _atomic; bool _atomic;
vector<RegexMatcher> _regexs; vector<RegexMatcher> _regexs;
vector<GeoMatcher> _geo;
// so we delete the mem when we're done: // so we delete the mem when we're done:
vector< shared_ptr< BSONObjBuilder > > _builders; vector< shared_ptr< BSONObjBuilder > > _builders;
list< shared_ptr< Matcher > > _andMatchers; list< shared_ptr< Matcher > > _andMatchers;
list< shared_ptr< Matcher > > _orMatchers; list< shared_ptr< Matcher > > _orMatchers;
list< shared_ptr< Matcher > > _norMatchers; list< shared_ptr< Matcher > > _norMatchers;
friend class CoveredIndexMatcher; friend class CoveredIndexMatcher;
}; };
 End of changes. 4 change blocks. 
99 lines changed or deleted 8 lines changed or added


 md5.hpp   md5.hpp 
skipping to change at line 53 skipping to change at line 53
} }
return ss.str(); return ss.str();
} }
inline std::string md5simpledigest( const void* buf, int nbytes){ inline std::string md5simpledigest( const void* buf, int nbytes){
md5digest d; md5digest d;
md5( buf, nbytes , d ); md5( buf, nbytes , d );
return digestToString( d ); return digestToString( d );
} }
inline std::string md5simpledigest( string s ){ inline std::string md5simpledigest( const std::string& s ){
return md5simpledigest(s.data(), s.size()); return md5simpledigest(s.data(), s.size());
} }
} // namespace mongo } // namespace mongo
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 memconcept.h   memconcept.h 
#pragma once #pragma once
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* The idea here is to 'name' memory pointers so that we can do diagnostics . /* The idea here is to 'name' memory pointers so that we can do diagnostics .
these diagnostics might involve concurrency or other things. mainly wou ld these diagnostics might involve concurrency or other things. mainly wou ld
be for _DEBUG builds. Experimental we'll see how useful. be for _DEBUG builds. Experimental we'll see how useful.
*/ */
namespace mongo { namespace mongo {
namespace memconcept { namespace memconcept {
/** these are like fancy enums - you can use them as "types" of thi ngs /** these are like fancy enums - you can use them as "types" of thi ngs
and see if foo.concept == bar.concept. and see if foo.concept == bar.concept.
skipping to change at line 40 skipping to change at line 56
private: private:
const char * c; const char * c;
concept(const char *); concept(const char *);
}; };
/** file was unmapped or something */ /** file was unmapped or something */
void invalidate(void *p, unsigned len=0); void invalidate(void *p, unsigned len=0);
/** note you can be more than one thing; a datafile header is also the starting pointer /** note you can be more than one thing; a datafile header is also the starting pointer
for a file */ for a file */
void is(void *p, concept c, std::string desc = "", unsigned len=0); void is(void *p, concept c, const std::string desc = "", unsigned l en=0);
#if 1 #if 1
//#if !defined(_DEBUG) //#if !defined(_DEBUG)
inline void invalidate(void *p, unsigned len) { } inline void invalidate(void *p, unsigned len) { }
inline void is(void *p, concept c, std::string, unsigned) { } inline void is(void *p, concept c, const std::string, unsigned) { }
#endif #endif
} }
} }
 End of changes. 3 change blocks. 
2 lines changed or deleted 20 lines changed or added


 message.h   message.h 
skipping to change at line 94 skipping to change at line 94
} }
#pragma pack(1) #pragma pack(1)
/* see http://dochub.mongodb.org/core/mongowireprotocol /* see http://dochub.mongodb.org/core/mongowireprotocol
*/ */
struct MSGHEADER { struct MSGHEADER {
int messageLength; // total message size, including this int messageLength; // total message size, including this
int requestID; // identifier for this message int requestID; // identifier for this message
int responseTo; // requestID from the original request int responseTo; // requestID from the original request
// (used in reponses from db) // (used in responses from db)
int opCode; int opCode;
}; };
#pragma pack() #pragma pack()
#pragma pack(1) #pragma pack(1)
/* todo merge this with MSGHEADER (or inherit from it). */ /* todo merge this with MSGHEADER (or inherit from it). */
struct MsgData { struct MsgData {
int len; /* len of the msg, including this field */ int len; /* len of the msg, including this field */
MSGID id; /* request/reply id's match... */ MSGID id; /* request/reply id's match... */
MSGID responseTo; /* id of the message we are responding to */ MSGID responseTo; /* id of the message we are responding to */
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 message_port.h   message_port.h 
skipping to change at line 66 skipping to change at line 66
// in some cases the timeout will actually be 2x this value - eg we do a partial send, // in some cases the timeout will actually be 2x this value - eg we do a partial send,
// then the timeout fires, then we try to send again, then the time out fires again with // then the timeout fires, then we try to send again, then the time out fires again with
// no data sent, then we detect that the other side is down // no data sent, then we detect that the other side is down
MessagingPort(double so_timeout = 0, int logLevel = 0 ); MessagingPort(double so_timeout = 0, int logLevel = 0 );
MessagingPort(boost::shared_ptr<Socket> socket); MessagingPort(boost::shared_ptr<Socket> socket);
virtual ~MessagingPort(); virtual ~MessagingPort();
void setSocketTimeout(double timeout);
void shutdown(); void shutdown();
/* it's assumed if you reuse a message object, that it doesn't cros s MessagingPort's. /* it's assumed if you reuse a message object, that it doesn't cros s MessagingPort's.
also, the Message data will go out of scope on the subsequent re cv call. also, the Message data will go out of scope on the subsequent re cv call.
*/ */
bool recv(Message& m); bool recv(Message& m);
void reply(Message& received, Message& response, MSGID responseTo); void reply(Message& received, Message& response, MSGID responseTo);
void reply(Message& received, Message& response); void reply(Message& received, Message& response);
bool call(Message& toSend, Message& response); bool call(Message& toSend, Message& response);
void say(Message& toSend, int responseTo = -1); void say(Message& toSend, int responseTo = -1);
/** /**
* this is used for doing 'async' queries * this is used for doing 'async' queries
* instead of doing call( to , from ) * instead of doing call( to , from )
* you would do * you would do
* say( to ) * say( to )
* recv( from ) * recv( from )
* Note: if you fail to call recv and someone else uses this port, * Note: if you fail to call recv and someone else uses this port,
* horrible things will happend * horrible things will happen
*/ */
bool recv( const Message& sent , Message& response ); bool recv( const Message& sent , Message& response );
void piggyBack( Message& toSend , int responseTo = -1 ); void piggyBack( Message& toSend , int responseTo = -1 );
unsigned remotePort() const { return psock->remotePort(); } unsigned remotePort() const { return psock->remotePort(); }
virtual HostAndPort remote() const; virtual HostAndPort remote() const;
boost::shared_ptr<Socket> psock; boost::shared_ptr<Socket> psock;
 End of changes. 2 change blocks. 
1 lines changed or deleted 3 lines changed or added


 miniwebserver.h   miniwebserver.h 
skipping to change at line 49 skipping to change at line 49
vector<string>& headers, // if completely empty, content-type: text/html will be added vector<string>& headers, // if completely empty, content-type: text/html will be added
const SockAddr &from const SockAddr &from
) = 0; ) = 0;
// --- static helpers ---- // --- static helpers ----
static void parseParams( BSONObj & params , string query ); static void parseParams( BSONObj & params , string query );
static string parseURL( const char * buf ); static string parseURL( const char * buf );
static string parseMethod( const char * headers ); static string parseMethod( const char * headers );
static string getHeader( const char * headers , string name ); static string getHeader( const char * headers , const std::string& name );
static const char *body( const char *buf ); static const char *body( const char *buf );
static string urlDecode(const char* s); static string urlDecode(const char* s);
static string urlDecode(string s) {return urlDecode(s.c_str());} static string urlDecode(const std::string& s) {return urlDecode(s.c _str());}
private: private:
void accepted(boost::shared_ptr<Socket> psocket, long long connecti onId ); void accepted(boost::shared_ptr<Socket> psocket, long long connecti onId );
static bool fullReceive( const char *buf ); static bool fullReceive( const char *buf );
}; };
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 mk_wcwidth.h   mk_wcwidth.h 
/* /*
* Copyright (C) 2007 Markus Kuhn
*
* This is an implementation of wcwidth() and wcswidth() (defined in * This is an implementation of wcwidth() and wcswidth() (defined in
* IEEE Std 1002.1-2001) for Unicode. * IEEE Std 1002.1-2001) for Unicode.
* *
* http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
* http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
* *
* In fixed-width output devices, Latin characters all occupy a single * In fixed-width output devices, Latin characters all occupy a single
* "cell" position of equal width, whereas ideographic CJK characters * "cell" position of equal width, whereas ideographic CJK characters
* occupy two such cells. Interoperability between terminal-line * occupy two such cells. Interoperability between terminal-line
* applications and (teletype-style) character terminals using the * applications and (teletype-style) character terminals using the
 End of changes. 1 change blocks. 
0 lines changed or deleted 2 lines changed or added


 mmap.h   mmap.h 
skipping to change at line 54 skipping to change at line 54
/** era changes anytime memory maps come and go. thus you can use this as a cheap way to check /** era changes anytime memory maps come and go. thus you can use this as a cheap way to check
if nothing has changed since the last time you locked. Of cour se you must be shared locked if nothing has changed since the last time you locked. Of cour se you must be shared locked
at the time of this call, otherwise someone could be in progres s. at the time of this call, otherwise someone could be in progres s.
This is used for yielding; see PageFaultException::touch(). This is used for yielding; see PageFaultException::touch().
*/ */
static unsigned getEra() { return era; } static unsigned getEra() { return era; }
static void assertExclusivelyLocked() { mmmutex.assertExclusivelyLo cked(); } static void assertExclusivelyLocked() { mmmutex.assertExclusivelyLo cked(); }
static void assertAtLeastReadLocked() { mmmutex.assertAtLeastReadLo cked(); }
}; };
class LockMongoFilesExclusive { class LockMongoFilesExclusive {
RWLockRecursive::Exclusive lk; RWLockRecursive::Exclusive lk;
public: public:
LockMongoFilesExclusive() : lk(LockMongoFilesShared::mmmutex) { LockMongoFilesExclusive() : lk(LockMongoFilesShared::mmmutex) {
LockMongoFilesShared::era++; LockMongoFilesShared::era++;
} }
}; };
skipping to change at line 82 skipping to change at line 83
}; };
virtual ~MongoFile() {} virtual ~MongoFile() {}
enum Options { enum Options {
SEQUENTIAL = 1, // hint - e.g. FILE_FLAG_SEQUENTIAL_SCAN on win dows SEQUENTIAL = 1, // hint - e.g. FILE_FLAG_SEQUENTIAL_SCAN on win dows
READONLY = 2 // not contractually guaranteed, but if specifi ed the impl has option to fault writes READONLY = 2 // not contractually guaranteed, but if specifi ed the impl has option to fault writes
}; };
/** @param fun is called for each MongoFile. /** @param fun is called for each MongoFile.
calledl from within a mutex that MongoFile uses. so be careful not to deadlock. called from within a mutex that MongoFile uses. so be careful n ot to deadlock.
*/ */
template < class F > template < class F >
static void forEach( F fun ); static void forEach( F fun );
/** note: you need to be in mmmutex when using this. forEach (above ) handles that for you automatically. /** note: you need to be in mmmutex when using this. forEach (above ) handles that for you automatically.
*/ */
static set<MongoFile*>& getAllFiles() { return mmfiles; } static set<MongoFile*>& getAllFiles();
// callbacks if you need them // callbacks if you need them
static void (*notifyPreFlush)(); static void (*notifyPreFlush)();
static void (*notifyPostFlush)(); static void (*notifyPostFlush)();
static int flushAll( bool sync ); // returns n flushed static int flushAll( bool sync ); // returns n flushed
static long long totalMappedLength(); static long long totalMappedLength();
static void closeAllFiles( stringstream &message ); static void closeAllFiles( stringstream &message );
virtual bool isMongoMMF() { return false; } virtual bool isMongoMMF() { return false; }
string filename() const { return _filename; } string filename() const { return _filename; }
void setFilename(string fn); void setFilename(const std::string& fn);
private: private:
string _filename; string _filename;
static int _flushAll( bool sync ); // returns n flushed static int _flushAll( bool sync ); // returns n flushed
protected: protected:
virtual void close() = 0; virtual void close() = 0;
virtual void flush(bool sync) = 0; virtual void flush(bool sync) = 0;
/** /**
* returns a thread safe object that you can call flush on * returns a thread safe object that you can call flush on
* Flushable has to fail nicely if the underlying object gets kille d * Flushable has to fail nicely if the underlying object gets kille d
skipping to change at line 126 skipping to change at line 127
void created(); /* subclass must call after create */ void created(); /* subclass must call after create */
/* subclass must call in destructor (or at close). /* subclass must call in destructor (or at close).
removes this from pathToFile and other maps removes this from pathToFile and other maps
safe to call more than once, albeit might be wasted work safe to call more than once, albeit might be wasted work
ideal to call close to the close, if the close is well before ob ject destruction ideal to call close to the close, if the close is well before ob ject destruction
*/ */
void destroyed(); void destroyed();
virtual unsigned long long length() const = 0; virtual unsigned long long length() const = 0;
static set<MongoFile*> mmfiles;
public:
static map<string,MongoFile*> pathToFile;
}; };
/** look up a MMF by filename. scoped mutex locking convention. /** look up a MMF by filename. scoped mutex locking convention.
example: example:
MMFFinderByName finder; MMFFinderByName finder;
MongoMMF *a = finder.find("file_name_a"); MongoMMF *a = finder.find("file_name_a");
MongoMMF *b = finder.find("file_name_b"); MongoMMF *b = finder.find("file_name_b");
*/ */
class MongoFileFinder : boost::noncopyable { class MongoFileFinder : boost::noncopyable {
public: public:
MongoFileFinder() { }
/** @return The MongoFile object associated with the specified file name. If no file is open /** @return The MongoFile object associated with the specified file name. If no file is open
with the specified name, returns null. with the specified name, returns null.
*/ */
MongoFile* findByPath(string path) { MongoFile* findByPath(const std::string& path) const;
map<string,MongoFile*>::iterator i = MongoFile::pathToFile.find
(path);
return i == MongoFile::pathToFile.end() ? NULL : i->second;
}
private: private:
LockMongoFilesShared _lk; LockMongoFilesShared _lk;
}; };
class MemoryMappedFile : public MongoFile { class MemoryMappedFile : public MongoFile {
protected: protected:
virtual void* viewForFlushing() { virtual void* viewForFlushing() {
if( views.size() == 0 ) if( views.size() == 0 )
return 0; return 0;
skipping to change at line 188 skipping to change at line 180
/* Creates with length if DNE, otherwise uses existing file length, /* Creates with length if DNE, otherwise uses existing file length,
passed length. passed length.
@param options MongoFile::Options bits @param options MongoFile::Options bits
*/ */
void* map(const char *filename, unsigned long long &length, int opt ions = 0 ); void* map(const char *filename, unsigned long long &length, int opt ions = 0 );
/* Create. Must not exist. /* Create. Must not exist.
@param zero fill file with zeros when true @param zero fill file with zeros when true
*/ */
void* create(string filename, unsigned long long len, bool zero); void* create(const std::string& filename, unsigned long long len, b ool zero);
void flush(bool sync); void flush(bool sync);
virtual Flushable * prepareFlush(); virtual Flushable * prepareFlush();
long shortLength() const { return (long) len; } long shortLength() const { return (long) len; }
unsigned long long length() const { return len; } unsigned long long length() const { return len; }
HANDLE getFd() const { return fd; } HANDLE getFd() const { return fd; }
/** create a new view with the specified properties. /** create a new view with the specified properties.
automatically cleaned up upon close/destruction of the MemoryMa ppedFile object. automatically cleaned up upon close/destruction of the MemoryMa ppedFile object.
*/ */
skipping to change at line 240 skipping to change at line 232
/** close the current private view and open a new replacement */ /** close the current private view and open a new replacement */
void* remapPrivateView(void *oldPrivateAddr); void* remapPrivateView(void *oldPrivateAddr);
}; };
typedef MemoryMappedFile MMF; typedef MemoryMappedFile MMF;
/** p is called from within a mutex that MongoFile uses. so be careful not to deadlock. */ /** p is called from within a mutex that MongoFile uses. so be careful not to deadlock. */
template < class F > template < class F >
inline void MongoFile::forEach( F p ) { inline void MongoFile::forEach( F p ) {
LockMongoFilesShared lklk; LockMongoFilesShared lklk;
for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.e const set<MongoFile*>& mmfiles = MongoFile::getAllFiles();
nd(); i++ ) for ( set<MongoFile*>::const_iterator i = mmfiles.begin(); i != mmf
iles.end(); i++ )
p(*i); p(*i);
} }
#if defined(_WIN32) #if defined(_WIN32)
class ourbitset { class ourbitset {
volatile unsigned bits[MemoryMappedFile::NChunks]; // volatile as w e are doing double check locking volatile unsigned bits[MemoryMappedFile::NChunks]; // volatile as w e are doing double check locking
public: public:
ourbitset() { ourbitset() {
memset((void*) bits, 0, sizeof(bits)); memset((void*) bits, 0, sizeof(bits));
} }
 End of changes. 9 change blocks. 
17 lines changed or deleted 9 lines changed or added


 module.h   module.h 
skipping to change at line 21 skipping to change at line 21
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include "mongo/pch.h"
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <list> #include <list>
#include <string>
namespace mongo { namespace mongo {
/** /**
* Module is the base class for adding modules to MongoDB * Module is the base class for adding modules to MongoDB
* modules allow adding hooks and features to mongo * modules allow adding hooks and features to mongo
* the idea is to add hooks into the main code for module support where needed * the idea is to add hooks into the main code for module support where needed
* some ideas are: monitoring, indexes, full text search * some ideas are: monitoring, indexes, full text search
*/ */
class Module { class Module {
public: public:
Module( const string& name ); Module( const std::string& name );
virtual ~Module(); virtual ~Module();
boost::program_options::options_description_easy_init add_options() { boost::program_options::options_description_easy_init add_options() {
return _options.add_options(); return _options.add_options();
} }
/** /**
* read config from command line * read config from command line
*/ */
virtual void config( boost::program_options::variables_map& params ) = 0; virtual void config( boost::program_options::variables_map& params ) = 0;
skipping to change at line 57 skipping to change at line 57
/** /**
* called after configuration when the server is ready start * called after configuration when the server is ready start
*/ */
virtual void init() = 0; virtual void init() = 0;
/** /**
* called when the database is about to shutdown * called when the database is about to shutdown
*/ */
virtual void shutdown() = 0; virtual void shutdown() = 0;
const string& getName() { return _name; } const std::string& getName() { return _name; }
// --- static things // --- static things
static void addOptions( boost::program_options::options_description & options ); static void addOptions( boost::program_options::options_description & options );
static void configAll( boost::program_options::variables_map& param s ); static void configAll( boost::program_options::variables_map& param s );
static void initAll(); static void initAll();
private: private:
static std::list<Module*> * _all; static std::list<Module*> * _all;
string _name; std::string _name;
boost::program_options::options_description _options; boost::program_options::options_description _options;
}; };
} }
 End of changes. 5 change blocks. 
4 lines changed or deleted 4 lines changed or added


 mongommf.h   mongommf.h 
skipping to change at line 39 skipping to change at line 39
class MongoMMF : private MemoryMappedFile { class MongoMMF : private MemoryMappedFile {
protected: protected:
virtual void* viewForFlushing() { return _view_write; } virtual void* viewForFlushing() { return _view_write; }
public: public:
MongoMMF(); MongoMMF();
virtual ~MongoMMF(); virtual ~MongoMMF();
virtual void close(); virtual void close();
/** @return true if opened ok. */ /** @return true if opened ok. */
bool open(string fname, bool sequentialHint /*typically we open wit h this false*/); bool open(const std::string& fname, bool sequentialHint /*typically we open with this false*/);
/** @return file length */ /** @return file length */
unsigned long long length() const { return MemoryMappedFile::length (); } unsigned long long length() const { return MemoryMappedFile::length (); }
string filename() const { return MemoryMappedFile::filename(); } string filename() const { return MemoryMappedFile::filename(); }
void flush(bool sync) { MemoryMappedFile::flush(sync); } void flush(bool sync) { MemoryMappedFile::flush(sync); }
/* Creates with length if DNE, otherwise uses existing file length, /* Creates with length if DNE, otherwise uses existing file length,
passed length. passed length.
@param sequentialHint if true will be sequentially accessed @param sequentialHint if true will be sequentially accessed
@return true for ok @return true for ok
*/ */
bool create(string fname, unsigned long long& len, bool sequentialH int); bool create(const std::string& fname, unsigned long long& len, bool sequentialHint);
/* Get the "standard" view (which is the private one). /* Get the "standard" view (which is the private one).
@return the private view. @return the private view.
*/ */
void* getView() const { return _view_private; } void* getView() const { return _view_private; }
/* Get the "write" view (which is required for writing). /* Get the "write" view (which is required for writing).
@return the write view. @return the write view.
*/ */
void* view_write() const { return _view_write; } void* view_write() const { return _view_write; }
skipping to change at line 103 skipping to change at line 103
virtual bool isMongoMMF() { return true; } virtual bool isMongoMMF() { return true; }
private: private:
void *_view_write; void *_view_write;
void *_view_private; void *_view_private;
bool _willNeedRemap; bool _willNeedRemap;
RelativePath _p; // e.g. "somepath/dbname" RelativePath _p; // e.g. "somepath/dbname"
int _fileSuffixNo; // e.g. 3. -1="ns" int _fileSuffixNo; // e.g. 3. -1="ns"
void setPath(string pathAndFileName); void setPath(const std::string& pathAndFileName);
bool finishOpening(); bool finishOpening();
}; };
/** for durability support we want to be able to map pointers to specif ic MongoMMF objects. /** for durability support we want to be able to map pointers to specif ic MongoMMF objects.
*/ */
class PointerToMMF : boost::noncopyable { class PointerToMMF : boost::noncopyable {
public: public:
PointerToMMF(); PointerToMMF();
/** register view. /** register view.
 End of changes. 3 change blocks. 
3 lines changed or deleted 3 lines changed or added


 mr.h   mr.h 
// mr.h // mr.h
/** /**
* Copyright (C) 2012 10gen Inc.
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3, * it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation. * as published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
skipping to change at line 75 skipping to change at line 76
/** /**
* used as a holder for Scope and ScriptingFunction * used as a holder for Scope and ScriptingFunction
* visitor like pattern as Scope is gotten from first access * visitor like pattern as Scope is gotten from first access
*/ */
class JSFunction : boost::noncopyable { class JSFunction : boost::noncopyable {
public: public:
/** /**
* @param type (map|reduce|finalize) * @param type (map|reduce|finalize)
*/ */
JSFunction( string type , const BSONElement& e ); JSFunction( const std::string& type , const BSONElement& e );
virtual ~JSFunction() {} virtual ~JSFunction() {}
virtual void init( State * state ); virtual void init( State * state );
Scope * scope() const { return _scope; } Scope * scope() const { return _scope; }
ScriptingFunction func() const { return _func; } ScriptingFunction func() const { return _func; }
private: private:
string _type; string _type;
string _code; // actual javascript code string _code; // actual javascript code
 End of changes. 2 change blocks. 
1 lines changed or deleted 2 lines changed or added


 msg.h   msg.h 
skipping to change at line 38 skipping to change at line 38
namespace task { namespace task {
typedef boost::function<void()> lam; typedef boost::function<void()> lam;
/** typical usage is: task::fork( new Server("threadname") ); */ /** typical usage is: task::fork( new Server("threadname") ); */
class Server : public Task { class Server : public Task {
public: public:
/** send a message to the port */ /** send a message to the port */
void send(lam); void send(lam);
Server(string name) : m("server"), _name(name), rq(false) { } Server(const std::string& name) : m("server"), _name(name), rq( false) { }
virtual ~Server() { } virtual ~Server() { }
/** send message but block until function completes */ /** send message but block until function completes */
void call(const lam&); void call(const lam&);
void requeue() { rq = true; } void requeue() { rq = true; }
protected: protected:
/* REMINDER : for use in mongod, you will want to have this cal l Client::initThread(). */ /* REMINDER : for use in mongod, you will want to have this cal l Client::initThread(). */
virtual void starting() { } virtual void starting() { }
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 mutexdebugger.h   mutexdebugger.h 
// @file mutexdebugger.h // @file mutexdebugger.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "mongo/client/undef_macros.h" #include "mongo/client/undef_macros.h"
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <set> #include <set>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include "boost/thread/mutex.hpp" #include "boost/thread/mutex.hpp"
#include "mongo/client/redef_macros.h" #include "mongo/client/redef_macros.h"
#include "mongo/util/assert_util.h" #include "mongo/util/assert_util.h"
namespace mongo { namespace mongo {
/** only used on _DEBUG builds. /** only used on _DEBUG builds.
MutexDebugger checks that we always acquire locks for multiple mute xes in a consistant (acyclic) order. MutexDebugger checks that we always acquire locks for multiple mute xes in a consistent (acyclic) order.
If we were inconsistent we could deadlock. If we were inconsistent we could deadlock.
*/ */
class MutexDebugger { class MutexDebugger {
typedef const char * mid; // mid = mutex ID typedef const char * mid; // mid = mutex ID
typedef std::map<mid,int> Preceeding; typedef std::map<mid,int> Preceeding;
std::map< mid, int > maxNest; std::map< mid, int > maxNest;
boost::thread_specific_ptr< Preceeding > us; boost::thread_specific_ptr< Preceeding > us;
std::map< mid, std::set<mid> > followers; std::map< mid, std::set<mid> > followers;
boost::mutex &x; boost::mutex &x;
unsigned magic; unsigned magic;
 End of changes. 2 change blocks. 
1 lines changed or deleted 19 lines changed or added


 namespace_details.h   namespace_details.h 
skipping to change at line 22 skipping to change at line 22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include "mongo/pch.h" #include "mongo/pch.h"
#include "mongo/db/d_concurrency.h" #include "mongo/db/d_concurrency.h"
#include "mongo/db/diskloc.h" #include "mongo/db/diskloc.h"
#include "mongo/db/index.h" #include "mongo/db/index.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/mongommf.h" #include "mongo/db/mongommf.h"
#include "mongo/db/namespace.h" #include "mongo/db/namespace.h"
#include "mongo/db/namespacestring.h"
#include "mongo/db/queryoptimizercursor.h" #include "mongo/db/queryoptimizercursor.h"
#include "mongo/db/querypattern.h" #include "mongo/db/querypattern.h"
#include "mongo/platform/unordered_map.h"
#include "mongo/util/hashtab.h" #include "mongo/util/hashtab.h"
namespace mongo { namespace mongo {
class Database; class Database;
/** @return true if a client can modify this namespace even though it i s under ".system." /** @return true if a client can modify this namespace even though it i s under ".system."
For example <dbname>.system.users is ok for regular clients to upda te. For example <dbname>.system.users is ok for regular clients to upda te.
@param write used when .system.js @param write used when .system.js
*/ */
bool legalClientSystemNS( const string& ns , bool write ); bool legalClientSystemNS( const string& ns , bool write );
skipping to change at line 421 skipping to change at line 422
these are things we know / compute about a namespace that are transi ent -- things these are things we know / compute about a namespace that are transi ent -- things
we don't actually store in the .ns file. so mainly caching of frequ ently used we don't actually store in the .ns file. so mainly caching of frequ ently used
information. information.
CAUTION: Are you maintaining this properly on a collection drop()? A dropdatabase()? Be careful. CAUTION: Are you maintaining this properly on a collection drop()? A dropdatabase()? Be careful.
The current field "allIndexKeys" may have too many keys in it on such an occurrence; The current field "allIndexKeys" may have too many keys in it on such an occurrence;
as currently used that does not cause anything terrible to happen. as currently used that does not cause anything terrible to happen.
todo: cleanup code, need abstractions and separation todo: cleanup code, need abstractions and separation
*/ */
// todo: multiple db's with the same name (repairDatbase) is not handle d herein. that may be // todo: multiple db's with the same name (repairDatabase) is not handl ed herein. that may be
// the way to go, if not used by repair, but need some sort of en forcement / asserts. // the way to go, if not used by repair, but need some sort of en forcement / asserts.
class NamespaceDetailsTransient : boost::noncopyable { class NamespaceDetailsTransient : boost::noncopyable {
BOOST_STATIC_ASSERT( sizeof(NamespaceDetails) == 496 ); BOOST_STATIC_ASSERT( sizeof(NamespaceDetails) == 496 );
//Database *database; //Database *database;
const string _ns; const string _ns;
void reset(); void reset();
static std::map< string, shared_ptr< NamespaceDetailsTransient > > _nsdMap;
NamespaceDetailsTransient(Database*,const char *ns); // < db -> < fullns -> NDT > >
typedef unordered_map< string, shared_ptr<NamespaceDetailsTransient
> > CMap;
typedef unordered_map< string, CMap*, NamespaceDBHash, NamespaceDBE
quals > DMap;
static DMap _nsdMap;
NamespaceDetailsTransient(Database*,const string& ns);
public: public:
~NamespaceDetailsTransient(); ~NamespaceDetailsTransient();
void addedIndex() { reset(); } void addedIndex() { reset(); }
void deletedIndex() { reset(); } void deletedIndex() { reset(); }
/* Drop cached information on all namespaces beginning with the spe
cified prefix. /**
Can be useful as index namespaces share the same start as the re * reset stats for a given collection
gular collection. */
SLOW - sequential scan of all NamespaceDetailsTransient objects static void resetCollection(const string& ns );
*/
static void clearForPrefix(const char *prefix); /**
static void eraseForPrefix(const char *prefix); * remove entry for a collection
*/
static void eraseCollection(const string& ns);
/**
* remove all entries for db
*/
static void eraseDB(const string& db);
/** /**
* @return a cursor interface to the query optimizer. The implemen tation may utilize a * @return a cursor interface to the query optimizer. The implemen tation may utilize a
* single query plan or interleave results from multiple query plan s before settling on a * single query plan or interleave results from multiple query plan s before settling on a
* single query plan. Note that the schema of currKey() documents, indexKeyPattern(), the * single query plan. Note that the schema of currKey() documents, indexKeyPattern(), the
* matcher(), and the isMultiKey() nature of the cursor may change over the course of * matcher(), and the isMultiKey() nature of the cursor may change over the course of
* iteration. * iteration.
* *
* @param query - Query used to select indexes and populate matcher s; not copied if unowned * @param query - Query used to select indexes and populate matcher s; not copied if unowned
* (see bsonobj.h). * (see bsonobj.h).
skipping to change at line 538 skipping to change at line 553
verify( spec._finishedInit ); verify( spec._finishedInit );
} }
} }
return spec; return spec;
} }
/* query cache (for query optimizer) ------------------------------ ------- */ /* query cache (for query optimizer) ------------------------------ ------- */
private: private:
int _qcWriteCount; int _qcWriteCount;
map<QueryPattern,CachedQueryPlan> _qcCache; map<QueryPattern,CachedQueryPlan> _qcCache;
static NamespaceDetailsTransient& make_inlock(const char *ns); static NamespaceDetailsTransient& make_inlock(const string& ns);
static CMap& get_cmap_inlock(const string& ns);
public: public:
static SimpleMutex _qcMutex; static SimpleMutex _qcMutex;
/* you must be in the qcMutex when calling this. /* you must be in the qcMutex when calling this.
A NamespaceDetailsTransient object will not go out of scope on y ou if you are A NamespaceDetailsTransient object will not go out of scope on y ou if you are
d.dbMutex.atLeastReadLocked(), so you do't have to stay locked. d.dbMutex.atLeastReadLocked(), so you do't have to stay locked.
Creates a NamespaceDetailsTransient before returning if one DNE. Creates a NamespaceDetailsTransient before returning if one DNE.
todo: avoid creating too many on erroneous ns queries. todo: avoid creating too many on erroneous ns queries.
*/ */
static NamespaceDetailsTransient& get_inlock(const char *ns); static NamespaceDetailsTransient& get_inlock(const string& ns);
static NamespaceDetailsTransient& get(const char *ns) { static NamespaceDetailsTransient& get(const char *ns) {
// todo : _qcMutex will create bottlenecks in our parallelism // todo : _qcMutex will create bottlenecks in our parallelism
SimpleMutex::scoped_lock lk(_qcMutex); SimpleMutex::scoped_lock lk(_qcMutex);
return get_inlock(ns); return get_inlock(ns);
} }
void clearQueryCache() { void clearQueryCache() {
_qcCache.clear(); _qcCache.clear();
_qcWriteCount = 0; _qcWriteCount = 0;
skipping to change at line 577 skipping to change at line 593
CachedQueryPlan cachedQueryPlanForPattern( const QueryPattern &patt ern ) { CachedQueryPlan cachedQueryPlanForPattern( const QueryPattern &patt ern ) {
return _qcCache[ pattern ]; return _qcCache[ pattern ];
} }
void registerCachedQueryPlanForPattern( const QueryPattern &pattern , void registerCachedQueryPlanForPattern( const QueryPattern &pattern ,
const CachedQueryPlan &cache dQueryPlan ) { const CachedQueryPlan &cache dQueryPlan ) {
_qcCache[ pattern ] = cachedQueryPlan; _qcCache[ pattern ] = cachedQueryPlan;
} }
}; /* NamespaceDetailsTransient */ }; /* NamespaceDetailsTransient */
inline NamespaceDetailsTransient& NamespaceDetailsTransient::get_inlock inline NamespaceDetailsTransient& NamespaceDetailsTransient::get_inlock
(const char *ns) { (const string& ns) {
std::map< string, shared_ptr< NamespaceDetailsTransient > >::iterat CMap& m = get_cmap_inlock(ns);
or i = _nsdMap.find(ns); CMap::iterator i = m.find( ns );
if( i != _nsdMap.end() && if ( i != m.end() &&
i->second.get() ) { // could be null ptr from clearForPrefix i->second.get() ) { // could be null ptr from clearForPrefix
return *i->second; return *i->second;
} }
return make_inlock(ns); return make_inlock(ns);
} }
/* NamespaceIndex is the ".ns" file you see in the data directory. It is the "system catalog" /* NamespaceIndex is the ".ns" file you see in the data directory. It is the "system catalog"
if you will: at least the core parts. (Additional info in system.* collections.) if you will: at least the core parts. (Additional info in system.* collections.)
*/ */
class NamespaceIndex { class NamespaceIndex {
public: public:
 End of changes. 10 change blocks. 
20 lines changed or deleted 35 lines changed or added


 namespacestring.h   namespacestring.h 
skipping to change at line 163 skipping to change at line 163
return buf; return buf;
} }
inline string nsToDatabase(const string& ns) { inline string nsToDatabase(const string& ns) {
size_t i = ns.find( '.' ); size_t i = ns.find( '.' );
if ( i == string::npos ) if ( i == string::npos )
return ns; return ns;
massert(10088, "nsToDatabase: ns too long", i < (size_t)MaxDatabase NameLen); massert(10088, "nsToDatabase: ns too long", i < (size_t)MaxDatabase NameLen);
return ns.substr( 0 , i ); return ns.substr( 0 , i );
} }
/**
* NamespaceDBHash and NamespaceDBEquals allow you to do something like
* unordered_map<string,int,NamespaceDBHash,NamespaceDBEquals>
* and use the full namespace for the string
* but comparisons are done only on the db piece
*/
/**
* this can change, do not store on disk
*/
inline int nsDBHash( const string& ns ) {
int hash = 7;
for ( size_t i = 0; i < ns.size(); i++ ) {
if ( ns[i] == '.' )
break;
hash += 11 * ( ns[i] );
hash *= 3;
}
return hash;
}
inline bool nsDBEquals( const string& a, const string& b ) {
for ( size_t i = 0; i < a.size(); i++ ) {
if ( a[i] == '.' ) {
// b has to either be done or a '.'
if ( b.size() == i )
return true;
if ( b[i] == '.' )
return true;
return false;
}
// a is another character
if ( b.size() == i )
return false;
if ( b[i] != a[i] )
return false;
}
// a is done
// make sure b is done
if ( b.size() == a.size() ||
b[a.size()] == '.' )
return true;
return false;
}
struct NamespaceDBHash {
int operator()( const string& ns ) const {
return nsDBHash( ns );
}
};
struct NamespaceDBEquals {
bool operator()( const string& a, const string& b ) const {
return nsDBEquals( a, b );
}
};
} }
 End of changes. 1 change blocks. 
0 lines changed or deleted 65 lines changed or added


 ntservice.h   ntservice.h 
skipping to change at line 35 skipping to change at line 35
struct ntServiceDefaultStrings { struct ntServiceDefaultStrings {
const wchar_t* serviceName; const wchar_t* serviceName;
const wchar_t* displayName; const wchar_t* displayName;
const wchar_t* serviceDescription; const wchar_t* serviceDescription;
}; };
typedef bool ( *ServiceCallback )( void ); typedef bool ( *ServiceCallback )( void );
bool serviceParamsCheck( bool serviceParamsCheck(
boost::program_options::variables_map& params, boost::program_options::variables_map& params,
const std::string dbpath, const std::string& dbpath,
const ntServiceDefaultStrings& defaultStrings, const ntServiceDefaultStrings& defaultStrings,
const vector<string>& disallowedOptions, const vector<string>& disallowedOptions,
int argc, int argc,
char* argv[] char* argv[]
); );
class ServiceController { class ServiceController {
public: public:
ServiceController(); ServiceController();
virtual ~ServiceController() {} virtual ~ServiceController() {}
static bool installService( static bool installService(
const std::wstring& serviceName, const std::wstring& serviceName,
const std::wstring& displayName, const std::wstring& displayName,
const std::wstring& serviceDesc, const std::wstring& serviceDesc,
const std::wstring& serviceUser, const std::wstring& serviceUser,
const std::wstring& servicePassword, const std::wstring& servicePassword,
const std::string dbpath, const std::string& dbpath,
int argc, int argc,
char* argv[] char* argv[]
); );
static bool removeService( const std::wstring& serviceName ); static bool removeService( const std::wstring& serviceName );
static bool startService( const std::wstring& serviceName, ServiceC allback startService ); static bool startService( const std::wstring& serviceName, ServiceC allback startService );
static bool reportStatus( DWORD reportState, DWORD waitHint = 0 ); static bool reportStatus( DWORD reportState, DWORD waitHint = 0 );
static void WINAPI initService( DWORD argc, LPTSTR *argv ); static void WINAPI initService( DWORD argc, LPTSTR *argv );
static void WINAPI serviceCtrl( DWORD ctrlCode ); static void WINAPI serviceCtrl( DWORD ctrlCode );
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 oid.h   oid.h 
skipping to change at line 82 skipping to change at line 82
void init(); void init();
/** sets the contents to a new oid /** sets the contents to a new oid
* guaranteed to be sequential * guaranteed to be sequential
* NOT guaranteed to be globally unique * NOT guaranteed to be globally unique
* only unique for this process * only unique for this process
* */ * */
void initSequential(); void initSequential();
/** init from a 24 char hex string */ /** init from a 24 char hex string */
void init( std::string s ); void init( const std::string& s );
/** Set to the min/max OID that could be generated at given timesta mp. */ /** Set to the min/max OID that could be generated at given timesta mp. */
void init( Date_t date, bool max=false ); void init( Date_t date, bool max=false );
time_t asTimeT(); time_t asTimeT();
Date_t asDateT() { return asTimeT() * (long long)1000; } Date_t asDateT() { return asTimeT() * (long long)1000; }
bool isSet() const { return a || b; } bool isSet() const { return a || b; }
/** /**
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 oplog.h   oplog.h 
skipping to change at line 63 skipping to change at line 63
void logKeepalive(); void logKeepalive();
/** puts obj in the oplog as a comment (a no-op). Just for diags. /** puts obj in the oplog as a comment (a no-op). Just for diags.
convention is convention is
{ msg : "text", ... } { msg : "text", ... }
*/ */
void logOpComment(const BSONObj& obj); void logOpComment(const BSONObj& obj);
void oplogCheckCloseDatabase( Database * db ); void oplogCheckCloseDatabase( Database * db );
extern int __findingStartInitialTimeout; // configurable for testing
class QueryPlan; class QueryPlan;
/** Implements an optimized procedure for finding the first op in the o plog. */ /** Implements an optimized procedure for finding the first op in the o plog. */
class FindingStartCursor { class FindingStartCursor {
public: public:
/** /**
* The cursor will attempt to find the first op in the oplog matchi ng the * The cursor will attempt to find the first op in the oplog matchi ng the
* 'ts' field of the qp's query. * 'ts' field of the qp's query.
*/ */
skipping to change at line 112 skipping to change at line 110
} }
/** /**
* @return a BasicCursor constructed using a FindingStartCursor wit h the provided query and * @return a BasicCursor constructed using a FindingStartCursor wit h the provided query and
* order parameters. * order parameters.
* @yields the db lock. * @yields the db lock.
* @asserts on yield recovery failure. * @asserts on yield recovery failure.
*/ */
static shared_ptr<Cursor> getCursor( const char *ns, const BSONObj &query, const BSONObj &order ); static shared_ptr<Cursor> getCursor( const char *ns, const BSONObj &query, const BSONObj &order );
/**
* @return the first record of the first nonempty extent preceding
the extent containing
* @param rec, or DiskLoc() if there is no such record or the b
eginning of the
* collection is reached.
* public for testing
*/
DiskLoc prevExtentFirstLoc( const DiskLoc& rec ) const;
/** For testing only. */
static int getInitialTimeout() { return _initialTimeout; }
static void setInitialTimeout( int timeout ) { _initialTimeout = ti
meout; }
private: private:
FindingStartCursor( const QueryPlan &qp ); FindingStartCursor( const QueryPlan &qp );
void init(); void init();
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::Holder _findingStartCursor; ClientCursor::Holder _findingStartCursor;
shared_ptr<Cursor> _c; shared_ptr<Cursor> _c;
ClientCursor::YieldData _yieldData; ClientCursor::YieldData _yieldData;
static int _initialTimeout;
/** @return the first record of the extent containing @param rec. *
/
DiskLoc extentFirstLoc( const DiskLoc &rec ); DiskLoc extentFirstLoc( const DiskLoc &rec );
DiskLoc prevExtentFirstLoc( const DiskLoc &rec );
void createClientCursor( const DiskLoc &startLoc = DiskLoc() ); void createClientCursor( const DiskLoc &startLoc = DiskLoc() );
void destroyClientCursor() { void destroyClientCursor() {
_findingStartCursor.reset( 0 ); _findingStartCursor.reset( 0 );
} }
bool firstDocMatchesOrEmpty() const; bool firstDocMatchesOrEmpty() const;
}; };
class Sync { class Sync {
protected: protected:
string hn; string hn;
 End of changes. 4 change blocks. 
3 lines changed or deleted 20 lines changed or added


 oplogreader.h   oplogreader.h 
/** @file oplogreader.h */ /** @file oplogreader.h */
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "../client/constants.h" #include "../client/constants.h"
#include "dbhelpers.h" #include "dbhelpers.h"
#include "mongo/client/dbclientcursor.h" #include "mongo/client/dbclientcursor.h"
namespace mongo { namespace mongo {
/* started abstracting out the querying of the primary/master's oplog /* started abstracting out the querying of the primary/master's oplog
still fairly awkward but a start. still fairly awkward but a start.
skipping to change at line 37 skipping to change at line 53
} }
DBClientConnection* conn() { return _conn.get(); } DBClientConnection* conn() { return _conn.get(); }
BSONObj findOne(const char *ns, const Query& q) { BSONObj findOne(const char *ns, const Query& q) {
return conn()->findOne(ns, q, 0, QueryOption_SlaveOk); return conn()->findOne(ns, q, 0, QueryOption_SlaveOk);
} }
BSONObj getLastOp(const char *ns) { BSONObj getLastOp(const char *ns) {
return findOne(ns, Query().sort(reverseNaturalObj)); return findOne(ns, Query().sort(reverseNaturalObj));
} }
/* ok to call if already connected */ /* ok to call if already connected */
bool connect(string hostname); bool connect(const std::string& hostname);
bool connect(const BSONObj& rid, const int from, const string& to); bool connect(const BSONObj& rid, const int from, const string& to);
void tailCheck() { void tailCheck() {
if( cursor.get() && cursor->isDead() ) { if( cursor.get() && cursor->isDead() ) {
log() << "repl: old cursor isDead, will initiate a new one" << endl; log() << "repl: old cursor isDead, will initiate a new one" << endl;
resetCursor(); resetCursor();
} }
} }
 End of changes. 2 change blocks. 
1 lines changed or deleted 19 lines changed or added


 optime.h   optime.h 
skipping to change at line 45 skipping to change at line 45
*/ */
#pragma pack(4) #pragma pack(4)
class OpTime { class OpTime {
unsigned i; // ordinal comes first so we can do a single 64 bit com pare on little endian unsigned i; // ordinal comes first so we can do a single 64 bit com pare on little endian
unsigned secs; unsigned secs;
static OpTime last; static OpTime last;
static OpTime skewed(); static OpTime skewed();
public: public:
static void setLast(const Date_t &date) { static void setLast(const Date_t &date) {
mutex::scoped_lock lk(m); mutex::scoped_lock lk(m);
notifier.notify_all(); // won't really do anything until write- lock released
last = OpTime(date); last = OpTime(date);
notifier.notify_all();
} }
static void setLast(const OpTime &new_last) {
mutex::scoped_lock lk(m);
last = new_last;
notifier.notify_all();
}
unsigned getSecs() const { unsigned getSecs() const {
return secs; return secs;
} }
unsigned getInc() const { unsigned getInc() const {
return i; return i;
} }
OpTime(Date_t date) { OpTime(Date_t date) {
reinterpret_cast<unsigned long long&>(*this) = date.millis; reinterpret_cast<unsigned long long&>(*this) = date.millis;
dassert( (int)secs >= 0 ); dassert( (int)secs >= 0 );
} }
 End of changes. 3 change blocks. 
7 lines changed or deleted 1 lines changed or added


 pagefault.h   pagefault.h 
// @file pagefault.h // @file pagefault.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
namespace mongo { namespace mongo {
class Record; class Record;
class PageFaultException /*: public DBException*/ { class PageFaultException /*: public DBException*/ {
unsigned era; unsigned era;
const Record *r; const Record *r;
public: public:
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 parallel.h   parallel.h 
skipping to change at line 69 skipping to change at line 69
return toString(); return toString();
} }
string _server; string _server;
BSONObj _extra; BSONObj _extra;
BSONObj _orderObject; BSONObj _orderObject;
}; };
/** /**
* this is a cursor that works over a set of servers * this is a cursor that works over a set of servers
* can be used in serial/paralellel as controlled by sub classes * can be used in serial/parallel as controlled by sub classes
*/ */
class ClusteredCursor { class ClusteredCursor {
public: public:
ClusteredCursor( const QuerySpec& q ); ClusteredCursor( const QuerySpec& q );
ClusteredCursor( QueryMessage& q ); ClusteredCursor( QueryMessage& q );
ClusteredCursor( const string& ns , const BSONObj& q , int options= 0 , const BSONObj& fields=BSONObj() ); ClusteredCursor( const string& ns , const BSONObj& q , int options= 0 , const BSONObj& fields=BSONObj() );
virtual ~ClusteredCursor(); virtual ~ClusteredCursor();
/** call before using */ /** call before using */
void init(); void init();
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 paths.h   paths.h 
skipping to change at line 42 skipping to change at line 42
extern string dbpath; extern string dbpath;
/** this is very much like a boost::path. however, we define a new typ e to get some type /** this is very much like a boost::path. however, we define a new typ e to get some type
checking. if you want to say 'my param MUST be a relative path", u se this. checking. if you want to say 'my param MUST be a relative path", u se this.
*/ */
struct RelativePath { struct RelativePath {
string _p; string _p;
bool empty() const { return _p.empty(); } bool empty() const { return _p.empty(); }
static RelativePath fromRelativePath(string f) { static RelativePath fromRelativePath(const std::string& f) {
RelativePath rp; RelativePath rp;
rp._p = f; rp._p = f;
return rp; return rp;
} }
/** from a full path */ /** from a full path */
static RelativePath fromFullPath(boost::filesystem::path f) { static RelativePath fromFullPath(boost::filesystem::path f) {
boost::filesystem::path dbp(dbpath); // normalizes / and backsl ash boost::filesystem::path dbp(dbpath); // normalizes / and backsl ash
string fullpath = f.string(); string fullpath = f.string();
string relative = str::after(fullpath, dbp.string()); string relative = str::after(fullpath, dbp.string());
skipping to change at line 112 skipping to change at line 112
#ifdef __linux__ // this isn't needed elsewhere #ifdef __linux__ // this isn't needed elsewhere
// if called without a fully qualified path it asserts; that makes mongoperf fail. so make a warning. need a better solution longer term. // if called without a fully qualified path it asserts; that makes mongoperf fail. so make a warning. need a better solution longer term.
// massert(13652, str::stream() << "Couldn't find parent dir for fi le: " << file.string(), ); // massert(13652, str::stream() << "Couldn't find parent dir for fi le: " << file.string(), );
if( !file.has_branch_path() ) { if( !file.has_branch_path() ) {
log() << "warning flushMYDirectory couldn't find parent dir for file: " << file.string() << endl; log() << "warning flushMYDirectory couldn't find parent dir for file: " << file.string() << endl;
return; return;
} }
boost::filesystem::path dir = file.branch_path(); // parent_path in new boosts boost::filesystem::path dir = file.branch_path(); // parent_path in new boosts
LOG(1) << "flushing directory " << dir.string() << endl; log(1) << "flushing directory " << dir.string() << endl;
int fd = ::open(dir.string().c_str(), O_RDONLY); // DO NOT THROW OR ASSERT BEFORE CLOSING int fd = ::open(dir.string().c_str(), O_RDONLY); // DO NOT THROW OR ASSERT BEFORE CLOSING
massert(13650, str::stream() << "Couldn't open directory '" << dir. string() << "' for flushing: " << errnoWithDescription(), fd >= 0); massert(13650, str::stream() << "Couldn't open directory '" << dir. string() << "' for flushing: " << errnoWithDescription(), fd >= 0);
if (fsync(fd) != 0){ if (fsync(fd) != 0){
int e = errno; int e = errno;
close(fd); close(fd);
massert(13651, str::stream() << "Couldn't fsync directory '" << dir.string() << "': " << errnoWithDescription(e), false); massert(13651, str::stream() << "Couldn't fsync directory '" << dir.string() << "': " << errnoWithDescription(e), false);
} }
close(fd); close(fd);
#endif #endif
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 pch.h   pch.h 
skipping to change at line 47 skipping to change at line 47
#include <vector> #include <vector>
#include <set> #include <set>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#include "time.h" #include "time.h"
#include "string.h" #include "string.h"
#include "limits.h" #include "limits.h"
#define BOOST_FILESYSTEM_VERSION 2 #define BOOST_FILESYSTEM_VERSION 3
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/smart_ptr.hpp> #include <boost/smart_ptr.hpp>
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/version.hpp> #include <boost/version.hpp>
#include "mongo/client/redef_macros.h" #include "mongo/client/redef_macros.h"
#include "mongo/util/exit_code.h" #include "mongo/util/exit_code.h"
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 pdfile.h   pdfile.h 
skipping to change at line 51 skipping to change at line 51
// pdfile versions // pdfile versions
const int PDFILE_VERSION = 4; const int PDFILE_VERSION = 4;
const int PDFILE_VERSION_MINOR = 5; const int PDFILE_VERSION_MINOR = 5;
class DataFileHeader; class DataFileHeader;
class Extent; class Extent;
class Record; class Record;
class Cursor; class Cursor;
class OpDebug; class OpDebug;
void dropDatabase(string db); void dropDatabase(const std::string& db);
bool repairDatabase(string db, string &errmsg, bool preserveClonedFiles OnFailure = false, bool backupOriginalFiles = false); bool repairDatabase(string db, string &errmsg, bool preserveClonedFiles OnFailure = false, bool backupOriginalFiles = false);
/* low level - only drops this ns */ /* low level - only drops this ns */
void dropNS(const string& dropNs); void dropNS(const string& dropNs);
/* deletes this ns, indexes and cursors */ /* deletes this ns, indexes and cursors */
void dropCollection( const string &name, string &errmsg, BSONObjBuilder &result ); void dropCollection( const string &name, string &errmsg, BSONObjBuilder &result );
bool userCreateNS(const char *ns, BSONObj j, string& err, bool logForRe plication, bool *deferIdIndex = 0); bool userCreateNS(const char *ns, BSONObj j, string& err, bool logForRe plication, bool *deferIdIndex = 0);
shared_ptr<Cursor> findTableScan(const char *ns, const BSONObj& order, const DiskLoc &startLoc=DiskLoc()); shared_ptr<Cursor> findTableScan(const char *ns, const BSONObj& order, const DiskLoc &startLoc=DiskLoc());
skipping to change at line 159 skipping to change at line 159
no _id field check no _id field check
*/ */
Record* fast_oplog_insert(NamespaceDetails *d, const char *ns, int len); Record* fast_oplog_insert(NamespaceDetails *d, const char *ns, int len);
static Extent* getExtent(const DiskLoc& dl); static Extent* getExtent(const DiskLoc& dl);
static Record* getRecord(const DiskLoc& dl); static Record* getRecord(const DiskLoc& dl);
static DeletedRecord* makeDeletedRecord(const DiskLoc& dl, int len) ; static DeletedRecord* makeDeletedRecord(const DiskLoc& dl, int len) ;
void deleteRecord(const char *ns, Record *todelete, const DiskLoc& dl, bool cappedOK = false, bool noWarn = false, bool logOp=false); void deleteRecord(const char *ns, Record *todelete, const DiskLoc& dl, bool cappedOK = false, bool noWarn = false, bool logOp=false);
void deleteRecord(NamespaceDetails* d, const char *ns, Record *tode
lete, const DiskLoc& dl, bool cappedOK = false, bool noWarn = false, bool l
ogOp=false);
/* does not clean up indexes, etc. : just deletes the record in the pdfile. use deleteRecord() to unindex */ /* does not clean up indexes, etc. : just deletes the record in the pdfile. use deleteRecord() to unindex */
void _deleteRecord(NamespaceDetails *d, const char *ns, Record *tod elete, const DiskLoc& dl); void _deleteRecord(NamespaceDetails *d, const char *ns, Record *tod elete, const DiskLoc& dl);
private: private:
vector<MongoDataFile *> files; vector<MongoDataFile *> files;
}; };
extern DataFileMgr theDataFileMgr; extern DataFileMgr theDataFileMgr;
#pragma pack(1) #pragma pack(1)
skipping to change at line 287 skipping to change at line 289
static bool likelyInPhysicalMemory( const char* data ); static bool likelyInPhysicalMemory( const char* data );
static bool blockCheckSupported(); static bool blockCheckSupported();
/** /**
* this adds stats about page fault exceptions currently * this adds stats about page fault exceptions currently
* specically how many times we call _accessing where the record is not in memory * specically how many times we call _accessing where the record is not in memory
* and how many times we throw a PageFaultException * and how many times we throw a PageFaultException
*/ */
static void appendStats( BSONObjBuilder& b ); static void appendStats( BSONObjBuilder& b );
static void appendWorkingSetInfo( BSONObjBuilder& b );
private: private:
int _netLength() const { return _lengthWithHeaders - HeaderSize; } int _netLength() const { return _lengthWithHeaders - HeaderSize; }
/** /**
* call this when accessing a field which could hit disk * call this when accessing a field which could hit disk
*/ */
void _accessing() const; void _accessing() const;
int _lengthWithHeaders; int _lengthWithHeaders;
 End of changes. 3 change blocks. 
1 lines changed or deleted 7 lines changed or added


 progress_meter.h   progress_meter.h 
skipping to change at line 49 skipping to change at line 49
void finished() { _active = 0; } void finished() { _active = 0; }
bool isActive() const { return _active; } bool isActive() const { return _active; }
/** /**
* @param n how far along we are relative to the total # we set in CurOp::setMessage * @param n how far along we are relative to the total # we set in CurOp::setMessage
* @return if row was printed * @return if row was printed
*/ */
bool hit( int n = 1 ); bool hit( int n = 1 );
void setUnits( std::string units ) { _units = units; } void setUnits( const std::string& units ) { _units = units; }
std::string getUnit() const { return _units; } std::string getUnit() const { return _units; }
void setTotalWhileRunning( unsigned long long total ) { void setTotalWhileRunning( unsigned long long total ) {
_total = total; _total = total;
} }
unsigned long long done() const { return _done; } unsigned long long done() const { return _done; }
unsigned long long hits() const { return _hits; } unsigned long long hits() const { return _hits; }
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 qlock.h   qlock.h 
// @file qlock.h // @file qlock.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp> #include <boost/thread/condition.hpp>
#include "../assert_util.h" #include "../assert_util.h"
#include "../time_support.h" #include "../time_support.h"
namespace mongo { namespace mongo {
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 query.h   query.h 
skipping to change at line 50 skipping to change at line 50
/** Exception indicating that a query should be retried from the beginn ing. */ /** Exception indicating that a query should be retried from the beginn ing. */
class QueryRetryException : public DBException { class QueryRetryException : public DBException {
public: public:
QueryRetryException() : DBException( "query retry exception" , 1608 3 ) { QueryRetryException() : DBException( "query retry exception" , 1608 3 ) {
return; return;
massert( 16083, "reserve 16083", true ); // Reserve 16083. massert( 16083, "reserve 16083", true ); // Reserve 16083.
} }
}; };
/** Metadata about matching and loading a single candidate result docum
ent from a Cursor. */
struct ResultDetails {
ResultDetails();
MatchDetails matchDetails; // Details on how the Matcher matched th
e query.
bool match; // Matched the query, was not a dup, was
not skipped etc.
bool orderedMatch; // _match and belonged to an ordered que
ry plan.
bool loadedRecord; // Record was loaded (to match or return
the document).
bool chunkSkip; // Did not belong to an owned chunk rang
e.
};
/** Interface for recording events that contribute to explain results. */ /** Interface for recording events that contribute to explain results. */
class ExplainRecordingStrategy { class ExplainRecordingStrategy {
public: public:
ExplainRecordingStrategy( const ExplainQueryInfo::AncillaryInfo &an cillaryInfo ); ExplainRecordingStrategy( const ExplainQueryInfo::AncillaryInfo &an cillaryInfo );
virtual ~ExplainRecordingStrategy() {} virtual ~ExplainRecordingStrategy() {}
/** Note information about a single query plan. */ /** Note information about a single query plan. */
virtual void notePlan( bool scanAndOrder, bool indexOnly ) {} virtual void notePlan( bool scanAndOrder, bool indexOnly ) {}
/** Note an iteration of the query. */ /** Note an iteration of the query. */
virtual void noteIterate( bool match, bool orderedMatch, bool loade virtual void noteIterate( const ResultDetails& resultDetails ) {}
dRecord,
bool chunkSkip ) {}
/** Note that the query yielded. */ /** Note that the query yielded. */
virtual void noteYield() {} virtual void noteYield() {}
/** @return number of ordered matches noted. */ /** @return number of ordered matches noted. */
virtual long long orderedMatches() const { return 0; } virtual long long orderedMatches() const { return 0; }
/** @return ExplainQueryInfo for a complete query. */ /** @return ExplainQueryInfo for a complete query. */
shared_ptr<ExplainQueryInfo> doneQueryInfo(); shared_ptr<ExplainQueryInfo> doneQueryInfo();
protected: protected:
/** @return ExplainQueryInfo for a complete query, to be implemente d by subclass. */ /** @return ExplainQueryInfo for a complete query, to be implemente d by subclass. */
virtual shared_ptr<ExplainQueryInfo> _doneQueryInfo() = 0; virtual shared_ptr<ExplainQueryInfo> _doneQueryInfo() = 0;
private: private:
skipping to change at line 86 skipping to change at line 95
NoExplainStrategy(); NoExplainStrategy();
private: private:
/** @asserts always. */ /** @asserts always. */
virtual shared_ptr<ExplainQueryInfo> _doneQueryInfo(); virtual shared_ptr<ExplainQueryInfo> _doneQueryInfo();
}; };
class MatchCountingExplainStrategy : public ExplainRecordingStrategy { class MatchCountingExplainStrategy : public ExplainRecordingStrategy {
public: public:
MatchCountingExplainStrategy( const ExplainQueryInfo::AncillaryInfo &ancillaryInfo ); MatchCountingExplainStrategy( const ExplainQueryInfo::AncillaryInfo &ancillaryInfo );
protected: protected:
virtual void _noteIterate( bool match, bool orderedMatch, bool load virtual void _noteIterate( const ResultDetails& resultDetails ) = 0
edRecord, ;
bool chunkSkip ) = 0;
private: private:
virtual void noteIterate( bool match, bool orderedMatch, bool loade virtual void noteIterate( const ResultDetails& resultDetails );
dRecord,
bool chunkSkip );
virtual long long orderedMatches() const { return _orderedMatches; } virtual long long orderedMatches() const { return _orderedMatches; }
long long _orderedMatches; long long _orderedMatches;
}; };
/** Record explain events for a simple cursor representing a single cla use and plan. */ /** Record explain events for a simple cursor representing a single cla use and plan. */
class SimpleCursorExplainStrategy : public MatchCountingExplainStrategy { class SimpleCursorExplainStrategy : public MatchCountingExplainStrategy {
public: public:
SimpleCursorExplainStrategy( const ExplainQueryInfo::AncillaryInfo &ancillaryInfo, SimpleCursorExplainStrategy( const ExplainQueryInfo::AncillaryInfo &ancillaryInfo,
const shared_ptr<Cursor> &cursor ); const shared_ptr<Cursor> &cursor );
private: private:
virtual void notePlan( bool scanAndOrder, bool indexOnly ); virtual void notePlan( bool scanAndOrder, bool indexOnly );
virtual void _noteIterate( bool match, bool orderedMatch, bool load virtual void _noteIterate( const ResultDetails& resultDetails );
edRecord,
bool chunkSkip );
virtual void noteYield(); virtual void noteYield();
virtual shared_ptr<ExplainQueryInfo> _doneQueryInfo(); virtual shared_ptr<ExplainQueryInfo> _doneQueryInfo();
shared_ptr<Cursor> _cursor; shared_ptr<Cursor> _cursor;
shared_ptr<ExplainSinglePlanQueryInfo> _explainInfo; shared_ptr<ExplainSinglePlanQueryInfo> _explainInfo;
}; };
/** /**
* Record explain events for a QueryOptimizerCursor, which may record s ome explain information * Record explain events for a QueryOptimizerCursor, which may record s ome explain information
* for multiple clauses and plans through an internal implementation. * for multiple clauses and plans through an internal implementation.
*/ */
class QueryOptimizerCursorExplainStrategy : public MatchCountingExplain Strategy { class QueryOptimizerCursorExplainStrategy : public MatchCountingExplain Strategy {
public: public:
QueryOptimizerCursorExplainStrategy( const ExplainQueryInfo::Ancill aryInfo &ancillaryInfo, QueryOptimizerCursorExplainStrategy( const ExplainQueryInfo::Ancill aryInfo &ancillaryInfo,
const shared_ptr<QueryOptimizer Cursor> &cursor ); const shared_ptr<QueryOptimizer Cursor> &cursor );
private: private:
virtual void _noteIterate( bool match, bool orderedMatch, bool load virtual void _noteIterate( const ResultDetails& resultDetails );
edRecord,
bool chunkSkip );
virtual void noteYield(); virtual void noteYield();
virtual shared_ptr<ExplainQueryInfo> _doneQueryInfo(); virtual shared_ptr<ExplainQueryInfo> _doneQueryInfo();
shared_ptr<QueryOptimizerCursor> _cursor; shared_ptr<QueryOptimizerCursor> _cursor;
}; };
/** Interface for building a query response in a supplied BufBuilder. * / /** Interface for building a query response in a supplied BufBuilder. * /
class ResponseBuildStrategy { class ResponseBuildStrategy {
public: public:
/** /**
* @param queryPlan must be supplied if @param cursor is not a Quer yOptimizerCursor and * @param queryPlan must be supplied if @param cursor is not a Quer yOptimizerCursor and
* results must be sorted or read with a covered index. * results must be sorted or read with a covered index.
*/ */
ResponseBuildStrategy( const ParsedQuery &parsedQuery, const shared _ptr<Cursor> &cursor, ResponseBuildStrategy( const ParsedQuery &parsedQuery, const shared _ptr<Cursor> &cursor,
BufBuilder &buf ); BufBuilder &buf );
virtual ~ResponseBuildStrategy() {} virtual ~ResponseBuildStrategy() {}
/** /**
* Handle the current iterate of the supplied cursor as a (possibly duplicate) match. * Handle the current iterate of the supplied cursor as a (possibly duplicate) match.
* @return true if a match is found. * @return true if a match is found.
* @param orderedMatch set if it is an ordered match. * @param resultDetails details of how the result is matched and lo aded.
*/ */
virtual bool handleMatch( bool& orderedMatch, MatchDetails& details ) = 0; virtual bool handleMatch( ResultDetails* resultDetails ) = 0;
/** /**
* Write all matches into the buffer, overwriting existing data. * Write all matches into the buffer, overwriting existing data.
* @return number of matches written, or -1 if no op. * @return number of matches written, or -1 if no op.
*/ */
virtual int rewriteMatches() { return -1; } virtual int rewriteMatches() { return -1; }
/** @return the number of matches that have been written to the buf fer. */ /** @return the number of matches that have been written to the buf fer. */
virtual int bufferedMatches() const = 0; virtual int bufferedMatches() const = 0;
/** /**
* Callback when enough results have been read for the first batch, with potential handoff * Callback when enough results have been read for the first batch, with potential handoff
* to getMore. * to getMore.
*/ */
virtual void finishedFirstBatch() {} virtual void finishedFirstBatch() {}
/** Reset the buffer. */ /** Reset the buffer. */
void resetBuf(); void resetBuf();
protected: protected:
/** /**
* Return the document for the current iterate. Implements the $re turnKey option. * Return the document for the current iterate. Implements the $re turnKey option.
* @param allowCovered - enable covered index support. * @param allowCovered enable covered index support.
* @param resultDetails details of how the result is loaded.
*/ */
BSONObj current( bool allowCovered ) const; BSONObj current( bool allowCovered, ResultDetails* resultDetails ) const;
const ParsedQuery &_parsedQuery; const ParsedQuery &_parsedQuery;
shared_ptr<Cursor> _cursor; shared_ptr<Cursor> _cursor;
shared_ptr<QueryOptimizerCursor> _queryOptimizerCursor; shared_ptr<QueryOptimizerCursor> _queryOptimizerCursor;
BufBuilder &_buf; BufBuilder &_buf;
}; };
/** Build strategy for a cursor returning in order results. */ /** Build strategy for a cursor returning in order results. */
class OrderedBuildStrategy : public ResponseBuildStrategy { class OrderedBuildStrategy : public ResponseBuildStrategy {
public: public:
OrderedBuildStrategy( const ParsedQuery &parsedQuery, const shared_ ptr<Cursor> &cursor, OrderedBuildStrategy( const ParsedQuery &parsedQuery, const shared_ ptr<Cursor> &cursor,
BufBuilder &buf ); BufBuilder &buf );
virtual bool handleMatch( bool& orderedMatch, MatchDetails& details ); virtual bool handleMatch( ResultDetails* resultDetails );
virtual int bufferedMatches() const { return _bufferedMatches; } virtual int bufferedMatches() const { return _bufferedMatches; }
private: private:
int _skip; int _skip;
int _bufferedMatches; int _bufferedMatches;
}; };
class ScanAndOrder; class ScanAndOrder;
/** Build strategy for a cursor returning out of order results. */ /** Build strategy for a cursor returning out of order results. */
class ReorderBuildStrategy : public ResponseBuildStrategy { class ReorderBuildStrategy : public ResponseBuildStrategy {
public: public:
static ReorderBuildStrategy* make( const ParsedQuery& parsedQuery, static ReorderBuildStrategy* make( const ParsedQuery& parsedQuery,
const shared_ptr<Cursor>& cursor , const shared_ptr<Cursor>& cursor ,
BufBuilder& buf, BufBuilder& buf,
const QueryPlanSummary& queryPla n ); const QueryPlanSummary& queryPla n );
virtual bool handleMatch( bool &orderedMatch, MatchDetails& details ); virtual bool handleMatch( ResultDetails* resultDetails );
/** Handle a match without performing deduping. */ /** Handle a match without performing deduping. */
void _handleMatchNoDedup(); void _handleMatchNoDedup( ResultDetails* resultDetails );
virtual int rewriteMatches(); virtual int rewriteMatches();
virtual int bufferedMatches() const { return _bufferedMatches; } virtual int bufferedMatches() const { return _bufferedMatches; }
private: private:
ReorderBuildStrategy( const ParsedQuery& parsedQuery, ReorderBuildStrategy( const ParsedQuery& parsedQuery,
const shared_ptr<Cursor>& cursor, const shared_ptr<Cursor>& cursor,
BufBuilder& buf ); BufBuilder& buf );
void init( const QueryPlanSummary& queryPlan ); void init( const QueryPlanSummary& queryPlan );
ScanAndOrder *newScanAndOrder( const QueryPlanSummary &queryPlan ) const; ScanAndOrder *newScanAndOrder( const QueryPlanSummary &queryPlan ) const;
shared_ptr<ScanAndOrder> _scanAndOrder; shared_ptr<ScanAndOrder> _scanAndOrder;
int _bufferedMatches; int _bufferedMatches;
skipping to change at line 231 skipping to change at line 237
class HybridBuildStrategy : public ResponseBuildStrategy { class HybridBuildStrategy : public ResponseBuildStrategy {
public: public:
static HybridBuildStrategy* make( const ParsedQuery& parsedQuery, static HybridBuildStrategy* make( const ParsedQuery& parsedQuery,
const shared_ptr<QueryOptimizerCu rsor>& cursor, const shared_ptr<QueryOptimizerCu rsor>& cursor,
BufBuilder& buf ); BufBuilder& buf );
private: private:
HybridBuildStrategy( const ParsedQuery &parsedQuery, HybridBuildStrategy( const ParsedQuery &parsedQuery,
const shared_ptr<QueryOptimizerCursor> &cursor, const shared_ptr<QueryOptimizerCursor> &cursor,
BufBuilder &buf ); BufBuilder &buf );
void init(); void init();
virtual bool handleMatch( bool &orderedMatch, MatchDetails &details ); virtual bool handleMatch( ResultDetails* resultDetails );
virtual int rewriteMatches(); virtual int rewriteMatches();
virtual int bufferedMatches() const; virtual int bufferedMatches() const;
virtual void finishedFirstBatch(); virtual void finishedFirstBatch();
bool handleReorderMatch(); bool handleReorderMatch( ResultDetails* resultDetails );
DiskLocDupSet _scanAndOrderDups; DiskLocDupSet _scanAndOrderDups;
OrderedBuildStrategy _orderedBuild; OrderedBuildStrategy _orderedBuild;
scoped_ptr<ReorderBuildStrategy> _reorderBuild; scoped_ptr<ReorderBuildStrategy> _reorderBuild;
bool _reorderedMatches; bool _reorderedMatches;
}; };
/** /**
* Builds a query response with the help of an ExplainRecordingStrategy and a * Builds a query response with the help of an ExplainRecordingStrategy and a
* ResponseBuildStrategy. * ResponseBuildStrategy.
*/ */
skipping to change at line 286 skipping to change at line 292
private: private:
QueryResponseBuilder( const ParsedQuery &parsedQuery, const shared_ ptr<Cursor> &cursor ); QueryResponseBuilder( const ParsedQuery &parsedQuery, const shared_ ptr<Cursor> &cursor );
void init( const QueryPlanSummary &queryPlan, const BSONObj &oldPla n ); void init( const QueryPlanSummary &queryPlan, const BSONObj &oldPla n );
ShardChunkManagerPtr newChunkManager() const; ShardChunkManagerPtr newChunkManager() const;
shared_ptr<ExplainRecordingStrategy> newExplainRecordingStrategy shared_ptr<ExplainRecordingStrategy> newExplainRecordingStrategy
( const QueryPlanSummary &queryPlan, const BSONObj &oldPlan ) const ; ( const QueryPlanSummary &queryPlan, const BSONObj &oldPlan ) const ;
shared_ptr<ResponseBuildStrategy> newResponseBuildStrategy shared_ptr<ResponseBuildStrategy> newResponseBuildStrategy
( const QueryPlanSummary &queryPlan ); ( const QueryPlanSummary &queryPlan );
bool currentMatches( MatchDetails& details ); /**
bool chunkMatches(); * @return true if the cursor's document matches the query.
* @param resultDetails describes how the document was matched and
loaded.
*/
bool currentMatches( ResultDetails* resultDetails );
/**
* @return true if the cursor's document is in a valid chunk range.
* @param resultDetails describes how the document was matched and
loaded.
*/
bool chunkMatches( ResultDetails* resultDetails );
const ParsedQuery &_parsedQuery; const ParsedQuery &_parsedQuery;
shared_ptr<Cursor> _cursor; shared_ptr<Cursor> _cursor;
shared_ptr<QueryOptimizerCursor> _queryOptimizerCursor; shared_ptr<QueryOptimizerCursor> _queryOptimizerCursor;
BufBuilder _buf; BufBuilder _buf;
ShardChunkManagerPtr _chunkManager; ShardChunkManagerPtr _chunkManager;
shared_ptr<ExplainRecordingStrategy> _explain; shared_ptr<ExplainRecordingStrategy> _explain;
shared_ptr<ResponseBuildStrategy> _builder; shared_ptr<ResponseBuildStrategy> _builder;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 16 change blocks. 
26 lines changed or deleted 44 lines changed or added


 queryoptimizer.h   queryoptimizer.h 
skipping to change at line 54 skipping to change at line 54
static QueryPlan *make( NamespaceDetails *d, static QueryPlan *make( NamespaceDetails *d,
int idxNo, // -1 = no index int idxNo, // -1 = no index
const FieldRangeSetPair &frsp, const FieldRangeSetPair &frsp,
const FieldRangeSetPair *originalFrsp, const FieldRangeSetPair *originalFrsp,
const BSONObj &originalQuery, const BSONObj &originalQuery,
const BSONObj &order, const BSONObj &order,
const shared_ptr<const ParsedQuery> &parsedQ uery = const shared_ptr<const ParsedQuery> &parsedQ uery =
shared_ptr<const ParsedQuery>(), shared_ptr<const ParsedQuery>(),
const BSONObj &startKey = BSONObj(), const BSONObj &startKey = BSONObj(),
const BSONObj &endKey = BSONObj(), const BSONObj &endKey = BSONObj(),
string special="" ); const std::string& special="" );
/** Categorical classification of a QueryPlan's utility. */ /** Categorical classification of a QueryPlan's utility. */
enum Utility { enum Utility {
Impossible, // Cannot produce any matches, so the query must ha ve an empty result set. Impossible, // Cannot produce any matches, so the query must ha ve an empty result set.
// No other plans need to be considered. // No other plans need to be considered.
Optimal, // Should run as the only candidate plan in the abs ence of an Impossible Optimal, // Should run as the only candidate plan in the abs ence of an Impossible
// plan. // plan.
Helpful, // Should be considered. Helpful, // Should be considered.
Unhelpful, // Should not be considered. Unhelpful, // Should not be considered.
Disallowed // Must not be considered unless explicitly hinted. May produce a Disallowed // Must not be considered unless explicitly hinted. May produce a
skipping to change at line 102 skipping to change at line 102
const IndexDetails *index() const { return _index; } const IndexDetails *index() const { return _index; }
int idxNo() const { return _idxNo; } int idxNo() const { return _idxNo; }
const char *ns() const { return _frs.ns(); } const char *ns() const { return _frs.ns(); }
NamespaceDetails *nsd() const { return _d; } NamespaceDetails *nsd() const { return _d; }
BSONObj originalQuery() const { return _originalQuery; } BSONObj originalQuery() const { return _originalQuery; }
shared_ptr<FieldRangeVector> originalFrv() const { return _original Frv; } shared_ptr<FieldRangeVector> originalFrv() const { return _original Frv; }
const FieldRangeSet &multikeyFrs() const { return _frsMulti; } const FieldRangeSet &multikeyFrs() const { return _frsMulti; }
shared_ptr<Projection::KeyOnly> keyFieldsOnly() const { return _key FieldsOnly; } shared_ptr<Projection::KeyOnly> keyFieldsOnly() const { return _key FieldsOnly; }
const ParsedQuery* parsedQuery() const { return _parsedQuery.get(); }
/** @return a shared, lazily initialized matcher for the query plan . */ /** @return a shared, lazily initialized matcher for the query plan . */
shared_ptr<CoveredIndexMatcher> matcher() const; shared_ptr<CoveredIndexMatcher> matcher() const;
QueryPlanSummary summary() const; QueryPlanSummary summary() const;
/** The following member functions are for testing, or public for t esting. */ /** The following member functions are for testing, or public for t esting. */
shared_ptr<FieldRangeVector> frv() const { return _frv; } shared_ptr<FieldRangeVector> frv() const { return _frv; }
bool isMultiKey() const; bool isMultiKey() const;
skipping to change at line 123 skipping to change at line 124
bool queryBoundsExactOrderSuffix() const; bool queryBoundsExactOrderSuffix() const;
private: private:
QueryPlan(NamespaceDetails *d, QueryPlan(NamespaceDetails *d,
int idxNo, int idxNo,
const FieldRangeSetPair &frsp, const FieldRangeSetPair &frsp,
const BSONObj &originalQuery, const BSONObj &originalQuery,
const BSONObj &order, const BSONObj &order,
const shared_ptr<const ParsedQuery> &parsedQuery, const shared_ptr<const ParsedQuery> &parsedQuery,
string special ); const std::string& special );
void init( const FieldRangeSetPair *originalFrsp, void init( const FieldRangeSetPair *originalFrsp,
const BSONObj &startKey, const BSONObj &startKey,
const BSONObj &endKey ); const BSONObj &endKey );
void checkTableScanAllowed() const; void checkTableScanAllowed() const;
int independentRangesSingleIntervalLimit() const; int independentRangesSingleIntervalLimit() const;
/** @return true when the plan's query may contains an $exists:fals e predicate. */ /** @return true when the plan's query may contains an $exists:fals e predicate. */
bool hasPossibleExistsFalsePredicate() const; bool hasPossibleExistsFalsePredicate() const;
NamespaceDetails * _d; NamespaceDetails * _d;
skipping to change at line 678 skipping to change at line 679
virtual bool supportYields() { return true; } virtual bool supportYields() { return true; }
virtual BSONObj indexKeyPattern() { return _c->indexKeyPattern(); } virtual BSONObj indexKeyPattern() { return _c->indexKeyPattern(); }
/** Deduping documents from a prior cursor is handled by the matche r. */ /** Deduping documents from a prior cursor is handled by the matche r. */
virtual bool getsetdup(DiskLoc loc) { return _c->getsetdup( loc ); } virtual bool getsetdup(DiskLoc loc) { return _c->getsetdup( loc ); }
virtual bool modifiedKeys() const { return true; } virtual bool modifiedKeys() const { return true; }
virtual bool isMultiKey() const { return _mps->hasMultiKey(); } virtual bool isMultiKey() const { return _mps->hasMultiKey(); }
virtual shared_ptr< CoveredIndexMatcher > matcherPtr() const { retu rn _matcher; }
virtual CoveredIndexMatcher* matcher() const { return _matcher.get( ); } virtual CoveredIndexMatcher* matcher() const { return _matcher.get( ); }
virtual bool capped() const { return _c->capped(); } virtual bool capped() const { return _c->capped(); }
virtual long long nscanned() { return _nscanned + _c->nscanned(); } virtual long long nscanned() { return _nscanned + _c->nscanned(); }
void noteIterate( bool match, bool loadedRecord ); void noteIterate( bool match, bool loadedRecord );
const QueryPlan &queryPlan() const { const QueryPlan &queryPlan() const {
verify( _c->ok() && _queryPlan ); verify( _c->ok() && _queryPlan );
 End of changes. 4 change blocks. 
3 lines changed or deleted 3 lines changed or added


 queryutil.h   queryutil.h 
skipping to change at line 28 skipping to change at line 28
#pragma once #pragma once
#include "jsobj.h" #include "jsobj.h"
#include "indexkey.h" #include "indexkey.h"
#include "projection.h" #include "projection.h"
namespace mongo { namespace mongo {
extern const int MaxBytesToReturnToClientAtOnce; extern const int MaxBytesToReturnToClientAtOnce;
//maximum number of intervals produced by $in queries.
static const unsigned MAX_IN_COMBINATIONS = 4000000;
/* This is for languages whose "objects" are not well ordered (JSON is well ordered). /* This is for languages whose "objects" are not well ordered (JSON is well ordered).
[ { a : ... } , { b : ... } ] -> { a : ..., b : ... } [ { a : ... } , { b : ... } ] -> { a : ..., b : ... }
*/ */
inline BSONObj transformOrderFromArrayFormat(BSONObj order) { inline BSONObj transformOrderFromArrayFormat(BSONObj order) {
/* note: this is slow, but that is ok as order will have very few p ieces */ /* note: this is slow, but that is ok as order will have very few p ieces */
BSONObjBuilder b; BSONObjBuilder b;
char p[2] = "0"; char p[2] = "0";
while ( 1 ) { while ( 1 ) {
BSONObj j = order.getObjectField(p); BSONObj j = order.getObjectField(p);
skipping to change at line 299 skipping to change at line 302
* Creates a FieldRange representing a superset of the BSONElement values matching a query * Creates a FieldRange representing a superset of the BSONElement values matching a query
* expression element. * expression element.
* @param e - The query expression element. * @param e - The query expression element.
* @param isNot - Indicates that 'e' appears within a query $not cl ause and its matching * @param isNot - Indicates that 'e' appears within a query $not cl ause and its matching
* semantics are inverted. * semantics are inverted.
* @param optimize - If true, the range may be bracketed by 'e''s d ata type. * @param optimize - If true, the range may be bracketed by 'e''s d ata type.
* TODO It is unclear why 'optimize' is optional, see SERVER-51 65. * TODO It is unclear why 'optimize' is optional, see SERVER-51 65.
*/ */
FieldRange( const BSONElement &e , bool isNot, bool optimize ); FieldRange( const BSONElement &e , bool isNot, bool optimize );
void setElemMatchContext( const BSONElement& elemMatchContext ) {
_elemMatchContext = elemMatchContext;
}
/** /**
* @return Range intersection with 'other'. * @return Range intersection with 'other'.
* @param singleKey - Indicate whether intersection will be perform ed in a single value or * @param singleKey - Indicate whether intersection will be perform ed in a single value or
* multi value context. * multi value context.
*/ */
const FieldRange &intersect( const FieldRange &other, bool singleKe y ); const FieldRange &intersect( const FieldRange &other, bool singleKe y );
/** @return Range union with 'other'. */ /** @return Range union with 'other'. */
const FieldRange &operator|=( const FieldRange &other ); const FieldRange &operator|=( const FieldRange &other );
/** @return Range of elements elements included in 'this' but not ' other'. */ /** @return Range of elements elements included in 'this' but not ' other'. */
const FieldRange &operator-=( const FieldRange &other ); const FieldRange &operator-=( const FieldRange &other );
skipping to change at line 347 skipping to change at line 354
*/ */
bool mustBeExactMatchRepresentation() const { return _exactMatchRep resentation; } bool mustBeExactMatchRepresentation() const { return _exactMatchRep resentation; }
/* Checks whether this FieldRange is a non-empty union of point-int ervals. /* Checks whether this FieldRange is a non-empty union of point-int ervals.
* Examples: * Examples:
* FieldRange( { a:3 } ), isPointIntervalSet() -> true * FieldRange( { a:3 } ), isPointIntervalSet() -> true
* FieldRange( { a:{ $in:[ 1, 2 ] } } ), isPointIntervalSet() -> t rue * FieldRange( { a:{ $in:[ 1, 2 ] } } ), isPointIntervalSet() -> t rue
* FieldRange( { a:{ $gt:5 } } ), isPointIntervalSet() -> false * FieldRange( { a:{ $gt:5 } } ), isPointIntervalSet() -> false
* FieldRange( {} ), isPointIntervalSet() -> false * FieldRange( {} ), isPointIntervalSet() -> false
*/ */
bool isPointIntervalSet() const; bool isPointIntervalSet() const;
const BSONElement& elemMatchContext() const { return _elemMatchCont ext; }
/** Empty the range so it includes no BSONElements. */ /** Empty the range so it includes no BSONElements. */
void makeEmpty() { _intervals.clear(); } void makeEmpty() { _intervals.clear(); }
const vector<FieldInterval> &intervals() const { return _intervals; } const vector<FieldInterval> &intervals() const { return _intervals; }
string getSpecial() const { return _special; } string getSpecial() const { return _special; }
/** Make component intervals noninclusive. */ /** Make component intervals noninclusive. */
void setExclusiveBounds(); void setExclusiveBounds();
/** /**
* Constructs a range where all FieldIntervals and FieldBounds are in * Constructs a range where all FieldIntervals and FieldBounds are in
* the opposite order of the current range. * the opposite order of the current range.
* NOTE the resulting intervals might not be strictValid(). * NOTE the resulting intervals might not be strictValid().
*/ */
void reverse( FieldRange &ret ) const; void reverse( FieldRange &ret ) const;
bool hasSpecialThatNeedsIndex() const { verify( _special.size() );
return _specialNeedsIndex; }
string toString() const; string toString() const;
private: private:
BSONObj addObj( const BSONObj &o ); BSONObj addObj( const BSONObj &o );
void finishOperation( const vector<FieldInterval> &newIntervals, co nst FieldRange &other, void finishOperation( const vector<FieldInterval> &newIntervals, co nst FieldRange &other,
bool exactMatchRepresentation ); bool exactMatchRepresentation );
vector<FieldInterval> _intervals; vector<FieldInterval> _intervals;
// Owns memory for our BSONElements. // Owns memory for our BSONElements.
vector<BSONObj> _objData; vector<BSONObj> _objData;
string _special; string _special; // Index type name of a non standard (eg '2d') ind
bool _specialNeedsIndex; ex required by a parsed
// query operator (eg '$near').
bool _exactMatchRepresentation; bool _exactMatchRepresentation;
BSONElement _elemMatchContext; // Parent $elemMatch object of the f
ield constraint that
// generated this FieldRange. For e
xample if the query is
// { a:{ $elemMatch:{ b:1, c:1 } } }
, then the
// _elemMatchContext for the FieldRa
nge on 'a.b' is the query
// element having field name '$elemM
atch'.
}; };
/**
* A BoundList contains intervals specified by inclusive start
* and end bounds. The intervals should be nonoverlapping and occur in
* the specified direction of traversal. For example, given a simple i
ndex {i:1}
* and direction +1, one valid BoundList is: (1, 2); (4, 6). The same
BoundList
* would be valid for index {i:-1} with direction -1.
*/
typedef vector<pair<BSONObj,BSONObj> > BoundList;
class QueryPattern; class QueryPattern;
/** /**
* A set of FieldRanges determined from constraints on the fields of a query, * A set of FieldRanges determined from constraints on the fields of a query,
* that may be used to determine index bounds. * that may be used to determine index bounds.
*/ */
class FieldRangeSet { class FieldRangeSet {
public: public:
friend class OrRangeGenerator; friend class OrRangeGenerator;
friend class FieldRangeVector; friend class FieldRangeVector;
skipping to change at line 462 skipping to change at line 464
/** /**
* @return a simplified query from the extreme values of the non un iversal * @return a simplified query from the extreme values of the non un iversal
* fields. * fields.
* @param fields If specified, the fields of the returned object ar e * @param fields If specified, the fields of the returned object ar e
* ordered to match those of 'fields'. * ordered to match those of 'fields'.
*/ */
BSONObj simplifiedQuery( const BSONObj &fields = BSONObj() ) const; BSONObj simplifiedQuery( const BSONObj &fields = BSONObj() ) const;
QueryPattern pattern( const BSONObj &sort = BSONObj() ) const; QueryPattern pattern( const BSONObj &sort = BSONObj() ) const;
string getSpecial() const; string getSpecial() const;
bool hasSpecialThatNeedsIndex() const;
/** /**
* @return a FieldRangeSet approximation of the documents in 'this' but * @return a FieldRangeSet approximation of the documents in 'this' but
* not in 'other'. The approximation will be a superset of the doc uments * not in 'other'. The approximation will be a superset of the doc uments
* in 'this' but not 'other'. * in 'this' but not 'other'.
*/ */
const FieldRangeSet &operator-=( const FieldRangeSet &other ); const FieldRangeSet &operator-=( const FieldRangeSet &other );
/** @return intersection of 'this' with 'other'. */ /** @return intersection of 'this' with 'other'. */
const FieldRangeSet &operator&=( const FieldRangeSet &other ); const FieldRangeSet &operator&=( const FieldRangeSet &other );
/** /**
* @return an ordered list of bounds generated using an index key p
attern
* and traversal direction.
*
* The value of matchPossible() should be true, otherwise this func
tion
* may @throw.
*
* NOTE This function is deprecated in the query optimizer and only
* currently used by sharding code.
*/
BoundList indexBounds( const BSONObj &keyPattern, int direction ) c
onst;
/**
* @return - A new FieldRangeSet based on this FieldRangeSet, but w ith only * @return - A new FieldRangeSet based on this FieldRangeSet, but w ith only
* a subset of the fields. * a subset of the fields.
* @param fields - Only fields which are represented as field names in this object * @param fields - Only fields which are represented as field names in this object
* will be included in the returned FieldRangeSet. * will be included in the returned FieldRangeSet.
*/ */
FieldRangeSet *subset( const BSONObj &fields ) const; FieldRangeSet *subset( const BSONObj &fields ) const;
/** /**
* @return A new FieldRangeSet based on this FieldRangeSet, but wit h all field names * @return A new FieldRangeSet based on this FieldRangeSet, but wit h all field names
* prefixed by the specified @param prefix field name. * prefixed by the specified @param prefix field name.
skipping to change at line 584 skipping to change at line 573
bool matchPossible() const { return _multiKey.matchPossible(); } bool matchPossible() const { return _multiKey.matchPossible(); }
/** /**
* @return false if a match is impossible on the specified index. * @return false if a match is impossible on the specified index.
* @param idxNo -1 for non index scan. * @param idxNo -1 for non index scan.
*/ */
bool matchPossibleForIndex( NamespaceDetails *d, int idxNo, const B SONObj &keyPattern ) const; bool matchPossibleForIndex( NamespaceDetails *d, int idxNo, const B SONObj &keyPattern ) const;
const char *ns() const { return _singleKey.ns(); } const char *ns() const { return _singleKey.ns(); }
string getSpecial() const { return _singleKey.getSpecial(); } string getSpecial() const { return _singleKey.getSpecial(); }
bool hasSpecialThatNeedsIndex() const { return _singleKey.hasSpecia lThatNeedsIndex(); }
/** Intersect with another FieldRangeSetPair. */ /** Intersect with another FieldRangeSetPair. */
FieldRangeSetPair &operator&=( const FieldRangeSetPair &other ); FieldRangeSetPair &operator&=( const FieldRangeSetPair &other );
/** /**
* Subtract a FieldRangeSet, generally one expressing a range that has * Subtract a FieldRangeSet, generally one expressing a range that has
* already been scanned. * already been scanned.
*/ */
FieldRangeSetPair &operator-=( const FieldRangeSet &scanned ); FieldRangeSetPair &operator-=( const FieldRangeSet &scanned );
BoundList shardKeyIndexBounds( const BSONObj &keyPattern ) const { bool matchPossibleForSingleKeyFRS( const BSONObj &keyPattern ) cons
return _singleKey.indexBounds( keyPattern, 1 ); t {
}
bool matchPossibleForShardKey( const BSONObj &keyPattern ) const {
return _singleKey.matchPossibleForIndex( keyPattern ); return _singleKey.matchPossibleForIndex( keyPattern );
} }
BSONObj originalQuery() const { return _singleKey.originalQuery(); } BSONObj originalQuery() const { return _singleKey.originalQuery(); }
const FieldRangeSet getSingleKeyFRS() const { return _singleKey; }
const FieldRangeSet getMultiKeyFRS() const { return _singleKey; }
string toString() const; string toString() const;
private: private:
FieldRangeSetPair( const FieldRangeSet &singleKey, const FieldRange Set &multiKey ) FieldRangeSetPair( const FieldRangeSet &singleKey, const FieldRange Set &multiKey )
:_singleKey( singleKey ), _multiKey( multiKey ) {} :_singleKey( singleKey ), _multiKey( multiKey ) {}
void assertValidIndex( const NamespaceDetails *d, int idxNo ) const ; void assertValidIndex( const NamespaceDetails *d, int idxNo ) const ;
void assertValidIndexOrNoIndex( const NamespaceDetails *d, int idxN o ) const; void assertValidIndexOrNoIndex( const NamespaceDetails *d, int idxN o ) const;
/** matchPossibleForIndex() must be true. */ /** matchPossibleForIndex() must be true. */
BSONObj simplifiedQueryForIndex( NamespaceDetails *d, int idxNo, co nst BSONObj &keyPattern ) const; BSONObj simplifiedQueryForIndex( NamespaceDetails *d, int idxNo, co nst BSONObj &keyPattern ) const;
FieldRangeSet _singleKey; FieldRangeSet _singleKey;
FieldRangeSet _multiKey; FieldRangeSet _multiKey;
 End of changes. 12 change blocks. 
38 lines changed or deleted 26 lines changed or added


 race.h   race.h 
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "../goodies.h" // printStackTrace #include "../goodies.h" // printStackTrace
#include "mutexdebugger.h" #include "mutexdebugger.h"
#include "mongo/util/stacktrace.h" #include "mongo/util/stacktrace.h"
namespace mongo { namespace mongo {
namespace race { namespace race {
skipping to change at line 51 skipping to change at line 67
sleepmillis(3); sleepmillis(3);
} }
} }
} }
} }
} }
void leave() { void leave() {
if( --n != 0 ) fail(); if( --n != 0 ) fail();
} }
public: public:
Block(string f, unsigned l) : n(0), ncalls(0), file(f), line(l) { } Block(const std::string& f, unsigned l) : n(0), ncalls(0), file (f), line(l) { }
~Block() { ~Block() {
if( ncalls > 1000000 ) { if( ncalls > 1000000 ) {
// just so we know if we are slowing things down // just so we know if we are slowing things down
log() << "race::Block lots of calls " << file << ' ' << line << " n:" << ncalls << endl; log() << "race::Block lots of calls " << file << ' ' << line << " n:" << ncalls << endl;
} }
} }
class Within { class Within {
Block& _s; Block& _s;
public: public:
Within(Block& s) : _s(s) { _s.enter(); } Within(Block& s) : _s(s) { _s.enter(); }
 End of changes. 2 change blocks. 
1 lines changed or deleted 19 lines changed or added


 ramlog.h   ramlog.h 
skipping to change at line 26 skipping to change at line 26
*/ */
#pragma once #pragma once
#include "log.h" #include "log.h"
namespace mongo { namespace mongo {
class RamLog : public Tee { class RamLog : public Tee {
public: public:
RamLog( string name ); RamLog( const std::string& name );
virtual void write(LogLevel ll, const string& str); virtual void write(LogLevel ll, const string& str);
void get( vector<const char*>& v) const; void get( vector<const char*>& v) const;
void toHTML(stringstream& s); void toHTML(stringstream& s);
static RamLog* get( string name ); static RamLog* get( const std::string& name );
static void getNames( vector<string>& names ); static void getNames( vector<string>& names );
time_t lastWrite() { return _lastWrite; } // 0 if no writes time_t lastWrite() { return _lastWrite; } // 0 if no writes
protected: protected:
static int repeats(const vector<const char *>& v, int i); static int repeats(const vector<const char *>& v, int i);
static string clean(const vector<const char *>& v, int i, string li ne=""); static string clean(const vector<const char *>& v, int i, string li ne="");
static string color(string line); static string color(const std::string& line);
/* turn http:... into an anchor */ /* turn http:... into an anchor */
static string linkify(const char *s); static string linkify(const char *s);
private: private:
~RamLog(); // want this private as we want to leak so we can use th em till the very end ~RamLog(); // want this private as we want to leak so we can use th em till the very end
enum { enum {
N = 128, // number of links N = 128, // number of links
C = 256 // max size of line C = 256 // max size of line
}; };
char lines[N][C]; char lines[N][C];
unsigned h; // current position unsigned h; // current position
unsigned n; // numer of lines stores 0 o N unsigned n; // number of lines stores 0 o N
string _name; string _name;
typedef map<string,RamLog*> RM; typedef map<string,RamLog*> RM;
static mongo::mutex* _namedLock; static mongo::mutex* _namedLock;
static RM* _named; static RM* _named;
time_t _lastWrite; time_t _lastWrite;
}; };
} }
 End of changes. 4 change blocks. 
4 lines changed or deleted 4 lines changed or added


 repl.h   repl.h 
skipping to change at line 97 skipping to change at line 97
Can be a group of things to replicate for several databases. Can be a group of things to replicate for several databases.
{ host: ..., source: ..., only: ..., syncedTo: ..., dbsNextPass: { ... }, incompleteCloneDbs: { ... } } { host: ..., source: ..., only: ..., syncedTo: ..., dbsNextPass: { ... }, incompleteCloneDbs: { ... } }
'source' defaults to 'main'; support for multiple source names is 'source' defaults to 'main'; support for multiple source names is
not done (always use main for now). not done (always use main for now).
*/ */
class ReplSource { class ReplSource {
shared_ptr<ThreadPool> tp; shared_ptr<ThreadPool> tp;
void resync(string db); void resync(const std::string& dbName);
/** @param alreadyLocked caller already put us in write lock if tru e */ /** @param alreadyLocked caller already put us in write lock if tru e */
void sync_pullOpLog_applyOperation(BSONObj& op, bool alreadyLocked) ; void sync_pullOpLog_applyOperation(BSONObj& op, bool alreadyLocked) ;
/* pull some operations from the master's oplog, and apply them. /* pull some operations from the master's oplog, and apply them.
calls sync_pullOpLog_applyOperation calls sync_pullOpLog_applyOperation
*/ */
int sync_pullOpLog(int& nApplied); int sync_pullOpLog(int& nApplied);
/* we only clone one database per pass, even if a lot need done. T his helps us /* we only clone one database per pass, even if a lot need done. T his helps us
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 repl_block.h   repl_block.h 
skipping to change at line 39 skipping to change at line 39
namespace mongo { namespace mongo {
void updateSlaveLocation( CurOp& curop, const char * oplog_ns , OpTime lastOp ); void updateSlaveLocation( CurOp& curop, const char * oplog_ns , OpTime lastOp );
/** @return true if op has made it to w servers */ /** @return true if op has made it to w servers */
bool opReplicatedEnough( OpTime op , int w ); bool opReplicatedEnough( OpTime op , int w );
bool opReplicatedEnough( OpTime op , BSONElement w ); bool opReplicatedEnough( OpTime op , BSONElement w );
bool waitForReplication( OpTime op , int w , int maxSecondsToWait ); bool waitForReplication( OpTime op , int w , int maxSecondsToWait );
std::vector<std::string> getHostsReplicatedTo(OpTime& op);
void resetSlaveCache(); void resetSlaveCache();
unsigned getSlaveCount(); unsigned getSlaveCount();
} }
 End of changes. 1 change blocks. 
0 lines changed or deleted 2 lines changed or added


 resource.h   resource.h 
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//{{NO_DEPENDENCIES}} //{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by db.rc // Used by db.rc
// //
#define IDI_ICON2 102 #define IDI_ICON2 102
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 rs.h   rs.h 
skipping to change at line 298 skipping to change at line 298
rwlock lk(m, true); rwlock lk(m, true);
verify(!sp.state.primary()); verify(!sp.state.primary());
sp.primary = remote; sp.primary = remote;
} }
StateBox() : m("StateBox") { } StateBox() : m("StateBox") { }
private: private:
RWLock m; RWLock m;
SP sp; SP sp;
}; };
void parseReplsetCmdLine(string cfgString, string& setname, vector<Host void parseReplsetCmdLine(const std::string& cfgString,
AndPort>& seeds, set<HostAndPort>& seedSet ); string& setname,
vector<HostAndPort>& seeds,
set<HostAndPort>& seedSet);
/** Parameter given to the --replSet command line option (parsed). /** Parameter given to the --replSet command line option (parsed).
Syntax is "<setname>/<seedhost1>,<seedhost2>" Syntax is "<setname>/<seedhost1>,<seedhost2>"
where setname is a name and seedhost is "<host>[:<port>]" */ where setname is a name and seedhost is "<host>[:<port>]" */
class ReplSetCmdline { class ReplSetCmdline {
public: public:
ReplSetCmdline(string cfgString) { parseReplsetCmdLine(cfgString, s etname, seeds, seedSet); } ReplSetCmdline(const std::string& cfgString) { parseReplsetCmdLine( cfgString, setname, seeds, seedSet); }
string setname; string setname;
vector<HostAndPort> seeds; vector<HostAndPort> seeds;
set<HostAndPort> seedSet; set<HostAndPort> seedSet;
}; };
/* information about the entire repl set, such as the various servers i n the set, and their state */ /* information about the entire repl set, such as the various servers i n the set, and their state */
/* note: We currently do not free mem when the set goes away - it is as sumed the replset is a /* note: We currently do not free mem when the set goes away - it is as sumed the replset is a
singleton and long lived. singleton and long lived.
*/ */
class ReplSetImpl : protected RSBase { class ReplSetImpl : protected RSBase {
skipping to change at line 371 skipping to change at line 374
void blockSync(bool block); void blockSync(bool block);
// set of electable members' _ids // set of electable members' _ids
set<unsigned> _electableSet; set<unsigned> _electableSet;
protected: protected:
// "heartbeat message" // "heartbeat message"
// sent in requestHeartbeat respond in field "hbm" // sent in requestHeartbeat respond in field "hbm"
char _hbmsg[256]; // we change this unlocked, thus not an stl::stri ng char _hbmsg[256]; // we change this unlocked, thus not an stl::stri ng
time_t _hbmsgTime; // when it was logged time_t _hbmsgTime; // when it was logged
public: public:
void sethbmsg(string s, int logLevel = 0); void sethbmsg(const std::string& s, int logLevel = 0);
/** /**
* Election with Priorities * Election with Priorities
* *
* Each node (n) keeps a set of nodes that could be elected primary . * Each node (n) keeps a set of nodes that could be elected primary .
* Each node in this set: * Each node in this set:
* *
* 1. can connect to a majority of the set * 1. can connect to a majority of the set
* 2. has a priority greater than 0 * 2. has a priority greater than 0
* 3. has an optime within 10 seconds of the most up-to-date node * 3. has an optime within 10 seconds of the most up-to-date node
skipping to change at line 430 skipping to change at line 433
void _fillIsMaster(BSONObjBuilder&); void _fillIsMaster(BSONObjBuilder&);
void _fillIsMasterHost(const Member*, vector<string>&, vector<strin g>&, vector<string>&); void _fillIsMasterHost(const Member*, vector<string>&, vector<strin g>&, vector<string>&);
const ReplSetConfig& config() { return *_cfg; } const ReplSetConfig& config() { return *_cfg; }
string name() const { return _name; } /* @return replica set's logi cal name */ string name() const { return _name; } /* @return replica set's logi cal name */
MemberState state() const { return box.getState(); } MemberState state() const { return box.getState(); }
void _fatal(); void _fatal();
void _getOplogDiagsAsHtml(unsigned server_id, stringstream& ss) con st; void _getOplogDiagsAsHtml(unsigned server_id, stringstream& ss) con st;
void _summarizeAsHtml(stringstream&) const; void _summarizeAsHtml(stringstream&) const;
void _summarizeStatus(BSONObjBuilder&) const; // for replSetGetStat us command void _summarizeStatus(BSONObjBuilder&) const; // for replSetGetStat us command
/* throws exception if a problem initializing. */
ReplSetImpl(ReplSetCmdline&);
// used for testing
ReplSetImpl();
/* call afer constructing to start - returns fairly quickly after l aunching its threads */ /* call afer constructing to start - returns fairly quickly after l aunching its threads */
void _go(); void _go();
private: private:
string _name; string _name;
const vector<HostAndPort> *_seeds; const vector<HostAndPort> *_seeds;
ReplSetConfig *_cfg; ReplSetConfig *_cfg;
/** /**
* Finds the configuration with the highest version number and atte mpts * Finds the configuration with the highest version number and atte mpts
* load it. * load it.
*/ */
bool _loadConfigFinish(vector<ReplSetConfig>& v); bool _loadConfigFinish(vector<ReplSetConfig*>& v);
/** /**
* Gather all possible configs (from command line seeds, our own co nfig * Gather all possible configs (from command line seeds, our own co nfig
* doc, and any hosts listed therein) and try to initiate from the most * doc, and any hosts listed therein) and try to initiate from the most
* recent config we find. * recent config we find.
*/ */
void loadConfig(); void loadConfig();
list<HostAndPort> memberHostnames() const; list<HostAndPort> memberHostnames() const;
bool iAmArbiterOnly() const { return myConfig().arbiterOnly; } bool iAmArbiterOnly() const { return myConfig().arbiterOnly; }
bool iAmPotentiallyHot() const { bool iAmPotentiallyHot() const {
return myConfig().potentiallyHot() && // not an arbiter return myConfig().potentiallyHot() && // not an arbiter
elect.steppedDown <= time(0) && // not stepped down/frozen elect.steppedDown <= time(0) && // not stepped down/frozen
state() == MemberState::RS_SECONDARY; // not stale state() == MemberState::RS_SECONDARY; // not stale
} }
protected: protected:
Member *_self; Member *_self;
bool _buildIndexes; // = _self->config().buildIndexes bool _buildIndexes; // = _self->config().buildIndexes
ReplSetImpl();
/* throws exception if a problem initializing. */
void init(ReplSetCmdline&);
void setSelfTo(Member *); // use this as it sets buildIndexes var void setSelfTo(Member *); // use this as it sets buildIndexes var
private: private:
List1<Member> _members; // all members of the set EXCEPT _self. List1<Member> _members; // all members of the set EXCEPT _self.
ReplSetConfig::MemberCfg _config; // config of _self ReplSetConfig::MemberCfg _config; // config of _self
unsigned _id; // _id of _self unsigned _id; // _id of _self
int _maintenanceMode; // if we should stay in recovering state int _maintenanceMode; // if we should stay in recovering state
public: public:
// this is called from within a writelock in logOpRS // this is called from within a writelock in logOpRS
unsigned selfId() const { return _id; } unsigned selfId() const { return _id; }
Manager *mgr; Manager *mgr;
GhostSync *ghost; GhostSync *ghost;
/** /**
* This forces a secondary to go into recovering state and stay the re * This forces a secondary to go into recovering state and stay the re
* until this is called again, passing in "false". Multiple thread s can * until this is called again, passing in "false". Multiple thread s can
* call this and it will leave maintenance mode once all of the cal lers * call this and it will leave maintenance mode once all of the cal lers
* have called it again, passing in false. * have called it again, passing in false.
*/ */
bool setMaintenanceMode(const bool inc); void setMaintenanceMode(const bool inc);
private: private:
Member* head() const { return _members.head(); } Member* head() const { return _members.head(); }
public: public:
const Member* findById(unsigned id) const; const Member* findById(unsigned id) const;
Member* findByName(const std::string& hostname) const;
private: private:
void _getTargets(list<Target>&, int &configVersion); void _getTargets(list<Target>&, int &configVersion);
void getTargets(list<Target>&, int &configVersion); void getTargets(list<Target>&, int &configVersion);
void startThreads(); void startThreads();
friend class FeedbackThread; friend class FeedbackThread;
friend class CmdReplSetElect; friend class CmdReplSetElect;
friend class Member; friend class Member;
friend class Manager; friend class Manager;
friend class GhostSync; friend class GhostSync;
friend class Consensus; friend class Consensus;
skipping to change at line 550 skipping to change at line 554
const OpTime lastOtherOpTime() const; const OpTime lastOtherOpTime() const;
static void setMinValid(BSONObj obj); static void setMinValid(BSONObj obj);
int oplogVersion; int oplogVersion;
private: private:
IndexPrefetchConfig _indexPrefetchConfig; IndexPrefetchConfig _indexPrefetchConfig;
}; };
class ReplSet : public ReplSetImpl { class ReplSet : public ReplSetImpl {
public: public:
ReplSet(); static ReplSet* make(ReplSetCmdline& replSetCmdline);
ReplSet(ReplSetCmdline& replSetCmdline);
virtual ~ReplSet() {} virtual ~ReplSet() {}
// for the replSetStepDown command // for the replSetStepDown command
bool stepDown(int secs) { return _stepDown(secs); } bool stepDown(int secs) { return _stepDown(secs); }
// for the replSetFreeze command // for the replSetFreeze command
bool freeze(int secs) { return _freeze(secs); } bool freeze(int secs) { return _freeze(secs); }
string selfFullName() { string selfFullName() {
verify( _self ); verify( _self );
skipping to change at line 607 skipping to change at line 610
*/ */
const ReplSetConfig& getConfig() { return config(); } const ReplSetConfig& getConfig() { return config(); }
bool lockedByMe() { return RSBase::lockedByMe(); } bool lockedByMe() { return RSBase::lockedByMe(); }
// heartbeat msg to send to others; descriptive diagnostic info // heartbeat msg to send to others; descriptive diagnostic info
string hbmsg() const { string hbmsg() const {
if( time(0)-_hbmsgTime > 120 ) return ""; if( time(0)-_hbmsgTime > 120 ) return "";
return _hbmsg; return _hbmsg;
} }
protected:
ReplSet();
}; };
/** /**
* Base class for repl set commands. Checks basic things such if we're in * Base class for repl set commands. Checks basic things such if we're in
* rs mode before the command does its real work. * rs mode before the command does its real work.
*/ */
class ReplSetCommand : public Command { class ReplSetCommand : public Command {
protected: protected:
ReplSetCommand(const char * s, bool show=false) : Command(s, show) { } ReplSetCommand(const char * s, bool show=false) : Command(s, show) { }
virtual bool slaveOk() const { return true; } virtual bool slaveOk() const { return true; }
 End of changes. 10 change blocks. 
13 lines changed or deleted 18 lines changed or added


 rs_config.h   rs_config.h 
skipping to change at line 39 skipping to change at line 39
class Member; class Member;
const string rsConfigNs = "local.system.replset"; const string rsConfigNs = "local.system.replset";
class ReplSetConfig { class ReplSetConfig {
enum { EMPTYCONFIG = -2 }; enum { EMPTYCONFIG = -2 };
struct TagSubgroup; struct TagSubgroup;
// Protects _groups. // Protects _groups.
static mongo::mutex groupMx; static mongo::mutex groupMx;
public: public:
ReplSetConfig();
/** /**
* This contacts the given host and tries to get a config from them . * This contacts the given host and tries to get a config from them .
* *
* This sends a test heartbeat to the host and, if all goes well an d the * This sends a test heartbeat to the host and, if all goes well an d the
* host has a more recent config, fetches the config and loads it ( see * host has a more recent config, fetches the config and loads it ( see
* from(). * from().
* *
* If it's contacting itself, it skips the heartbeat (for obvious * If it's contacting itself, it skips the heartbeat (for obvious
* reasons.) If something is misconfigured, throws an exception. If the * reasons.) If something is misconfigured, throws an exception. If the
* host couldn't be queried or is just blank, ok() will be false. * host couldn't be queried or is just blank, ok() will be false.
*/ */
ReplSetConfig(const HostAndPort& h); static ReplSetConfig* make(const HostAndPort& h);
static ReplSetConfig* make(BSONObj cfg, bool force=false);
ReplSetConfig(BSONObj cfg, bool force=false); /**
* This uses DBDirectClient to check itself for a config. This way
we don't need to connect
* to ourselves over the network to fetch our own config.
*/
static ReplSetConfig* makeDirect();
bool ok() const { return _ok; } bool ok() const { return _ok; }
struct TagRule; struct TagRule;
struct MemberCfg { struct MemberCfg {
MemberCfg() : _id(-1), votes(1), priority(1.0), arbiterOnly(fal se), slaveDelay(0), hidden(false), buildIndexes(true) { } MemberCfg() : _id(-1), votes(1), priority(1.0), arbiterOnly(fal se), slaveDelay(0), hidden(false), buildIndexes(true) { }
int _id; /* ordinal */ int _id; /* ordinal */
unsigned votes; /* how many votes this node gets. default 1. */ unsigned votes; /* how many votes this node gets. default 1. */
HostAndPort h; HostAndPort h;
skipping to change at line 159 skipping to change at line 164
* servers is safe if 4 of the servers are arbiters). * servers is safe if 4 of the servers are arbiters).
*/ */
private: private:
void setMajority(); void setMajority();
public: public:
int getMajority() const; int getMajority() const;
bool _constructed; bool _constructed;
/** /**
* Returns if replication chaining is allowed. * Get the timeout to use for heartbeats.
*/ */
bool chainingAllowed() const; int getHeartbeatTimeout() const;
private:
bool _ok;
/** /**
* If replication can be chained. If chaining is disallowed, it can * Default timeout: 10 seconds
still be explicitly
* enabled via the replSetSyncFrom command, but it will not happen
automatically.
*/ */
bool _chainingAllowed; static const int DEFAULT_HB_TIMEOUT;
private:
ReplSetConfig();
void init(const HostAndPort& h);
void init(BSONObj cfg, bool force);
bool _ok;
int _majority; int _majority;
void from(BSONObj); void from(BSONObj);
void clear(); void clear();
struct TagClause; struct TagClause;
/** /**
* The timeout to use for heartbeats
*/
int _heartbeatTimeout;
/**
* This is a logical grouping of servers. It is pointed to by a se t of * This is a logical grouping of servers. It is pointed to by a se t of
* servers with a certain tag. * servers with a certain tag.
* *
* For example, suppose servers A, B, and C have the tag "dc" : "ny c". If we * For example, suppose servers A, B, and C have the tag "dc" : "ny c". If we
* have a rule {"dc" : 2}, then we want A _or_ B _or_ C to have the * have a rule {"dc" : 2}, then we want A _or_ B _or_ C to have the
* write for one of the "dc" critiria to be fulfilled, so all three will * write for one of the "dc" critiria to be fulfilled, so all three will
* point to this subgroup. When one of their oplog-tailing cursors is * point to this subgroup. When one of their oplog-tailing cursors is
* updated, this subgroup is updated. * updated, this subgroup is updated.
*/ */
struct TagSubgroup : boost::noncopyable { struct TagSubgroup : boost::noncopyable {
~TagSubgroup(); // never called; not defined ~TagSubgroup(); // never called; not defined
TagSubgroup(string nm) : name(nm) { } TagSubgroup(const std::string& nm) : name(nm) { }
const string name; const string name;
OpTime last; OpTime last;
vector<TagClause*> clauses; vector<TagClause*> clauses;
// this probably won't actually point to valid members after th e // this probably won't actually point to valid members after th e
// subgroup is created, as initFromConfig() makes a copy of the // subgroup is created, as initFromConfig() makes a copy of the
// config // config
set<MemberCfg*> m; set<MemberCfg*> m;
void updateLast(const OpTime& op); void updateLast(const OpTime& op);
 End of changes. 9 change blocks. 
14 lines changed or deleted 26 lines changed or added


 rs_exception.h   rs_exception.h 
// @file rs_exception.h // @file rs_exception.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
namespace mongo { namespace mongo {
class VoteException : public std::exception { class VoteException : public std::exception {
public: public:
const char * what() const throw () { return "VoteException"; } const char * what() const throw () { return "VoteException"; }
}; };
class RetryAfterSleepException : public std::exception { class RetryAfterSleepException : public std::exception {
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 rs_member.h   rs_member.h 
skipping to change at line 74 skipping to change at line 74
bool operator==(const MemberState& r) const { return s == r.s; } bool operator==(const MemberState& r) const { return s == r.s; }
bool operator!=(const MemberState& r) const { return s != r.s; } bool operator!=(const MemberState& r) const { return s != r.s; }
}; };
/* this is supposed to be just basic information on a member, /* this is supposed to be just basic information on a member,
and copy constructable. */ and copy constructable. */
class HeartbeatInfo { class HeartbeatInfo {
unsigned _id; unsigned _id;
public: public:
HeartbeatInfo() : _id(0xffffffff), hbstate(MemberState::RS_UNKNOWN) , health(-1.0), HeartbeatInfo() : _id(0xffffffff), hbstate(MemberState::RS_UNKNOWN) , health(-1.0),
downSince(0), skew(INT_MIN), authIssue(false), ping(0) { } downSince(0), lastHeartbeatRecv(0), skew(INT_MIN), authIssue(fa lse), ping(0) { }
HeartbeatInfo(unsigned id); HeartbeatInfo(unsigned id);
unsigned id() const { return _id; } unsigned id() const { return _id; }
MemberState hbstate; MemberState hbstate;
double health; double health;
time_t upSince; time_t upSince;
long long downSince; long long downSince;
// This is the last time we got a response from a heartbeat request to a given member.
time_t lastHeartbeat; time_t lastHeartbeat;
// This is the last time we got a heartbeat request from a given me
mber.
time_t lastHeartbeatRecv;
DiagStr lastHeartbeatMsg; DiagStr lastHeartbeatMsg;
OpTime opTime; OpTime opTime;
int skew; int skew;
bool authIssue; bool authIssue;
unsigned int ping; // milliseconds unsigned int ping; // milliseconds
static unsigned int numPings; static unsigned int numPings;
bool up() const { return health > 0; } bool up() const { return health > 0; }
/** health is set to -1 on startup. that means we haven't even che cked yet. 0 means we checked and it failed. */ /** health is set to -1 on startup. that means we haven't even che cked yet. 0 means we checked and it failed. */
bool maybeUp() const { return health != 0; } bool maybeUp() const { return health != 0; }
long long timeDown() const; // ms long long timeDown() const; // ms
/* true if changed in a way of interest to the repl set manager. */ /* true if changed in a way of interest to the repl set manager. */
bool changed(const HeartbeatInfo& old) const; bool changed(const HeartbeatInfo& old) const;
void recvHeartbeat();
}; };
inline HeartbeatInfo::HeartbeatInfo(unsigned id) : inline HeartbeatInfo::HeartbeatInfo(unsigned id) :
_id(id), _id(id),
lastHeartbeatRecv(0),
authIssue(false), authIssue(false),
ping(0) { ping(0) {
hbstate = MemberState::RS_UNKNOWN; hbstate = MemberState::RS_UNKNOWN;
health = -1.0; health = -1.0;
downSince = 0; downSince = 0;
lastHeartbeat = upSince = 0; lastHeartbeat = upSince = 0;
skew = INT_MIN; skew = INT_MIN;
} }
inline bool HeartbeatInfo::changed(const HeartbeatInfo& old) const { inline bool HeartbeatInfo::changed(const HeartbeatInfo& old) const {
 End of changes. 5 change blocks. 
1 lines changed or deleted 8 lines changed or added


 rs_sync.h   rs_sync.h 
skipping to change at line 48 skipping to change at line 48
public: public:
SyncTail(BackgroundSyncInterface *q); SyncTail(BackgroundSyncInterface *q);
virtual ~SyncTail(); virtual ~SyncTail();
virtual bool syncApply(const BSONObj &o, bool convertUpdateToUpsert = false); virtual bool syncApply(const BSONObj &o, bool convertUpdateToUpsert = false);
/** /**
* Apply ops from applyGTEObj's ts to at least minValidObj's ts. N ote that, due to * Apply ops from applyGTEObj's ts to at least minValidObj's ts. N ote that, due to
* batching, this may end up applying ops beyond minValidObj's ts. * batching, this may end up applying ops beyond minValidObj's ts.
* *
* @param applyGTEObj the op to start replicating at. This is actu ally not used except in * @param applyGTEObj the op to start replicating at. This is actu ally not used except in
* comparision to minValidObj: the background sy nc thread keeps its own * comparison to minValidObj: the background syn c thread keeps its own
* record of where we're synced to and starts pr oviding ops from that * record of where we're synced to and starts pr oviding ops from that
* point. * point.
* @param minValidObj the op to finish syncing at. This function c annot return (other than * @param minValidObj the op to finish syncing at. This function c annot return (other than
* fatally erroring out) without applying at lea st this op. * fatally erroring out) without applying at lea st this op.
* @param func whether this should use initial sync logic (r ecloning docs) or * @param func whether this should use initial sync logic (r ecloning docs) or
* "normal" logic. * "normal" logic.
* @return BSONObj the op that was synced to. This may be great er than minValidObj, as a * @return BSONObj the op that was synced to. This may be great er than minValidObj, as a
* single batch might blow right by minvalid. If applyGTEObj is the same * single batch might blow right by minvalid. If applyGTEObj is the same
* op as minValidObj, this will be applyGTEObj. * op as minValidObj, this will be applyGTEObj.
*/ */
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 rwlock.h   rwlock.h 
skipping to change at line 166 skipping to change at line 166
class RWLockRecursive : protected RWLockBase { class RWLockRecursive : protected RWLockBase {
protected: protected:
ThreadLocalValue<int> _state; ThreadLocalValue<int> _state;
void lock(); // not implemented - Lock() should be used; didn't ove rload this name to avoid mistakes void lock(); // not implemented - Lock() should be used; didn't ove rload this name to avoid mistakes
virtual void Lock() { RWLockBase::lock(); } virtual void Lock() { RWLockBase::lock(); }
public: public:
virtual ~RWLockRecursive() { } virtual ~RWLockRecursive() { }
const char * const _name; const char * const _name;
RWLockRecursive(const char *name) : _name(name) { } RWLockRecursive(const char *name) : _name(name) { }
void assertAtLeastReadLocked() {
verify( _state.get() != 0 );
}
void assertExclusivelyLocked() { void assertExclusivelyLocked() {
verify( _state.get() < 0 ); verify( _state.get() < 0 );
} }
class Exclusive : boost::noncopyable { class Exclusive : boost::noncopyable {
RWLockRecursive& _r; RWLockRecursive& _r;
public: public:
Exclusive(RWLockRecursive& r) : _r(r) { Exclusive(RWLockRecursive& r) : _r(r) {
int s = _r._state.get(); int s = _r._state.get();
dassert( s <= 0 ); dassert( s <= 0 );
 End of changes. 1 change blocks. 
0 lines changed or deleted 3 lines changed or added


 rwlockimpl.h   rwlockimpl.h 
// @file rwlockimpl.h // @file rwlockimpl.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "mutex.h" #include "mutex.h"
#if defined(RWLOCK_TEST) #if defined(RWLOCK_TEST)
namespace mongo { namespace mongo {
typedef RWLockBase1 RWLockBase; typedef RWLockBase1 RWLockBase;
} }
#elif defined(MONGO_USE_SRW_ON_WINDOWS) && defined(_WIN32) #elif defined(MONGO_USE_SRW_ON_WINDOWS) && defined(_WIN32)
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 security.h   security.h 
skipping to change at line 47 skipping to change at line 47
public: public:
void startRequest(); // need to call at the beginning of each reque st void startRequest(); // need to call at the beginning of each reque st
void setIsALocalHostConnectionWithSpecialAuthPowers(); // called, i f localhost, when conneciton established. void setIsALocalHostConnectionWithSpecialAuthPowers(); // called, i f localhost, when conneciton established.
AuthenticationInfo() { AuthenticationInfo() {
_isLocalHost = false; _isLocalHost = false;
_isLocalHostAndLocalHostIsAuthorizedForAll = false; _isLocalHostAndLocalHostIsAuthorizedForAll = false;
_usingTempAuth = false; _usingTempAuth = false;
} }
~AuthenticationInfo() {} ~AuthenticationInfo() {}
bool isLocalHost() const { return _isLocalHost; } // why are you ca lling this? makes no sense to be externalized bool isLocalHost() const { return _isLocalHost; } // why are you ca lling this? makes no sense to be externalized
bool isSpecialLocalhostAdmin() const;
// -- modifiers ---- // -- modifiers ----
void logout(const std::string& dbname ) { void logout(const std::string& dbname ) {
scoped_spinlock lk(_lock); scoped_spinlock lk(_lock);
_authTable.removeAuth( dbname ); _authTable.removeAuth( dbname );
} }
void authorize(const std::string& dbname , const std::string& user ) { void authorize(const std::string& dbname , const std::string& user ) {
scoped_spinlock lk(_lock); scoped_spinlock lk(_lock);
_authTable.addAuth( dbname, user, Auth::WRITE ); _authTable.addAuth( dbname, user, Auth::WRITE );
 End of changes. 1 change blocks. 
1 lines changed or deleted 0 lines changed or added


 server.h   server.h 
/** @file server.h //server.h
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
This file contains includes commonly needed in the server files (mongod , mongos, test). It is *NOT* included in the C++ client; i.e. This file contains includes commonly needed in the server files (mongod , mongos, test). It is *NOT* included in the C++ client; i.e.
this is a very good place for global-ish things that you don't need to be in the client lib. this is a very good place for global-ish things that you don't need to be in the client lib.
Over time we should move more here, and more out of pch.h. And get rid of pch.h at some point. Over time we should move more here, and more out of pch.h. And get rid of pch.h at some point.
*/ */
#pragma once #pragma once
#if !defined(MONGO_EXPOSE_MACROS) #if !defined(MONGO_EXPOSE_MACROS)
# error this file is for mongo server programs not client lib # error this file is for mongo server programs not client lib
 End of changes. 2 change blocks. 
1 lines changed or deleted 20 lines changed or added


 shard.h   shard.h 
skipping to change at line 102 skipping to change at line 102
string toString() const { string toString() const {
return _name + ":" + _addr; return _name + ":" + _addr;
} }
friend ostream& operator << (ostream& out, const Shard& s) { friend ostream& operator << (ostream& out, const Shard& s) {
return (out << s.toString()); return (out << s.toString());
} }
bool operator==( const Shard& s ) const { bool operator==( const Shard& s ) const {
if ( _name != s._name ) bool n = _name == s._name;
return false; bool a = _addr == s._addr;
return _cs.sameLogicalEndpoint( s._cs );
verify( n == a ); // names and address are 1 to 1
return n;
} }
bool operator!=( const Shard& s ) const { bool operator!=( const Shard& s ) const {
return ! ( *this == s ); bool n = _name == s._name;
bool a = _addr == s._addr;
return ! ( n && a );
} }
bool operator==( const string& s ) const { bool operator==( const string& s ) const {
return _name == s || _addr == s; return _name == s || _addr == s;
} }
bool operator!=( const string& s ) const { bool operator!=( const string& s ) const {
return _name != s && _addr != s; return _name != s && _addr != s;
} }
skipping to change at line 270 skipping to change at line 274
ChunkManagerPtr getManager() const { ChunkManagerPtr getManager() const {
return _manager; return _manager;
} }
bool setVersion() { bool setVersion() {
_finishInit(); _finishInit();
return _setVersion; return _setVersion;
} }
static void sync( const string& db ); static void sync();
void donotCheckVersion() { void donotCheckVersion() {
_setVersion = false; _setVersion = false;
_finishedInit = true; _finishedInit = true;
} }
bool ok() const { return _conn > 0; } bool ok() const { return _conn > 0; }
/** /**
this just passes through excpet it checks for stale configs this just passes through excpet it checks for stale configs
*/ */
bool runCommand( const string& db , const BSONObj& cmd , BSONObj& r es ); bool runCommand( const string& db , const BSONObj& cmd , BSONObj& r es );
/** checks all of my thread local connections for the version of th is ns */ /** checks all of my thread local connections for the version of th is ns */
static void checkMyConnectionVersions( const string & ns ); static void checkMyConnectionVersions( const string & ns );
/**
* Whether or not we should release all connections after an operat
ion with
* a response.
*/
static bool releaseConnectionsAfterResponse;
/**
* Returns all the current sharded connections to the pool.
* Note: This is *dangerous* if we have GLE state.
*/
static void releaseMyConnections();
private: private:
void _init(); void _init();
void _finishInit(); void _finishInit();
bool _finishedInit; bool _finishedInit;
string _addr; string _addr;
string _ns; string _ns;
ChunkManagerPtr _manager; ChunkManagerPtr _manager;
skipping to change at line 323 skipping to change at line 315
extern DBConnectionPool shardConnectionPool; extern DBConnectionPool shardConnectionPool;
class ShardingConnectionHook : public DBConnectionHook { class ShardingConnectionHook : public DBConnectionHook {
public: public:
ShardingConnectionHook( bool shardedConnections ) ShardingConnectionHook( bool shardedConnections )
: _shardedConnections( shardedConnections ) { : _shardedConnections( shardedConnections ) {
} }
virtual void onCreate( DBClientBase * conn ); virtual void onCreate( DBClientBase * conn );
virtual void onHandedOut( DBClientBase * conn );
virtual void onDestroy( DBClientBase * conn ); virtual void onDestroy( DBClientBase * conn );
bool _shardedConnections; bool _shardedConnections;
}; };
} }
 End of changes. 5 change blocks. 
18 lines changed or deleted 10 lines changed or added


 shard_version.h   shard_version.h 
skipping to change at line 24 skipping to change at line 24
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
namespace mongo { namespace mongo {
/* /*
* Install chunk shard vesion callbaks in shardconnection code. This ac tivates * Install chunk shard version callbacks in shardconnection code. This activates
* the chunk shard version control that mongos needs. * the chunk shard version control that mongos needs.
* *
* MUST be called before accepting any connections. * MUST be called before accepting any connections.
*/ */
void installChunkShardVersioning(); void installChunkShardVersioning();
} // namespace mongo } // namespace mongo
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 shardkey.h   shardkey.h 
skipping to change at line 21 skipping to change at line 21
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include "mongo/db/keypattern.h"
namespace mongo { namespace mongo {
class Chunk; class Chunk;
class FieldRangeSet;
/* A ShardKeyPattern is a pattern indicating what data to extract from the object to make the shard key from. /* A ShardKeyPattern is a pattern indicating what data to extract from the object to make the shard key from.
Analogous to an index key pattern. Analogous to an index key pattern.
*/ */
class ShardKeyPattern { class ShardKeyPattern {
public: public:
ShardKeyPattern( BSONObj p = BSONObj() ); ShardKeyPattern( BSONObj p = BSONObj() );
/** /**
global min is the lowest possible value for this key global min is the lowest possible value for this key
skipping to change at line 55 skipping to change at line 58
} }
bool isGlobalMax( const BSONObj& k ) const { bool isGlobalMax( const BSONObj& k ) const {
return k.woCompare( globalMax() ) == 0; return k.woCompare( globalMax() ) == 0;
} }
bool isGlobal( const BSONObj& k ) const { bool isGlobal( const BSONObj& k ) const {
return isGlobalMin( k ) || isGlobalMax( k ); return isGlobalMin( k ) || isGlobalMax( k );
} }
/** compare shard keys from the objects specified
l < r negative
l == r 0
l > r positive
*/
int compare( const BSONObj& l , const BSONObj& r ) const;
/** /**
@return whether or not obj has all fields in this shard key patt ern @return whether or not obj has all fields in this shard key patt ern
e.g. e.g.
ShardKey({num:1}).hasShardKey({ name:"joe", num:3 }) is true ShardKey({num:1}).hasShardKey({ name:"joe", num:3 }) is true
ShardKey({"a.b":1}).hasShardKey({ "a.b":"joe"}) is true ShardKey({"a.b":1}).hasShardKey({ "a.b":"joe"}) is true
ShardKey({"a.b":1}).hasShardKey({ "a": {"b":"joe"}}) is true ShardKey({"a.b":1}).hasShardKey({ "a": {"b":"joe"}}) is true
ShardKey({num:1}).hasShardKey({ name:"joe"}) is false ShardKey({num:1}).hasShardKey({ name:"joe"}) is false
ShardKey({num:1}).hasShardKey({ name:"joe", num:{$gt:3} }) is false ShardKey({num:1}).hasShardKey({ name:"joe", num:{$gt:3} }) is false
see unit test for more examples see unit test for more examples
*/ */
bool hasShardKey( const BSONObj& obj ) const; bool hasShardKey( const BSONObj& obj ) const;
BSONObj key() const { return pattern; } BSONObj key() const { return pattern.toBSON(); }
string toString() const; string toString() const;
BSONObj extractKey(const BSONObj& from) const; BSONObj extractKey(const BSONObj& from) const;
bool partOfShardKey(const char* key ) const { bool partOfShardKey(const char* key ) const {
return pattern.hasField(key); return pattern.hasField(key);
} }
bool partOfShardKey(const string& key ) const { bool partOfShardKey(const string& key ) const {
return pattern.hasField(key.c_str()); return pattern.hasField(key.c_str());
} }
/** /**
* @return * @return
* true if 'this' is a prefix (not necessarily contained) of 'other Pattern'. * true if 'this' is a prefix (not necessarily contained) of 'other Pattern'.
*/ */
bool isPrefixOf( const BSONObj& otherPattern ) const; bool isPrefixOf( const KeyPattern& otherPattern ) const;
/**
* @return
* true if this shard key is compatible with a unique index on 'uni
queIndexPattern'.
* Primarily this just checks whether 'this' is a prefix of 'u
niqueIndexPattern',
* However it does not need to be an exact syntactic prefix du
e to "hashed"
* indexes or mismatches in ascending/descending order. Also,
uniqueness of the
* _id field is guaranteed by the generation process (or by th
e user) so every
* index that begins with _id is unique index compatible with
any shard key.
* Examples:
* shard key {a : 1} is compatible with a unique index on {_
id : 1}
* shard key {a : 1} is compatible with a unique index on {a
: 1 , b : 1}
* shard key {a : 1} is compatible with a unique index on {a
: -1 , b : 1 }
* shard key {a : "hashed"} is compatible with a unique inde
x on {a : 1}
* shard key {a : 1} is not compatible with a unique index o
n {b : 1}
* shard key {a : "hashed" , b : 1 } is not compatible with
unique index on { b : 1 }
* Note:
* this method assumes that 'uniqueIndexPattern' is a valid
index pattern,
* and is capable of being a unique index. A pattern like {
k : "hashed" }
* is never capable of being a unique index, and thus is an
invalid setting
* for the 'uniqueIndexPattern' argument.
*/
bool isUniqueIndexCompatible( const KeyPattern& uniqueIndexPattern
) const;
/**
* @return
* true if keyPattern contains any computed values, (e.g. {a : "has
hed"})
* false if keyPattern consists of only ascending/descending fields
(e.g. {a : 1, b : -1})
* With our current index expression language, "special" shar
d keys are any keys
* that are not a simple list of field names and 1/-1 values.
*/
bool isSpecial() const { return pattern.isSpecial(); }
/** /**
* @return BSONObj with _id and shardkey at front. May return origi nal object. * @return BSONObj with _id and shardkey at front. May return origi nal object.
*/ */
BSONObj moveToFront(const BSONObj& obj) const; BSONObj moveToFront(const BSONObj& obj) const;
/**@param queryConstraints a FieldRangeSet formed from parsing a qu
ery
* @return an ordered list of bounds generated using this KeyPatter
n
* and the constraints from the FieldRangeSet
*
* The value of frsp->matchPossibleForSingleKeyFRS(fromQuery) shoul
d be true,
* otherwise this function could throw.
*
*/
BoundList keyBounds( const FieldRangeSet& queryConstraints ) const{
return pattern.keyBounds( queryConstraints );
}
private: private:
BSONObj pattern; KeyPattern pattern;
BSONObj gMin; BSONObj gMin;
BSONObj gMax; BSONObj gMax;
/* question: better to have patternfields precomputed or not? depe nds on if we use copy constructor often. */ /* question: better to have patternfields precomputed or not? depe nds on if we use copy constructor often. */
set<string> patternfields; set<string> patternfields;
}; };
inline BSONObj ShardKeyPattern::extractKey(const BSONObj& from) const { inline BSONObj ShardKeyPattern::extractKey(const BSONObj& from) const {
BSONObj k = from; BSONObj k = pattern.extractSingleKey( from );
bool needExtraction = false;
BSONObjIterator a(from);
BSONObjIterator b(pattern);
while (a.more() && b.more()){
if (strcmp(a.next().fieldName(), b.next().fieldName()) != 0){
needExtraction = true;
break;
}
}
if (needExtraction || a.more() != b.more())
k = from.extractFields(pattern);
uassert(13334, "Shard Key must be less than 512 bytes", k.objsize() < 512); uassert(13334, "Shard Key must be less than 512 bytes", k.objsize() < 512);
return k; return k;
} }
} }
 End of changes. 8 change blocks. 
25 lines changed or deleted 73 lines changed or added


 simplerwlock.h   simplerwlock.h 
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "mongo/bson/util/atomic_int.h" #include "mongo/bson/util/atomic_int.h"
namespace mongo { namespace mongo {
/** separated out as later the implementation of this may be different than RWLock, /** separated out as later the implementation of this may be different than RWLock,
depending on OS, as there is no upgrade etc. facility herein. depending on OS, as there is no upgrade etc. facility herein.
*/ */
class SimpleRWLock : boost::noncopyable { class SimpleRWLock : boost::noncopyable {
 End of changes. 1 change blocks. 
0 lines changed or deleted 18 lines changed or added


 sock.h   sock.h 
skipping to change at line 128 skipping to change at line 128
extern SockAddr unknownAddress; // ( "0.0.0.0", 0 ) extern SockAddr unknownAddress; // ( "0.0.0.0", 0 )
/** this is not cache and does a syscall */ /** this is not cache and does a syscall */
string getHostName(); string getHostName();
/** this is cached, so if changes during the process lifetime /** this is cached, so if changes during the process lifetime
* will be stale */ * will be stale */
string getHostNameCached(); string getHostNameCached();
string prettyHostName();
/** /**
* thrown by Socket and SockAddr * thrown by Socket and SockAddr
*/ */
class SocketException : public DBException { class SocketException : public DBException {
public: public:
const enum Type { CLOSED , RECV_ERROR , SEND_ERROR, RECV_TIMEOUT, S END_TIMEOUT, FAILED_STATE, CONNECT_ERROR } _type; const enum Type { CLOSED , RECV_ERROR , SEND_ERROR, RECV_TIMEOUT, S END_TIMEOUT, FAILED_STATE, CONNECT_ERROR } _type;
SocketException( Type t , string server , int code = 9001 , string extra="" ) SocketException( Type t , const std::string& server , int code = 90 01 , const std::string& extra="" )
: DBException( (string)"socket exception [" + _getStringType( t ) + "] for " + server, code ), : DBException( (string)"socket exception [" + _getStringType( t ) + "] for " + server, code ),
_type(t), _type(t),
_server(server), _server(server),
_extra(extra) _extra(extra)
{} {}
virtual ~SocketException() throw() {} virtual ~SocketException() throw() {}
bool shouldPrint() const { return _type != CLOSED; } bool shouldPrint() const { return _type != CLOSED; }
virtual string toString() const; virtual string toString() const;
virtual const std::string* server() const { return &_server; }
private: private:
// TODO: Allow exceptions better control over their messages // TODO: Allow exceptions better control over their messages
static string _getStringType( Type t ){ static string _getStringType( Type t ){
switch (t) { switch (t) {
case CLOSED: return "CLOSED"; case CLOSED: return "CLOSED";
case RECV_ERROR: return "RECV_ERROR"; case RECV_ERROR: return "RECV_ERROR";
case SEND_ERROR: return "SEND_ERROR"; case SEND_ERROR: return "SEND_ERROR";
case RECV_TIMEOUT: return "RECV_TIMEOUT"; case RECV_TIMEOUT: return "RECV_TIMEOUT";
case SEND_TIMEOUT: return "SEND_TIMEOUT"; case SEND_TIMEOUT: return "SEND_TIMEOUT";
skipping to change at line 207 skipping to change at line 209
Socket(int sock, const SockAddr& farEnd); Socket(int sock, const SockAddr& farEnd);
/** In some cases the timeout will actually be 2x this value - eg w e do a partial send, /** In some cases the timeout will actually be 2x this value - eg w e do a partial send,
then the timeout fires, then we try to send again, then the tim eout fires again with then the timeout fires, then we try to send again, then the tim eout fires again with
no data sent, then we detect that the other side is down. no data sent, then we detect that the other side is down.
Generally you don't want a timeout, you should be very prepared for errors if you set one. Generally you don't want a timeout, you should be very prepared for errors if you set one.
*/ */
Socket(double so_timeout = 0, int logLevel = 0 ); Socket(double so_timeout = 0, int logLevel = 0 );
~Socket(); ~Socket() {
close();
}
bool connect(SockAddr& farEnd); bool connect(SockAddr& farEnd);
void close(); void close();
void send( const char * data , int len, const char *context ); void send( const char * data , int len, const char *context );
void send( const vector< pair< char *, int > > &data, const char *c ontext ); void send( const vector< pair< char *, int > > &data, const char *c ontext );
// recv len or throw SocketException // recv len or throw SocketException
void recv( char * data , int len ); void recv( char * data , int len );
int unsafe_recv( char *buf, int max ); int unsafe_recv( char *buf, int max );
 End of changes. 4 change blocks. 
3 lines changed or deleted 7 lines changed or added


 stack_introspect.h   stack_introspect.h 
// stack_introspect.h // stack_introspect.h
/* Copyright 2010 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once #pragma once
namespace mongo { namespace mongo {
/** /**
* checks up call tree * checks up call tree
* if any method on top of me is a constructor, return true * if any method on top of me is a constructor, return true
* may do internal caching * may do internal caching
* probably slow, use with care * probably slow, use with care
* if not implemented for a platform, returns false * if not implemented for a platform, returns false
 End of changes. 1 change blocks. 
0 lines changed or deleted 16 lines changed or added


 str.h   str.h 
skipping to change at line 40 skipping to change at line 40
#include <string> #include <string>
#include <sstream> #include <sstream>
// this violates the README rules for mongoutils: // this violates the README rules for mongoutils:
#include "../../bson/util/builder.h" #include "../../bson/util/builder.h"
namespace mongoutils { namespace mongoutils {
namespace str { namespace str {
typedef std::string string;
/** the idea here is to make one liners easy. e.g.: /** the idea here is to make one liners easy. e.g.:
return str::stream() << 1 << ' ' << 2; return str::stream() << 1 << ' ' << 2;
since the following doesn't work: since the following doesn't work:
(stringstream() << 1).str(); (stringstream() << 1).str();
*/ */
class stream { class stream {
public: public:
skipping to change at line 70 skipping to change at line 68
inline bool startsWith(const char *str, const char *prefix) { inline bool startsWith(const char *str, const char *prefix) {
const char *s = str; const char *s = str;
const char *p = prefix; const char *p = prefix;
while( *p ) { while( *p ) {
if( *p != *s ) return false; if( *p != *s ) return false;
p++; s++; p++; s++;
} }
return true; return true;
} }
inline bool startsWith(string s, string p) { return startsWith(s.c_ inline bool startsWith(const std::string& s, const std::string& p)
str(), p.c_str()); } {
return startsWith(s.c_str(), p.c_str());
}
// while these are trivial today use in case we do different wide c har things later // while these are trivial today use in case we do different wide c har things later
inline bool startsWith(const char *p, char ch) { return *p == ch; } inline bool startsWith(const char *p, char ch) { return *p == ch; }
inline bool startsWith(string s, char ch) { return startsWith(s.c_s tr(), ch); } inline bool startsWith(const std::string& s, char ch) { return star tsWith(s.c_str(), ch); }
inline bool endsWith(string s, string p) { inline bool endsWith(const std::string& s, const std::string& p) {
int l = p.size(); int l = p.size();
int x = s.size(); int x = s.size();
if( x < l ) return false; if( x < l ) return false;
return strncmp(s.c_str()+x-l, p.c_str(), l) == 0; return strncmp(s.c_str()+x-l, p.c_str(), l) == 0;
} }
inline bool endsWith(const char *s, char p) { inline bool endsWith(const char *s, char p) {
size_t len = strlen(s); size_t len = strlen(s);
return len && s[len-1] == p; return len && s[len-1] == p;
} }
inline bool equals( const char * a , const char * b ) { return strc mp( a , b ) == 0; } inline bool equals( const char * a , const char * b ) { return strc mp( a , b ) == 0; }
/** find char x, and return rest of string thereafter, or "" if not found */ /** find char x, and return rest of string thereafter, or "" if not found */
inline const char * after(const char *s, char x) { inline const char * after(const char *s, char x) {
const char *p = strchr(s, x); const char *p = strchr(s, x);
return (p != 0) ? p+1 : ""; return (p != 0) ? p+1 : "";
} }
inline string after(const string& s, char x) { inline std::string after(const std::string& s, char x) {
const char *p = strchr(s.c_str(), x); const char *p = strchr(s.c_str(), x);
return (p != 0) ? string(p+1) : ""; return (p != 0) ? std::string(p+1) : "";
} }
/** find string x, and return rest of string thereafter, or "" if n ot found */ /** find string x, and return rest of string thereafter, or "" if n ot found */
inline const char * after(const char *s, const char *x) { inline const char * after(const char *s, const char *x) {
const char *p = strstr(s, x); const char *p = strstr(s, x);
return (p != 0) ? p+strlen(x) : ""; return (p != 0) ? p+strlen(x) : "";
} }
inline string after(string s, string x) { inline std::string after(const std::string& s, const std::string& x ) {
const char *p = strstr(s.c_str(), x.c_str()); const char *p = strstr(s.c_str(), x.c_str());
return (p != 0) ? string(p+x.size()) : ""; return (p != 0) ? std::string(p+x.size()) : "";
} }
/** @return true if s contains x /** @return true if s contains x
* These should not be used with strings containing NUL bytes * These should not be used with strings containing NUL bytes
*/ */
inline bool contains(string s, string x) { inline bool contains(const std::string& s, const std::string& x) {
return strstr(s.c_str(), x.c_str()) != 0; return strstr(s.c_str(), x.c_str()) != 0;
} }
inline bool contains(string s, char x) { inline bool contains(const std::string& s, char x) {
verify(x != '\0'); // this expects c-strings so don't use when looking for NUL bytes verify(x != '\0'); // this expects c-strings so don't use when looking for NUL bytes
return strchr(s.c_str(), x) != 0; return strchr(s.c_str(), x) != 0;
} }
/** @return everything before the character x, else entire string * / /** @return everything before the character x, else entire string * /
inline string before(const string& s, char x) { inline std::string before(const std::string& s, char x) {
const char *p = strchr(s.c_str(), x); const char *p = strchr(s.c_str(), x);
return (p != 0) ? s.substr(0, p-s.c_str()) : s; return (p != 0) ? s.substr(0, p-s.c_str()) : s;
} }
/** @return everything before the string x, else entire string */ /** @return everything before the string x, else entire string */
inline string before(const string& s, const string& x) { inline std::string before(const std::string& s, const std::string& x) {
const char *p = strstr(s.c_str(), x.c_str()); const char *p = strstr(s.c_str(), x.c_str());
return (p != 0) ? s.substr(0, p-s.c_str()) : s; return (p != 0) ? s.substr(0, p-s.c_str()) : s;
} }
/** check if if strings share a common starting prefix /** check if if strings share a common starting prefix
@return offset of divergence (or length if equal). 0=nothing i n common. */ @return offset of divergence (or length if equal). 0=nothing i n common. */
inline int shareCommonPrefix(const char *p, const char *q) { inline int shareCommonPrefix(const char *p, const char *q) {
int ofs = 0; int ofs = 0;
while( 1 ) { while( 1 ) {
if( *p == 0 || *q == 0 ) if( *p == 0 || *q == 0 )
break; break;
if( *p != *q ) if( *p != *q )
break; break;
p++; q++; ofs++; p++; q++; ofs++;
} }
return ofs; return ofs;
} }
inline int shareCommonPrefix(const string &a, const string &b) inline int shareCommonPrefix(const std::string &a, const std::strin g &b)
{ return shareCommonPrefix(a.c_str(), b.c_str()); } { return shareCommonPrefix(a.c_str(), b.c_str()); }
/** string to unsigned. zero if not a number. can end with non-num chars */ /** string to unsigned. zero if not a number. can end with non-num chars */
inline unsigned toUnsigned(const string& a) { inline unsigned toUnsigned(const std::string& a) {
unsigned x = 0; unsigned x = 0;
const char *p = a.c_str(); const char *p = a.c_str();
while( 1 ) { while( 1 ) {
if( !isdigit(*p) ) if( !isdigit(*p) )
break; break;
x = x * 10 + (*p - '0'); x = x * 10 + (*p - '0');
p++; p++;
} }
return x; return x;
} }
/** split a string on a specific char. We don't split N times, jus t once /** split a string on a specific char. We don't split N times, jus t once
on the first occurrence. If char not present entire string is in L on the first occurrence. If char not present entire string is in L
and R is empty. and R is empty.
@return true if char found @return true if char found
*/ */
inline bool splitOn(const string &s, char c, string& L, string& R) { inline bool splitOn(const std::string &s, char c, std::string& L, s td::string& R) {
const char *start = s.c_str(); const char *start = s.c_str();
const char *p = strchr(start, c); const char *p = strchr(start, c);
if( p == 0 ) { if( p == 0 ) {
L = s; R.clear(); L = s; R.clear();
return false; return false;
} }
L = string(start, p-start); L = std::string(start, p-start);
R = string(p+1); R = std::string(p+1);
return true; return true;
} }
/** split scanning reverse direction. Splits ONCE ONLY. */ /** split scanning reverse direction. Splits ONCE ONLY. */
inline bool rSplitOn(const string &s, char c, string& L, string& R) { inline bool rSplitOn(const std::string &s, char c, std::string& L, std::string& R) {
const char *start = s.c_str(); const char *start = s.c_str();
const char *p = strrchr(start, c); const char *p = strrchr(start, c);
if( p == 0 ) { if( p == 0 ) {
L = s; R.clear(); L = s; R.clear();
return false; return false;
} }
L = string(start, p-start); L = std::string(start, p-start);
R = string(p+1); R = std::string(p+1);
return true; return true;
} }
/** @return number of occurrences of c in s */ /** @return number of occurrences of c in s */
inline unsigned count( const string& s , char c ) { inline unsigned count( const std::string& s , char c ) {
unsigned n=0; unsigned n=0;
for ( unsigned i=0; i<s.size(); i++ ) for ( unsigned i=0; i<s.size(); i++ )
if ( s[i] == c ) if ( s[i] == c )
n++; n++;
return n; return n;
} }
/** trim leading spaces. spaces only, not tabs etc. */ /** trim leading spaces. spaces only, not tabs etc. */
inline string ltrim(const string& s) { inline std::string ltrim(const std::string& s) {
const char *p = s.c_str(); const char *p = s.c_str();
while( *p == ' ' ) p++; while( *p == ' ' ) p++;
return p; return p;
} }
/** remove trailing chars in place */ /** remove trailing chars in place */
inline void stripTrailing(string& s, const char *chars) { inline void stripTrailing(std::string& s, const char *chars) {
string::iterator i = s.end(); std::string::iterator i = s.end();
while( s.begin() != i ) { while( s.begin() != i ) {
i--; i--;
if( contains(chars, *i) ) { if( contains(chars, *i) ) {
s.erase(i); s.erase(i);
} }
} }
} }
} }
 End of changes. 21 change blocks. 
26 lines changed or deleted 26 lines changed or added


 stringutils.h   stringutils.h 
skipping to change at line 30 skipping to change at line 30
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/scoped_array.hpp> #include <boost/scoped_array.hpp>
namespace mongo { namespace mongo {
// see also mongoutils/str.h - perhaps move these there? // see also mongoutils/str.h - perhaps move these there?
// see also text.h // see also text.h
void splitStringDelim( const string& str , std::vector<std::string>* re s , char delim ); void splitStringDelim( const std::string& str , std::vector<std::string >* res , char delim );
void joinStringDelim( const std::vector<std::string>& strs , std::strin g* res , char delim ); void joinStringDelim( const std::vector<std::string>& strs , std::strin g* res , char delim );
inline std::string tolowerString( const std::string& input ) { inline std::string tolowerString( const std::string& input ) {
std::string::size_type sz = input.size(); std::string::size_type sz = input.size();
boost::scoped_array<char> line(new char[sz+1]); boost::scoped_array<char> line(new char[sz+1]);
char * copy = line.get(); char * copy = line.get();
for ( std::string::size_type i=0; i<sz; i++ ) { for ( std::string::size_type i=0; i<sz; i++ ) {
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 syncclusterconnection.h   syncclusterconnection.h 
skipping to change at line 53 skipping to change at line 53
using DBClientBase::query; using DBClientBase::query;
using DBClientBase::update; using DBClientBase::update;
using DBClientBase::remove; using DBClientBase::remove;
/** /**
* @param commaSeparated should be 3 hosts comma separated * @param commaSeparated should be 3 hosts comma separated
*/ */
SyncClusterConnection( const list<HostAndPort> &, double socketTime out = 0); SyncClusterConnection( const list<HostAndPort> &, double socketTime out = 0);
SyncClusterConnection( string commaSeparated, double socketTimeout = 0); SyncClusterConnection( string commaSeparated, double socketTimeout = 0);
SyncClusterConnection( string a , string b , string c, double socke SyncClusterConnection( const std::string& a,
tTimeout = 0 ); const std::string& b,
const std::string& c,
double socketTimeout = 0 );
~SyncClusterConnection(); ~SyncClusterConnection();
/** /**
* @return true if all servers are up and ready for writes * @return true if all servers are up and ready for writes
*/ */
bool prepare( string& errmsg ); bool prepare( string& errmsg );
/** /**
* runs fsync on all servers * runs fsync on all servers
*/ */
skipping to change at line 121 skipping to change at line 124
virtual bool lazySupported() const { return false; } virtual bool lazySupported() const { return false; }
private: private:
SyncClusterConnection( SyncClusterConnection& prev, double socketTi meout = 0 ); SyncClusterConnection( SyncClusterConnection& prev, double socketTi meout = 0 );
string _toString() const; string _toString() const;
bool _commandOnActive(const string &dbname, const BSONObj& cmd, BSO NObj &info, int options=0); bool _commandOnActive(const string &dbname, const BSONObj& cmd, BSO NObj &info, int options=0);
auto_ptr<DBClientCursor> _queryOnActive(const string &ns, Query que ry, int nToReturn, int nToSkip, auto_ptr<DBClientCursor> _queryOnActive(const string &ns, Query que ry, int nToReturn, int nToSkip,
const BSONObj *fieldsToRetu rn, int queryOptions, int batchSize ); const BSONObj *fieldsToRetu rn, int queryOptions, int batchSize );
int _lockType( const string& name ); int _lockType( const string& name );
void _checkLast(); void _checkLast();
void _connect( string host ); void _connect( const std::string& host );
string _address; string _address;
vector<string> _connAddresses; vector<string> _connAddresses;
vector<DBClientConnection*> _conns; vector<DBClientConnection*> _conns;
map<string,int> _lockTypes; map<string,int> _lockTypes;
mongo::mutex _mutex; mongo::mutex _mutex;
vector<BSONObj> _lastErrors; vector<BSONObj> _lastErrors;
double _socketTimeout; double _socketTimeout;
 End of changes. 2 change blocks. 
3 lines changed or deleted 5 lines changed or added


 text.h   text.h 
// text.h // text.h
/* /*
* Copyright 2010 10gen Inc. * Copyright 2010 10gen Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* Copyright 2009 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once #pragma once
#include <vector> #include <vector>
#include <string> #include <string>
namespace mongo { namespace mongo {
class StringSplitter { class StringSplitter {
public: public:
/** @param big the string to be split /** @param big the string to be split
skipping to change at line 61 skipping to change at line 47
/** get next split string fragment */ /** get next split string fragment */
std::string next(); std::string next();
void split( std::vector<std::string>& l ); void split( std::vector<std::string>& l );
std::vector<std::string> split(); std::vector<std::string> split();
static std::vector<std::string> split( const std::string& big , con st std::string& splitter ); static std::vector<std::string> split( const std::string& big , con st std::string& splitter );
static std::string join( std::vector<std::string>& l , const std::s tring& split ); static std::string join( const std::vector<std::string>& l , const std::string& split );
private: private:
const char * _big; const char * _big;
const char * _splitter; const char * _splitter;
}; };
/* This doesn't defend against ALL bad UTF8, but it will guarantee that the /* This doesn't defend against ALL bad UTF8, but it will guarantee that the
* string can be converted to sequence of codepoints. However, it doesn 't * string can be converted to sequence of codepoints. However, it doesn 't
* guarantee that the codepoints are valid. * guarantee that the codepoints are valid.
*/ */
bool isValidUTF8(const char *s); bool isValidUTF8(const char *s);
bool isValidUTF8(std::string s); bool isValidUTF8(const std::string& s);
// expect that n contains a base ten number and nothing else after it // expect that n contains a base ten number and nothing else after it
// NOTE win version hasn't been tested directly // NOTE win version hasn't been tested directly
long long parseLL( const char *n ); long long parseLL( const char *n );
#if defined(_WIN32) #if defined(_WIN32)
std::string toUtf8String(const std::wstring& wide); std::string toUtf8String(const std::wstring& wide);
std::wstring toWideString(const char *s); std::wstring toWideString(const char *s);
 End of changes. 4 change blocks. 
18 lines changed or deleted 3 lines changed or added


 top.h   top.h 
skipping to change at line 22 skipping to change at line 22
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli ed.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#pragma once #pragma once
#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp>
#include "mongo/platform/unordered_map.h"
namespace mongo { namespace mongo {
/** /**
* tracks usage by collection * tracks usage by collection
*/ */
class Top { class Top {
public: public:
Top() : _lock("Top") { } Top() : _lock("Top") { }
skipping to change at line 64 skipping to change at line 66
UsageData writeLock; UsageData writeLock;
UsageData queries; UsageData queries;
UsageData getmore; UsageData getmore;
UsageData insert; UsageData insert;
UsageData update; UsageData update;
UsageData remove; UsageData remove;
UsageData commands; UsageData commands;
}; };
typedef map<string,CollectionData> UsageMap; typedef unordered_map<string,CollectionData> UsageMap;
public: public:
void record( const StringData& ns , int op , int lockType , long lo ng micros , bool command ); void record( const StringData& ns , int op , int lockType , long lo ng micros , bool command );
void append( BSONObjBuilder& b ); void append( BSONObjBuilder& b );
void cloneMap(UsageMap& out) const; void cloneMap(UsageMap& out) const;
CollectionData getGlobalData() const { return _global; } CollectionData getGlobalData() const { return _global; }
void collectionDropped( const string& ns ); void collectionDropped( const string& ns );
public: // static stuff public: // static stuff
static Top global; static Top global;
 End of changes. 2 change blocks. 
1 lines changed or deleted 3 lines changed or added


 update_internal.h   update_internal.h 
skipping to change at line 33 skipping to change at line 33
#include "mongo/db/jsobjmanipulator.h" #include "mongo/db/jsobjmanipulator.h"
#include "mongo/db/matcher.h" #include "mongo/db/matcher.h"
#include "mongo/util/embedded_builder.h" #include "mongo/util/embedded_builder.h"
#include "mongo/util/stringutils.h" #include "mongo/util/stringutils.h"
namespace mongo { namespace mongo {
class ModState; class ModState;
class ModSetState; class ModSetState;
/**
* a.$ -> a
* @return true if out is set and we made a change
*/
bool getCanonicalIndexField( const string& fullName, string* out );
/* Used for modifiers such as $inc, $set, $push, ... /* Used for modifiers such as $inc, $set, $push, ...
* stores the info about a single operation * stores the info about a single operation
* once created should never be modified * once created should never be modified
*/ */
struct Mod { struct Mod {
// See opFromStr below // See opFromStr below
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13
enum Op { INC, SET, PUSH, PUSH_ALL, PULL, PULL_ALL , POP, UNSET, BI TAND, BITOR , BIT , ADDTOSET, RENAME_FROM, RENAME_TO } op; enum Op { INC, SET, PUSH, PUSH_ALL, PULL, PULL_ALL , POP, UNSET, BI TAND, BITOR , BIT , ADDTOSET, RENAME_FROM, RENAME_TO } op;
static const char* modNames[]; static const char* modNames[];
skipping to change at line 90 skipping to change at line 84
void setFieldName( const char* s ) { void setFieldName( const char* s ) {
fieldName = s; fieldName = s;
shortFieldName = strrchr( fieldName , '.' ); shortFieldName = strrchr( fieldName , '.' );
if ( shortFieldName ) if ( shortFieldName )
shortFieldName++; shortFieldName++;
else else
shortFieldName = fieldName; shortFieldName = fieldName;
} }
/** /**
* @param in incrememnts the actual value inside in * @param in increments the actual value inside in
*/ */
void incrementMe( BSONElement& in ) const { void incrementMe( BSONElement& in ) const {
BSONElementManipulator manip( in ); BSONElementManipulator manip( in );
switch ( in.type() ) { switch ( in.type() ) {
case NumberDouble: case NumberDouble:
manip.setNumber( elt.numberDouble() + in.numberDouble() ); manip.setNumber( elt.numberDouble() + in.numberDouble() );
break; break;
case NumberLong: case NumberLong:
manip.setLong( elt.numberLong() + in.numberLong() ); manip.setLong( elt.numberLong() + in.numberLong() );
break; break;
skipping to change at line 152 skipping to change at line 146
static bool isIndexed( const string& fullName , const set<string>& idxKeys ) { static bool isIndexed( const string& fullName , const set<string>& idxKeys ) {
const char * fieldName = fullName.c_str(); 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;
// 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; return false;
} }
/**
* checks if mod is in the index by inspecting fieldName, and remov
ing
* .$ or .### substrings (#=digit) with any number of digits.
*
* @return true iff the mod is indexed
*/
bool isIndexed( const set<string>& idxKeys ) const { bool isIndexed( const set<string>& idxKeys ) const {
string myFieldName = fieldName; string fullName = fieldName;
// first, check if full name is in idxKeys if ( isIndexed( fullName , idxKeys ) )
if ( isIndexed( myFieldName , idxKeys ) )
return true; return true;
string x; if ( strstr( fieldName , "." ) ) {
if ( getCanonicalIndexField( myFieldName, &x ) ) { // check for a.0.1
if ( isIndexed( x, idxKeys ) ) StringBuilder buf;
for ( size_t i=0; i<fullName.size(); i++ ) {
char c = fullName[i];
if ( c == '$' &&
i > 0 && fullName[i-1] == '.' &&
i+1<fullName.size() &&
fullName[i+1] == '.' ) {
i++;
continue;
}
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 true;
} }
return false; return false;
} }
void apply( BSONBuilderBase& b , BSONElement in , ModState& ms ) co nst; void apply( BSONBuilderBase& b , BSONElement in , ModState& ms ) co nst;
/** /**
* @return true iff toMatch should be removed from the array * @return true iff toMatch should be removed from the array
skipping to change at line 333 skipping to change at line 355
*/ */
void updateIsIndexed( const set<string>& idxKeys, const set<string> * backgroundKeys ); void updateIsIndexed( const set<string>& idxKeys, const set<string> * backgroundKeys );
// TODO: this is inefficient - should probably just handle when ite rating // TODO: this is inefficient - should probably just handle when ite rating
ModSet * fixDynamicArray( const string& elemMatchKey ) const; ModSet * fixDynamicArray( const string& elemMatchKey ) const;
bool hasDynamicArray() const { return _hasDynamicArray; } bool hasDynamicArray() const { return _hasDynamicArray; }
/** /**
* creates a ModSetState suitable for operation on obj * creates a ModSetState suitable for operation on obj
* doesn't change or modify this ModSet or any underying Mod * doesn't change or modify this ModSet or any underlying Mod
*/ */
auto_ptr<ModSetState> prepare( const BSONObj& obj ) const; auto_ptr<ModSetState> prepare( const BSONObj& obj ) const;
/** /**
* given a query pattern, builds an object suitable for an upsert * given a query pattern, builds an object suitable for an upsert
* will take the query spec and combine all $ operators * will take the query spec and combine all $ operators
*/ */
BSONObj createNewFromQuery( const BSONObj& query ); BSONObj createNewFromQuery( const BSONObj& query );
int isIndexed() const { return _isIndexed; } int isIndexed() const { return _isIndexed; }
skipping to change at line 437 skipping to change at line 459
return true; return true;
case Mod::BIT: case Mod::BIT:
case Mod::BITAND: case Mod::BITAND:
case Mod::BITOR: case Mod::BITOR:
return true; return true;
default: default:
return false; return false;
} }
} }
const char* getOpLogName() const;
void appendForOpLog( BSONObjBuilder& b ) const; void appendForOpLog( BSONObjBuilder& b ) const;
void apply( BSONBuilderBase& b , BSONElement in ) { void apply( BSONBuilderBase& b , BSONElement in ) {
m->apply( b , in , *this ); m->apply( b , in , *this );
} }
void appendIncValue( BSONBuilderBase& b , bool useFullName ) const { void appendIncValue( BSONBuilderBase& b , bool useFullName ) const {
const char* n = useFullName ? m->fieldName : m->shortFieldName; const char* n = useFullName ? m->fieldName : m->shortFieldName;
switch ( incType ) { switch ( incType ) {
skipping to change at line 618 skipping to change at line 639
// re-writing for oplog // re-writing for oplog
bool DEPRECATED_needOpLogRewrite() const { bool DEPRECATED_needOpLogRewrite() const {
for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ ) for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ )
if ( i->second->DEPRECATED_needOpLogRewrite() ) if ( i->second->DEPRECATED_needOpLogRewrite() )
return true; return true;
return false; return false;
} }
BSONObj getOpLogRewrite() const; BSONObj getOpLogRewrite() const {
BSONObjBuilder b;
for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m
ods.end(); i++ )
i->second->appendForOpLog( b );
return b.obj();
}
bool DEPRECATED_haveArrayDepMod() const { bool DEPRECATED_haveArrayDepMod() const {
for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ ) for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ )
if ( i->second->m->arrayDep() ) if ( i->second->m->arrayDep() )
return true; return true;
return false; return false;
} }
void DEPRECATED_appendSizeSpecForArrayDepMods( BSONObjBuilder& b ) const { void DEPRECATED_appendSizeSpecForArrayDepMods( BSONObjBuilder& b ) const {
for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ ) { for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ ) {
 End of changes. 10 change blocks. 
24 lines changed or deleted 50 lines changed or added


 version.h   version.h 
/**
* Copyright (C) 2012 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3
,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public Licen
se
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UTIL_VERSION_HEADER #ifndef UTIL_VERSION_HEADER
#define UTIL_VERSION_HEADER #define UTIL_VERSION_HEADER
#include <string> #include <string>
#include "mongo/bson/stringdata.h" #include "mongo/base/string_data.h"
namespace mongo { namespace mongo {
struct BSONArray; struct BSONArray;
// mongo version // mongo version
extern const char versionString[]; extern const char versionString[];
extern const BSONArray versionArray; extern const BSONArray versionArray;
std::string mongodVersion(); std::string mongodVersion();
int versionCmp(StringData rhs, StringData lhs); // like strcmp int versionCmp(StringData rhs, StringData lhs); // like strcmp
 End of changes. 2 change blocks. 
1 lines changed or deleted 19 lines changed or added


 windows_basic.h   windows_basic.h 
// windows_basic.h // windows_basic.h
/*
* Copyright 2010 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once #pragma once
#if defined(_WIN32) #if defined(_WIN32)
// for rand_s() usage: // for rand_s() usage:
# define _CRT_RAND_S # define _CRT_RAND_S
# ifndef NOMINMAX # ifndef NOMINMAX
# define NOMINMAX # define NOMINMAX
# endif # endif
// tell windows.h not to include a bunch of headers we don't need: // tell windows.h not to include a bunch of headers we don't need:
# define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
 End of changes. 1 change blocks. 
0 lines changed or deleted 17 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/