action_type.h   action_type.h 
skipping to change at line 51 skipping to change at line 51
std::string toString() const; std::string toString() const;
// Takes the string representation of a single action type and retu rns the corresponding // Takes the string representation of a single action type and retu rns the corresponding
// ActionType enum. // ActionType enum.
static Status parseActionFromString(const std::string& actionString , ActionType* result); static Status parseActionFromString(const std::string& actionString , ActionType* result);
// Takes an ActionType and returns the string representation // Takes an ActionType and returns the string representation
static std::string actionToString(const ActionType& action); static std::string actionToString(const ActionType& action);
static const ActionType addShard; static const ActionType addShard;
static const ActionType authCheck;
static const ActionType authenticate;
static const ActionType captrunc; static const ActionType captrunc;
static const ActionType clean; static const ActionType clean;
static const ActionType cleanupOrphaned;
static const ActionType clone; static const ActionType clone;
static const ActionType cloneCollectionLocalSource; static const ActionType cloneCollectionLocalSource;
static const ActionType cloneCollectionTarget; static const ActionType cloneCollectionTarget;
static const ActionType closeAllDatabases; static const ActionType closeAllDatabases;
static const ActionType collMod; static const ActionType collMod;
static const ActionType collStats; static const ActionType collStats;
static const ActionType compact; static const ActionType compact;
static const ActionType connPoolStats; static const ActionType connPoolStats;
static const ActionType connPoolSync; static const ActionType connPoolSync;
static const ActionType convertToCapped; static const ActionType convertToCapped;
skipping to change at line 96 skipping to change at line 99
static const ActionType indexRead; static const ActionType indexRead;
static const ActionType indexStats; static const ActionType indexStats;
static const ActionType inprog; static const ActionType inprog;
static const ActionType insert; static const ActionType insert;
static const ActionType killCursors; static const ActionType killCursors;
static const ActionType killop; static const ActionType killop;
static const ActionType listDatabases; static const ActionType listDatabases;
static const ActionType listShards; static const ActionType listShards;
static const ActionType logRotate; static const ActionType logRotate;
static const ActionType mapReduceShardedFinish; static const ActionType mapReduceShardedFinish;
static const ActionType mergeChunks;
static const ActionType moveChunk; static const ActionType moveChunk;
static const ActionType movePrimary; static const ActionType movePrimary;
static const ActionType netstat; static const ActionType netstat;
static const ActionType profileEnable; static const ActionType profileEnable;
static const ActionType profileRead; static const ActionType profileRead;
static const ActionType reIndex; static const ActionType reIndex;
static const ActionType remove; static const ActionType remove;
static const ActionType removeShard; static const ActionType removeShard;
static const ActionType renameCollectionSameDB; static const ActionType renameCollectionSameDB;
static const ActionType repairDatabase; static const ActionType repairDatabase;
skipping to change at line 117 skipping to change at line 121
static const ActionType replSetFreeze; static const ActionType replSetFreeze;
static const ActionType replSetFresh; static const ActionType replSetFresh;
static const ActionType replSetGetRBID; static const ActionType replSetGetRBID;
static const ActionType replSetGetStatus; static const ActionType replSetGetStatus;
static const ActionType replSetHeartbeat; static const ActionType replSetHeartbeat;
static const ActionType replSetInitiate; static const ActionType replSetInitiate;
static const ActionType replSetMaintenance; static const ActionType replSetMaintenance;
static const ActionType replSetReconfig; static const ActionType replSetReconfig;
static const ActionType replSetStepDown; static const ActionType replSetStepDown;
static const ActionType replSetSyncFrom; static const ActionType replSetSyncFrom;
static const ActionType replSetUpdatePosition;
static const ActionType resync; static const ActionType resync;
static const ActionType serverStatus; static const ActionType serverStatus;
static const ActionType setParameter; static const ActionType setParameter;
static const ActionType setShardVersion; static const ActionType setShardVersion;
static const ActionType shardCollection; static const ActionType shardCollection;
static const ActionType shardingState; static const ActionType shardingState;
static const ActionType shutdown; static const ActionType shutdown;
static const ActionType split; static const ActionType split;
static const ActionType splitChunk; static const ActionType splitChunk;
static const ActionType splitVector; static const ActionType splitVector;
static const ActionType storageDetails; static const ActionType storageDetails;
static const ActionType top; static const ActionType top;
static const ActionType touch; static const ActionType touch;
static const ActionType unlock; static const ActionType unlock;
static const ActionType unsetSharding; static const ActionType unsetSharding;
static const ActionType update; static const ActionType update;
static const ActionType userAdmin; static const ActionType userAdmin;
static const ActionType userAdminV1;
static const ActionType validate; static const ActionType validate;
static const ActionType writebacklisten; static const ActionType writebacklisten;
static const ActionType writeBacksQueued; static const ActionType writeBacksQueued;
static const ActionType _migrateClone; static const ActionType _migrateClone;
static const ActionType _recvChunkAbort; static const ActionType _recvChunkAbort;
static const ActionType _recvChunkCommit; static const ActionType _recvChunkCommit;
static const ActionType _recvChunkStart; static const ActionType _recvChunkStart;
static const ActionType _recvChunkStatus; static const ActionType _recvChunkStatus;
static const ActionType _transferMods; static const ActionType _transferMods;
enum ActionTypeIdentifier { enum ActionTypeIdentifier {
addShardValue, addShardValue,
authCheckValue,
authenticateValue,
captruncValue, captruncValue,
cleanValue, cleanValue,
cleanupOrphanedValue,
cloneValue, cloneValue,
cloneCollectionLocalSourceValue, cloneCollectionLocalSourceValue,
cloneCollectionTargetValue, cloneCollectionTargetValue,
closeAllDatabasesValue, closeAllDatabasesValue,
collModValue, collModValue,
collStatsValue, collStatsValue,
compactValue, compactValue,
connPoolStatsValue, connPoolStatsValue,
connPoolSyncValue, connPoolSyncValue,
convertToCappedValue, convertToCappedValue,
skipping to change at line 191 skipping to change at line 200
indexReadValue, indexReadValue,
indexStatsValue, indexStatsValue,
inprogValue, inprogValue,
insertValue, insertValue,
killCursorsValue, killCursorsValue,
killopValue, killopValue,
listDatabasesValue, listDatabasesValue,
listShardsValue, listShardsValue,
logRotateValue, logRotateValue,
mapReduceShardedFinishValue, mapReduceShardedFinishValue,
mergeChunksValue,
moveChunkValue, moveChunkValue,
movePrimaryValue, movePrimaryValue,
netstatValue, netstatValue,
profileEnableValue, profileEnableValue,
profileReadValue, profileReadValue,
reIndexValue, reIndexValue,
removeValue, removeValue,
removeShardValue, removeShardValue,
renameCollectionSameDBValue, renameCollectionSameDBValue,
repairDatabaseValue, repairDatabaseValue,
skipping to change at line 212 skipping to change at line 222
replSetFreezeValue, replSetFreezeValue,
replSetFreshValue, replSetFreshValue,
replSetGetRBIDValue, replSetGetRBIDValue,
replSetGetStatusValue, replSetGetStatusValue,
replSetHeartbeatValue, replSetHeartbeatValue,
replSetInitiateValue, replSetInitiateValue,
replSetMaintenanceValue, replSetMaintenanceValue,
replSetReconfigValue, replSetReconfigValue,
replSetStepDownValue, replSetStepDownValue,
replSetSyncFromValue, replSetSyncFromValue,
replSetUpdatePositionValue,
resyncValue, resyncValue,
serverStatusValue, serverStatusValue,
setParameterValue, setParameterValue,
setShardVersionValue, setShardVersionValue,
shardCollectionValue, shardCollectionValue,
shardingStateValue, shardingStateValue,
shutdownValue, shutdownValue,
splitValue, splitValue,
splitChunkValue, splitChunkValue,
splitVectorValue, splitVectorValue,
storageDetailsValue, storageDetailsValue,
topValue, topValue,
touchValue, touchValue,
unlockValue, unlockValue,
unsetShardingValue, unsetShardingValue,
updateValue, updateValue,
userAdminValue, userAdminValue,
userAdminV1Value,
validateValue, validateValue,
writebacklistenValue, writebacklistenValue,
writeBacksQueuedValue, writeBacksQueuedValue,
_migrateCloneValue, _migrateCloneValue,
_recvChunkAbortValue, _recvChunkAbortValue,
_recvChunkCommitValue, _recvChunkCommitValue,
_recvChunkStartValue, _recvChunkStartValue,
_recvChunkStatusValue, _recvChunkStatusValue,
_transferModsValue, _transferModsValue,
 End of changes. 10 change blocks. 
0 lines changed or deleted 12 lines changed or added


 admin_access.h   admin_access.h 
skipping to change at line 23 skipping to change at line 23
* 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/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/auth/user_name.h"
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
* privileges 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 privileged 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 UserName& 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; }
virtual BSONObj getAdminUser( const string& username ) const { retu rn BSONObj(); } virtual BSONObj getAdminUser(const UserName& username) const { retu rn BSONObj(); }
}; };
} // namespace mongo } // namespace mongo
 End of changes. 3 change blocks. 
2 lines changed or deleted 3 lines changed or added


 and_hash.h   and_hash.h 
skipping to change at line 24 skipping to change at line 24
* 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 <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <vector> #include <vector>
#include "mongo/db/diskloc.h" #include "mongo/db/diskloc.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/matcher.h"
#include "mongo/db/exec/plan_stage.h" #include "mongo/db/exec/plan_stage.h"
#include "mongo/db/matcher/expression.h"
#include "mongo/platform/unordered_set.h" #include "mongo/platform/unordered_set.h"
namespace mongo { namespace mongo {
/** /**
* Reads from N children, each of which must have a valid DiskLoc. Use s a hash table to * Reads from N children, each of which must have a valid DiskLoc. Use s a hash table to
* intersect the outputs of the N children, and outputs the intersectio n. * intersect the outputs of the N children, and outputs the intersectio n.
* *
* Preconditions: Valid DiskLoc. More than one child. * Preconditions: Valid DiskLoc. More than one child.
* *
* Any DiskLoc that we keep a reference to that is invalidated before w e are able to return it * Any DiskLoc that we keep a reference to that is invalidated before w e are able to return it
* is fetched and added to the WorkingSet as "flagged for further revie w." Because this stage * is fetched and added to the WorkingSet as "flagged for further revie w." Because this stage
* operates with DiskLocs, we are unable to evaluate the AND for the in validated DiskLoc, and it * operates with DiskLocs, we are unable to evaluate the AND for the in validated DiskLoc, and it
* must be fully matched later. * must be fully matched later.
*/ */
class AndHashStage : public PlanStage { class AndHashStage : public PlanStage {
public: public:
AndHashStage(WorkingSet* ws, Matcher* matcher); AndHashStage(WorkingSet* ws, const MatchExpression* filter);
virtual ~AndHashStage(); virtual ~AndHashStage();
void addChild(PlanStage* child); void addChild(PlanStage* child);
virtual StageState work(WorkingSetID* out); virtual StageState work(WorkingSetID* out);
virtual bool isEOF(); virtual bool isEOF();
virtual void prepareToYield(); virtual void prepareToYield();
virtual void recoverFromYield(); virtual void recoverFromYield();
virtual void invalidate(const DiskLoc& dl); virtual void invalidate(const DiskLoc& dl);
virtual PlanStageStats* getStats();
private: private:
StageState readFirstChild(); StageState readFirstChild();
StageState hashOtherChildren(); StageState hashOtherChildren();
// Not owned by us. // Not owned by us.
WorkingSet* _ws; WorkingSet* _ws;
scoped_ptr<Matcher> _matcher;
// Not owned by us.
const MatchExpression* _filter;
// The stages we read from. Owned by us. // The stages we read from. Owned by us.
vector<PlanStage*> _children; vector<PlanStage*> _children;
// _dataMap is filled out by the first child and probed by subseque nt children. // _dataMap is filled out by the first child and probed by subseque nt children.
typedef unordered_map<DiskLoc, WorkingSetID, DiskLoc::Hasher> DataM ap; typedef unordered_map<DiskLoc, WorkingSetID, DiskLoc::Hasher> DataM ap;
DataMap _dataMap; DataMap _dataMap;
// Keeps track of what elements from _dataMap subsequent children h ave seen. // Keeps track of what elements from _dataMap subsequent children h ave seen.
typedef unordered_set<DiskLoc, DiskLoc::Hasher> SeenMap; typedef unordered_set<DiskLoc, DiskLoc::Hasher> SeenMap;
SeenMap _seenMap; SeenMap _seenMap;
// Iterator over the members of _dataMap that survive. // Iterator over the members of _dataMap that survive.
DataMap::iterator _resultIterator; DataMap::iterator _resultIterator;
// True if we're still scanning _children for results. // True if we're still scanning _children for results.
bool _shouldScanChildren; bool _shouldScanChildren;
// Which child are we currently working on? // Which child are we currently working on?
size_t _currentChild; size_t _currentChild;
// Stats
CommonStats _commonStats;
AndHashStats _specificStats;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 6 change blocks. 
3 lines changed or deleted 11 lines changed or added


 and_sorted.h   and_sorted.h 
skipping to change at line 23 skipping to change at line 23
* 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 <queue> #include <queue>
#include <vector> #include <vector>
#include "mongo/db/diskloc.h" #include "mongo/db/diskloc.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/matcher.h"
#include "mongo/db/exec/plan_stage.h" #include "mongo/db/exec/plan_stage.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/matcher/expression.h"
#include "mongo/platform/unordered_set.h" #include "mongo/platform/unordered_set.h"
namespace mongo { namespace mongo {
/** /**
* Reads from N children, each of which must have a valid DiskLoc. Ass umes each child produces * Reads from N children, each of which must have a valid DiskLoc. Ass umes each child produces
* DiskLocs in sorted order. Outputs the intersection of the DiskLocs outputted by the * DiskLocs in sorted order. Outputs the intersection of the DiskLocs outputted by the
* children. * children.
* *
* Preconditions: Valid DiskLoc. More than one child. * Preconditions: Valid DiskLoc. More than one child.
* *
* Any DiskLoc that we keep a reference to that is invalidated before w e are able to return it * Any DiskLoc that we keep a reference to that is invalidated before w e are able to return it
* is fetched and added to the WorkingSet as "flagged for further revie w." Because this stage * is fetched and added to the WorkingSet as "flagged for further revie w." Because this stage
* operates with DiskLocs, we are unable to evaluate the AND for the in validated DiskLoc, and it * operates with DiskLocs, we are unable to evaluate the AND for the in validated DiskLoc, and it
* must be fully matched later. * must be fully matched later.
*/ */
class AndSortedStage : public PlanStage { class AndSortedStage : public PlanStage {
public: public:
AndSortedStage(WorkingSet* ws, Matcher* matcher); AndSortedStage(WorkingSet* ws, const MatchExpression* filter);
virtual ~AndSortedStage(); virtual ~AndSortedStage();
void addChild(PlanStage* child); void addChild(PlanStage* child);
virtual StageState work(WorkingSetID* out); virtual StageState work(WorkingSetID* out);
virtual bool isEOF(); virtual bool isEOF();
virtual void prepareToYield(); virtual void prepareToYield();
virtual void recoverFromYield(); virtual void recoverFromYield();
virtual void invalidate(const DiskLoc& dl); virtual void invalidate(const DiskLoc& dl);
virtual PlanStageStats* getStats();
private: private:
// Find a node to AND against. // Find a node to AND against.
PlanStage::StageState getTargetLoc(); PlanStage::StageState getTargetLoc();
// Move a child which hasn't advanced to the target node forward. // Move a child which hasn't advanced to the target node forward.
// Returns the target node in 'out' if all children successfully ad vance to it. // Returns the target node in 'out' if all children successfully ad vance to it.
PlanStage::StageState moveTowardTargetLoc(WorkingSetID* out); PlanStage::StageState moveTowardTargetLoc(WorkingSetID* out);
// Not owned by us. // Not owned by us.
WorkingSet* _ws; WorkingSet* _ws;
scoped_ptr<Matcher> _matcher;
// Not owned by us.
const MatchExpression* _filter;
// Owned by us. // Owned by us.
vector<PlanStage*> _children; vector<PlanStage*> _children;
// The current node we're AND-ing against. // The current node we're AND-ing against.
PlanStage* _targetNode; size_t _targetNode;
DiskLoc _targetLoc; DiskLoc _targetLoc;
WorkingSetID _targetId; WorkingSetID _targetId;
// Nodes we're moving forward until they hit the element we're AND- ing. // Nodes we're moving forward until they hit the element we're AND- ing.
// Everything in here has not advanced to _targetLoc yet. // Everything in here has not advanced to _targetLoc yet.
std::queue<PlanStage*> _workingTowardRep; // These are indices into _children.
std::queue<size_t> _workingTowardRep;
// If any child hits EOF or if we have any errors, we're EOF. // If any child hits EOF or if we have any errors, we're EOF.
bool _isEOF; bool _isEOF;
// Stats
CommonStats _commonStats;
AndSortedStats _specificStats;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 8 change blocks. 
6 lines changed or deleted 15 lines changed or added


 assert_util.h   assert_util.h 
skipping to change at line 203 skipping to change at line 203
return (e && *e != "") ? causedBy(*e) : ""; return (e && *e != "") ? causedBy(*e) : "";
} }
inline std::string causedBy( const Status& e ){ return causedBy( e.reas on() ); } inline std::string causedBy( const Status& e ){ return causedBy( e.reas on() ); }
/** aborts on condition failure */ /** aborts on condition failure */
inline void fassert(int msgid, bool testOK) {if (MONGO_unlikely(!testOK )) fassertFailed(msgid);} inline void fassert(int msgid, bool testOK) {if (MONGO_unlikely(!testOK )) fassertFailed(msgid);}
/* "user assert". if asserts, user did something wrong, not our code * / /* "user assert". if asserts, user did something wrong, not our code * /
#define MONGO_uassert(msgid, msg, expr) (void)( MONGO_likely(!!(expr)) || ( mongo::uasserted(msgid, msg), 0) ) #define MONGO_uassert(msgid, msg, expr) (void)( MONGO_likely(!!(expr)) || ( mongo::uasserted(msgid, msg), 0) )
#define MONGO_uassertStatusOK(expr) do { \ inline void uassertStatusOK(const Status& status) {
Status status = (expr); \ if (MONGO_unlikely(!status.isOK())) {
if (!status.isOK()) \ uasserted((status.location() != 0 ? status.location() : status.
uasserted(status.location() != 0 ? status.location() : status.c code()),
ode(), \ status.reason());
status.reason()); \ }
} while(0) }
/* warning only - keeps going */ /* warning only - keeps going */
#define MONGO_wassert(_Expression) (void)( MONGO_likely(!!(_Expression)) || (mongo::wasserted(#_Expression, __FILE__, __LINE__), 0) ) #define MONGO_wassert(_Expression) (void)( MONGO_likely(!!(_Expression)) || (mongo::wasserted(#_Expression, __FILE__, __LINE__), 0) )
/* display a message, no context, and throw assertionexception /* display a message, no context, and throw assertionexception
easy way to throw an exception and log something without our stack t race easy way to throw an exception and log something without our stack t race
display happening. display happening.
*/ */
#define MONGO_massert(msgid, msg, expr) (void)( MONGO_likely(!!(expr)) || ( mongo::msgasserted(msgid, msg), 0) ) #define MONGO_massert(msgid, msg, expr) (void)( MONGO_likely(!!(expr)) || ( mongo::msgasserted(msgid, msg), 0) )
skipping to change at line 245 skipping to change at line 245
# define MONGO_debug_and(x) debugCompare(true, (x)) # define MONGO_debug_and(x) debugCompare(true, (x))
#else #else
# define MONGO_debug_and(x) debugCompare(false, (x)) # define MONGO_debug_and(x) debugCompare(false, (x))
#endif #endif
#ifdef MONGO_EXPOSE_MACROS #ifdef MONGO_EXPOSE_MACROS
# define dcompare MONGO_debug_and # define dcompare MONGO_debug_and
# define dassert MONGO_dassert # define dassert MONGO_dassert
# define verify MONGO_verify # define verify MONGO_verify
# define uassert MONGO_uassert # define uassert MONGO_uassert
# define uassertStatusOK MONGO_uassertStatusOK
# define wassert MONGO_wassert # define wassert MONGO_wassert
# define massert MONGO_massert # define massert MONGO_massert
#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 };
 End of changes. 2 change blocks. 
8 lines changed or deleted 7 lines changed or added


 authentication_commands.h   authentication_commands.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 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 <string>
#include "mongo/base/status.h"
#include "mongo/db/auth/user_name.h"
#include "mongo/db/commands.h" #include "mongo/db/commands.h"
namespace mongo { namespace mongo {
class CmdAuthenticate : public Command { class CmdAuthenticate : public Command {
public: public:
static void disableCommand(); static void disableCommand();
virtual bool logTheOp() { virtual bool logTheOp() {
return false; return false;
} }
virtual bool slaveOk() const { virtual bool slaveOk() const {
return true; return true;
} }
virtual LockType locktype() const { return NONE; } virtual LockType locktype() const { return NONE; }
virtual void help(stringstream& ss) const { ss << "internal"; } virtual void help(stringstream& ss) const { ss << "internal"; }
virtual void addRequiredPrivileges(const std::string& dbname, virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj, const BSONObj& cmdObj,
std::vector<Privilege>* out) {} // No auth required std::vector<Privilege>* out) {} // No auth required
CmdAuthenticate() : Command("authenticate") {} CmdAuthenticate() : Command("authenticate") {}
bool run(const string& dbname , BSONObj& cmdObj, int options, strin bool run(const string& dbname,
g& errmsg, BSONObjBuilder& result, bool fromRepl); BSONObj& cmdObj,
int options,
string& errmsg,
BSONObjBuilder& result,
bool fromRepl);
private: private:
bool authenticateCR(const string& dbname, /**
BSONObj& cmdObj, * Completes the authentication of "user" using "mechanism" and par
string& errmsg, ameters from "cmdObj".
BSONObjBuilder& result); *
bool authenticateX509(const string& dbname, * Returns Status::OK() on success. All other statuses indicate fa
BSONObj& cmdObj, iled authentication. The
string& errmsg, * entire status returned here may always be used for logging. How
BSONObjBuilder& result); ever, if the code is
* AuthenticationFailed, the "reason" field of the return status ma
y contain information
* that should not be revealed to the connected client.
*
* Other than AuthenticationFailed, common returns are BadValue, in
dicating unsupported
* mechanism, and ProtocolError, indicating an error in the use of
the authentication
* protocol.
*/
Status _authenticate(const std::string& mechanism,
const UserName& user,
const BSONObj& cmdObj);
Status _authenticateCR(const UserName& user, const BSONObj& cmdObj)
;
Status _authenticateX509(const UserName& user, const BSONObj& cmdOb
j);
}; };
extern CmdAuthenticate cmdAuthenticate; extern CmdAuthenticate cmdAuthenticate;
} }
 End of changes. 3 change blocks. 
10 lines changed or deleted 35 lines changed or added


 authorization_manager.h   authorization_manager.h 
skipping to change at line 27 skipping to change at line 27
#pragma once #pragma once
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <string> #include <string>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h" #include "mongo/base/status.h"
#include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/authz_manager_external_state.h" #include "mongo/db/auth/authz_manager_external_state.h"
#include "mongo/db/auth/privilege_set.h"
#include "mongo/db/auth/user.h" #include "mongo/db/auth/user.h"
#include "mongo/db/auth/user_name.h" #include "mongo/db/auth/user_name.h"
#include "mongo/db/auth/user_name_hash.h" #include "mongo/db/auth/user_name_hash.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/platform/unordered_map.h" #include "mongo/platform/unordered_map.h"
namespace mongo { namespace mongo {
/** /**
* Internal secret key info. * Internal secret key info.
*/ */
struct AuthInfo { struct AuthInfo {
AuthInfo(); User* user;
std::string user;
std::string pwd;
BSONObj authParams; BSONObj authParams;
}; };
extern AuthInfo internalSecurity; // set at startup and not changed aft er initialization. extern AuthInfo internalSecurity; // set at startup and not changed aft er initialization.
/** /**
* Contains server/cluster-wide information about Authorization. * Contains server/cluster-wide information about Authorization.
*/ */
class AuthorizationManager { class AuthorizationManager {
MONGO_DISALLOW_COPYING(AuthorizationManager); MONGO_DISALLOW_COPYING(AuthorizationManager);
public: public:
// The newly constructed AuthorizationManager takes ownership of "e xternalState" // The newly constructed AuthorizationManager takes ownership of "e xternalState"
explicit AuthorizationManager(AuthzManagerExternalState* externalSt ate); explicit AuthorizationManager(AuthzManagerExternalState* externalSt ate);
~AuthorizationManager(); ~AuthorizationManager();
static const std::string SERVER_RESOURCE_NAME; static const std::string SERVER_RESOURCE_NAME;
static const std::string CLUSTER_RESOURCE_NAME; static const std::string CLUSTER_RESOURCE_NAME;
static const std::string WILDCARD_RESOURCE_NAME;
static const std::string USER_NAME_FIELD_NAME; static const std::string USER_NAME_FIELD_NAME;
static const std::string USER_SOURCE_FIELD_NAME; static const std::string USER_SOURCE_FIELD_NAME;
static const std::string PASSWORD_FIELD_NAME; static const std::string PASSWORD_FIELD_NAME;
// TODO: Make the following functions no longer static. // TODO: Make the following functions no longer static.
/** /**
* Sets whether or not we allow old style (pre v2.4) privilege docu ments for this whole * Sets whether or not we allow old style (pre v2.4) privilege docu ments for this whole
* server. * server.
skipping to change at line 108 skipping to change at line 106
// Returns true if there exists at least one privilege document in the given database. // Returns true if there exists at least one privilege document in the given database.
bool hasPrivilegeDocument(const std::string& dbname) const; bool hasPrivilegeDocument(const std::string& dbname) const;
// Creates the given user object in the given database. // Creates the given user object in the given database.
Status insertPrivilegeDocument(const std::string& dbname, const BSO NObj& userObj) const; Status insertPrivilegeDocument(const std::string& dbname, const BSO NObj& userObj) const;
// Updates the given user object with the given update modifier. // Updates the given user object with the given update modifier.
Status updatePrivilegeDocument(const UserName& user, const BSONObj& updateObj) const; Status updatePrivilegeDocument(const UserName& user, const BSONObj& updateObj) const;
// Removes users for the given database matching the given query.
Status removePrivilegeDocuments(const std::string& dbname, const BS
ONObj& query) const;
// Checks to see if "doc" is a valid privilege document, assuming i t is stored in the // Checks to see if "doc" is a valid privilege document, assuming i t is stored in the
// "system.users" collection of database "dbname". // "system.users" collection of database "dbname".
// //
// Returns Status::OK() if the document is good, or Status(ErrorCod es::BadValue), otherwise. // Returns Status::OK() if the document is good, or Status(ErrorCod es::BadValue), otherwise.
Status checkValidPrivilegeDocument(const StringData& dbname, const BSONObj& doc); Status checkValidPrivilegeDocument(const StringData& dbname, const BSONObj& doc);
// Parses the privilege document and returns a PrivilegeSet of all
the Privileges that
// the privilege document grants.
Status buildPrivilegeSet(const std::string& dbname,
const UserName& user,
const BSONObj& privilegeDocument,
PrivilegeSet* result) const;
// Given a database name and a readOnly flag return an ActionSet de scribing all the actions // Given a database name and a readOnly flag return an ActionSet de scribing all the actions
// that an old-style user with those attributes should be given. // that an old-style user with those attributes should be given.
ActionSet getActionsForOldStyleUser(const std::string& dbname, bool readOnly) const; ActionSet getActionsForOldStyleUser(const std::string& dbname, bool readOnly) const;
// Returns an ActionSet of all actions that can be be granted to us ers. This does not // Returns an ActionSet of all actions that can be be granted to us ers. This does not
// include internal-only actions. // include internal-only actions.
ActionSet getAllUserActions() const; ActionSet getAllUserActions() const;
/** /**
* Returns the User object for the given userName in the out param "acquiredUser". * Returns the User object for the given userName in the out param eter "acquiredUser".
* If the user cache already has a user object for this user, it i ncrements the refcount * If the user cache already has a user object for this user, it i ncrements the refcount
* on that object and gives out a pointer to it. If no user objec t for this user name * on that object and gives out a pointer to it. If no user objec t for this user name
* exists yet in the cache, reads the user's privilege document fr om disk, builds up * exists yet in the cache, reads the user's privilege document fr om disk, builds up
* a User object, sets the refcount to 1, and gives that out. * a User object, sets the refcount to 1, and gives that out. The
returned user may
* be invalid by the time the caller gets access to it.
* The AuthorizationManager retains ownership of the returned User object. * The AuthorizationManager retains ownership of the returned User object.
* On non-OK Status return values, acquiredUser will not be modifi ed. * On non-OK Status return values, acquiredUser will not be modifi ed.
*/ */
Status acquireUser(const UserName& userName, User** acquiredUser); Status acquireUser(const UserName& userName, User** acquiredUser);
/** /**
* Decrements the refcount of the given User object. If the refcou nt has gone to zero, * Decrements the refcount of the given User object. If the refcou nt has gone to zero,
* deletes the User. Caller must stop using its pointer to "user" after calling this. * deletes the User. Caller must stop using its pointer to "user" after calling this.
*/ */
void releaseUser(User* user); void releaseUser(User* user);
private: /**
* Marks the given user as invalid and removes it from the user cac
he.
*/
void invalidateUser(User* user);
// Parses the old-style (pre 2.4) privilege document and returns a /**
PrivilegeSet of all the * Inserts the given user directly into the _userCache. Used to ad
// Privileges that the privilege document grants. d the internalSecurity
Status _buildPrivilegeSetFromOldStylePrivilegeDocument( * user into the cache at process startup.
const std::string& dbname, */
const UserName& user, void addInternalUser(User* user);
const BSONObj& privilegeDocument,
PrivilegeSet* result) const ;
// Parses extended-form (2.4+) privilege documents and returns a Pr /**
ivilegeSet of all the * Initializes the user cache with User objects for every v0 and v1
// privileges that the document grants. user document in the
// * system, by reading the system.users collection of every database
// The document, "privilegeDocument", is assumed to describe privil . If this function
eges for "principal", and * returns a non-ok Status, the _userCache should be considered cor
// to come from database "dbname". rupt and must be
Status _buildPrivilegeSetFromExtendedPrivilegeDocument( * discarded. This function should be called once at startup (only
const std::string& dbname, if the system hasn't yet
const UserName& user, * been upgraded to V2 user data format) and never again after that
const BSONObj& privilegeDocument, .
PrivilegeSet* result) const; * TODO(spencer): This function will temporarily be called every ti
me user data is changed
* as part of the transition period to the new User data structures
. This should be changed
* once we have all the code necessary to upgrade to the V2 user da
ta format, as at that
* point we'll only be able to user V1 user data as read-only.
*/
Status initializeAllV1UserData();
/** /**
* Parses privDoc and initializes the user object with the informat ion extracted from the * Parses privDoc and initializes the user object with the informat ion extracted from the
* privilege document. * privilege document.
* This should never be called from outside the AuthorizationManage
r - the only reason it's
* public instead of private is so it can be unit tested.
*/ */
Status _initializeUserFromPrivilegeDocument(User* user, Status _initializeUserFromPrivilegeDocument(User* user,
const BSONObj& privDoc) const; const BSONObj& privDoc) const;
private:
/**
* Invalidates all User objects in the cache and removes them from
the cache.
* Should only be called when already holding _lock.
* TODO(spencer): This only exists because we're currently calling
initializeAllV1UserData
* every time user data is changed. Once we only call that once at
startup, this function
* should be removed.
*/
void _invalidateUserCache_inlock();
static bool _doesSupportOldStylePrivileges; static bool _doesSupportOldStylePrivileges;
// True if access control enforcement is enabled on this node (ie i t was started with // True if access control enforcement is enabled on this node (ie i t was started with
// --auth or --keyFile). // --auth or --keyFile).
// This is a config setting, set at startup and not changing after initialization. // This is a config setting, set at startup and not changing after initialization.
static bool _authEnabled; static bool _authEnabled;
// Integer that represents what format version the privilege docume nts in the system are. // Integer that represents what format version the privilege docume nts in the system are.
// The current version is 2. When upgrading to v2.6 or later from v2.4 or prior, the // The current version is 2. When upgrading to v2.6 or later from v2.4 or prior, the
// version is 1. After running the upgrade process to upgrade to t he new privilege document // version is 1. After running the upgrade process to upgrade to t he new privilege document
 End of changes. 12 change blocks. 
35 lines changed or deleted 58 lines changed or added


 authorization_session.h   authorization_session.h 
skipping to change at line 28 skipping to change at line 28
#include <string> #include <string>
#include <vector> #include <vector>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h" #include "mongo/base/status.h"
#include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h" #include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h" #include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authz_session_external_state.h" #include "mongo/db/auth/authz_session_external_state.h"
#include "mongo/db/auth/principal.h"
#include "mongo/db/auth/principal_set.h"
#include "mongo/db/auth/privilege.h" #include "mongo/db/auth/privilege.h"
#include "mongo/db/auth/privilege_set.h"
#include "mongo/db/auth/user_name.h" #include "mongo/db/auth/user_name.h"
#include "mongo/db/auth/user_set.h"
namespace mongo { namespace mongo {
/** /**
* Contains all the authorization logic for a single client connection. It contains a set of * Contains all the authorization logic for a single client connection. It contains a set of
* the principals which have been authenticated, as well as a set of pr ivileges that have been * the principals which have been authenticated, as well as a set of pr ivileges that have been
* granted by those principals to perform various actions. * granted by those principals to perform various actions.
* An AuthorizationSession object is present within every mongo::Client object, therefore there * An AuthorizationSession object is present within every mongo::Client object, therefore there
* is one per thread that corresponds to an incoming client connection. * is one per thread that corresponds to an incoming client connection.
*/ */
class AuthorizationSession { class AuthorizationSession {
MONGO_DISALLOW_COPYING(AuthorizationSession); MONGO_DISALLOW_COPYING(AuthorizationSession);
public: public:
// Takes ownership of the externalState. // Takes ownership of the externalState.
explicit AuthorizationSession(AuthzSessionExternalState* externalSt ate); explicit AuthorizationSession(AuthzSessionExternalState* externalSt ate);
~AuthorizationSession(); ~AuthorizationSession();
const AuthorizationManager& getAuthorizationManager() const; AuthorizationManager& getAuthorizationManager();
// Should be called at the beginning of every new request. This pe rforms the checks // Should be called at the beginning of every new request. This pe rforms the checks
// necessary to determine if localhost connections should be given full access. // necessary to determine if localhost connections should be given full access.
// TODO: try to eliminate the need for this call. // TODO: try to eliminate the need for this call.
void startRequest(); void startRequest();
// Adds "principal" to the authorization manager, and takes ownersh /**
ip of it. * Adds the User identified by "UserName" to the authorization sess
void addAuthorizedPrincipal(Principal* principal); ion, acquiring privileges
* for it in the process.
*/
Status addAndAuthorizeUser(const UserName& userName);
// Returns the authenticated principal with the given name. Return s NULL // Returns the authenticated user with the given name. Returns NUL L
// if no such user is found. // if no such user is found.
// Ownership of the returned Principal remains with _authenticatedP // The user remains in the _authenticatedUsers set for this Authori
rincipals zationSession,
Principal* lookupPrincipal(const UserName& name); // and ownership of the user stays with the AuthorizationManager
User* lookupUser(const UserName& name);
// Gets an iterator over the names of all authenticated principals // Gets an iterator over the names of all authenticated users store
stored in this manager. d in this manager.
PrincipalSet::NameIterator getAuthenticatedPrincipalNames(); UserSet::NameIterator getAuthenticatedUserNames();
// Removes any authenticated principals whose authorization credent ials came from the given // Removes any authenticated principals whose authorization credent ials came from the given
// database, and revokes any privileges that were granted via that principal. // database, and revokes any privileges that were granted via that principal.
void logoutDatabase(const std::string& dbname); void logoutDatabase(const std::string& dbname);
// Grant this connection the given privilege. // Adds the internalSecurity user to the set of authenticated users
Status acquirePrivilege(const Privilege& privilege, .
const UserName& authorizingUser);
// Adds a new principal with the given username and authorizes it w
ith full access.
// Used to grant internal threads full access. // Used to grant internal threads full access.
void grantInternalAuthorization(const UserName& userName); void grantInternalAuthorization();
// Checks if this connection has been authenticated as an internal user. // Checks if this connection has been authenticated as an internal user.
bool hasInternalAuthorization(); bool hasInternalAuthorization();
// Checks if this connection has the privileges required to perform the given action // Checks if this connection has the privileges required to perform the given action
// on the given resource. Contains all the authorization logic inc luding handling things // on the given resource. Contains all the authorization logic inc luding handling things
// like the localhost exception. Returns true if the action may pr oceed on the resource. // like the localhost exception. Returns true if the action may pr oceed on the resource.
// Note: this may acquire a database read lock (for automatic privi lege acquisition). // Note: this may acquire a database read lock (for automatic privi lege acquisition).
bool checkAuthorization(const std::string& resource, ActionType act ion); bool checkAuthorization(const std::string& resource, ActionType act ion);
// Same as above but takes an ActionSet instead of a single ActionT ype. Returns true if // Same as above but takes an ActionSet instead of a single ActionT ype. Returns true if
// all of the actions may proceed on the resource. // all of the actions may proceed on the resource.
bool checkAuthorization(const std::string& resource, ActionSet acti ons); bool checkAuthorization(const std::string& resource, ActionSet acti ons);
// Parses the privilege documents and acquires all privileges that
the privilege document
// grants
Status acquirePrivilegesFromPrivilegeDocument(const std::string& db
name,
const UserName& user,
const BSONObj& privil
egeDocument);
// Checks if this connection has the privileges necessary to perfor m the given query on the // Checks if this connection has the privileges necessary to perfor m the given query on the
// given namespace. // given namespace.
Status checkAuthForQuery(const std::string& ns, const BSONObj& quer y); Status checkAuthForQuery(const std::string& ns, const BSONObj& quer y);
// Checks if this connection has the privileges necessary to perfor m a getMore on the given // Checks if this connection has the privileges necessary to perfor m a getMore on the given
// cursor in the given namespace. // cursor in the given namespace.
Status checkAuthForGetMore(const std::string& ns, long long cursorI D); Status checkAuthForGetMore(const std::string& ns, long long cursorI D);
// Checks if this connection has the privileges necessary to perfor m the given update on the // Checks if this connection has the privileges necessary to perfor m the given update on the
// given namespace. // given namespace.
skipping to change at line 131 skipping to change at line 123
// namespace. // namespace.
Status checkAuthForDelete(const std::string& ns, const BSONObj& que ry); Status checkAuthForDelete(const std::string& ns, const BSONObj& que ry);
// Checks if this connection is authorized for the given Privilege. // Checks if this connection is authorized for the given Privilege.
Status checkAuthForPrivilege(const Privilege& privilege); Status checkAuthForPrivilege(const Privilege& privilege);
// Checks if this connection is authorized for all the given Privil eges. // Checks if this connection is authorized for all the given Privil eges.
Status checkAuthForPrivileges(const vector<Privilege>& privileges); Status checkAuthForPrivileges(const vector<Privilege>& privileges);
private: private:
// Finds the set of privileges attributed to "principal" in databas
e "dbname", // Checks if this connection is authorized for the given Privilege,
// and adds them to the set of acquired privileges. ignoring whether or not
void _acquirePrivilegesForPrincipalFromDatabase(const std::string& // we should even be doing authorization checks in general.
dbname, Status _checkAuthForPrivilegeHelper(const Privilege& privilege);
const UserName& use
r);
// Checks to see if the given privilege is allowed, performing impl
icit privilege
// acquisition if enabled and necessary to resolve the privilege.
Status _probeForPrivilege(const Privilege& privilege);
// Returns a new privilege that has replaced the actions needed to handle special casing // Returns a new privilege that has replaced the actions needed to handle special casing
// certain namespaces like system.users and system.profile. Note t hat the special handling // certain namespaces like system.users and system.profile. Note t hat the special handling
// of system.indexes takes place in checkAuthForInsert, not here. // of system.indexes takes place in checkAuthForInsert, not here.
Privilege _modifyPrivilegeForSpecialCases(const Privilege& privileg e); Privilege _modifyPrivilegeForSpecialCases(const Privilege& privileg e);
scoped_ptr<AuthzSessionExternalState> _externalState; scoped_ptr<AuthzSessionExternalState> _externalState;
// All the privileges that have been acquired by the authenticated // All Users who have been authenticated on this connection
principals. UserSet _authenticatedUsers;
PrivilegeSet _acquiredPrivileges;
// All principals who have been authenticated on this connection
PrincipalSet _authenticatedPrincipals;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 13 change blocks. 
47 lines changed or deleted 26 lines changed or added


 authz_manager_external_state.h   authz_manager_external_state.h 
skipping to change at line 20 skipping to change at line 20
* 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 <string> #include <string>
#include <vector>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h" #include "mongo/base/status.h"
#include "mongo/db/auth/user_name.h" #include "mongo/db/auth/user_name.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
namespace mongo { namespace mongo {
/** /**
* Public interface for a class that encapsulates all the information r elated to system * Public interface for a class that encapsulates all the information r elated to system
skipping to change at line 59 skipping to change at line 60
bool hasPrivilegeDocument(const std::string& dbname) const; bool hasPrivilegeDocument(const std::string& dbname) const;
// Creates the given user object in the given database. // Creates the given user object in the given database.
virtual Status insertPrivilegeDocument(const std::string& dbname, virtual Status insertPrivilegeDocument(const std::string& dbname,
const BSONObj& userObj) cons t = 0; const BSONObj& userObj) cons t = 0;
// Updates the given user object with the given update modifier. // Updates the given user object with the given update modifier.
virtual Status updatePrivilegeDocument(const UserName& user, virtual Status updatePrivilegeDocument(const UserName& user,
const BSONObj& updateObj) co nst = 0; const BSONObj& updateObj) co nst = 0;
// Removes users for the given database matching the given query.
virtual Status removePrivilegeDocuments(const std::string& dbname,
const BSONObj& query) const
= 0;
/**
* Puts into the *dbnames vector the name of every database in the
cluster.
*/
virtual Status getAllDatabaseNames(std::vector<std::string>* dbname
s) const = 0;
/**
* Puts into the *privDocs vector every privilege document from the
given database's
* system.users collection.
*/
virtual Status getAllV1PrivilegeDocsForDB(const std::string& dbname
,
std::vector<BSONObj>* pri
vDocs) const = 0;
protected: protected:
AuthzManagerExternalState(); // This class should never be instanti ated directly. AuthzManagerExternalState(); // This class should never be instanti ated directly.
// Queries the userNamespace with the given query and returns the p rivilegeDocument found // Queries the userNamespace with the given query and returns the p rivilegeDocument found
// in *result. Returns true if it finds a document matching the qu // in *result. Returns Status::OK if it finds a document matching
ery, or false if not. the query. If it doesn't
virtual bool _findUser(const std::string& usersNamespace, // find a document matching the query, returns a Status with code U
const BSONObj& query, serNotFound. Other
BSONObj* result) const = 0; // errors may return other Status codes.
virtual Status _findUser(const std::string& usersNamespace,
const BSONObj& query,
BSONObj* result) const = 0;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 3 change blocks. 
5 lines changed or deleted 31 lines changed or added


 authz_manager_external_state_d.h   authz_manager_external_state_d.h 
skipping to change at line 44 skipping to change at line 44
public: public:
AuthzManagerExternalStateMongod(); AuthzManagerExternalStateMongod();
virtual ~AuthzManagerExternalStateMongod(); virtual ~AuthzManagerExternalStateMongod();
virtual Status insertPrivilegeDocument(const std::string& dbname, virtual Status insertPrivilegeDocument(const std::string& dbname,
const BSONObj& userObj) cons t; const BSONObj& userObj) cons t;
virtual Status updatePrivilegeDocument(const UserName& user, virtual Status updatePrivilegeDocument(const UserName& user,
const BSONObj& updateObj) co nst; const BSONObj& updateObj) co nst;
virtual Status removePrivilegeDocuments(const std::string& dbname,
const BSONObj& query) const
;
virtual Status getAllDatabaseNames(std::vector<std::string>* dbname
s) const;
virtual Status getAllV1PrivilegeDocsForDB(const std::string& dbname
,
std::vector<BSONObj>* pri
vDocs) const;
protected: protected:
virtual bool _findUser(const string& usersNamespace, virtual Status _findUser(const string& usersNamespace,
const BSONObj& query, const BSONObj& query,
BSONObj* result) const; BSONObj* result) const;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
3 lines changed or deleted 15 lines changed or added


 authz_manager_external_state_mock.h   authz_manager_external_state_mock.h 
skipping to change at line 20 skipping to change at line 20
* 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 <string> #include <string>
#include <vector>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h" #include "mongo/base/status.h"
#include "mongo/db/auth/authz_manager_external_state.h" #include "mongo/db/auth/authz_manager_external_state.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/platform/unordered_map.h" #include "mongo/platform/unordered_map.h"
namespace mongo { namespace mongo {
/** /**
skipping to change at line 47 skipping to change at line 48
AuthzManagerExternalStateMock() {}; AuthzManagerExternalStateMock() {};
// no-op for the mock // no-op for the mock
virtual Status insertPrivilegeDocument(const std::string& dbname, virtual Status insertPrivilegeDocument(const std::string& dbname,
const BSONObj& userObj) cons t; const BSONObj& userObj) cons t;
// no-op for the mock // no-op for the mock
virtual Status updatePrivilegeDocument(const UserName& user, virtual Status updatePrivilegeDocument(const UserName& user,
const BSONObj& updateObj) co nst; const BSONObj& updateObj) co nst;
// no-op for the mock
virtual Status removePrivilegeDocuments(const std::string& dbname,
const BSONObj& query) const
;
// Non-const version that puts document into a vector that can be a ccessed later // Non-const version that puts document into a vector that can be a ccessed later
Status insertPrivilegeDocument(const std::string& dbname, const BSO NObj& userObj); Status insertPrivilegeDocument(const std::string& dbname, const BSO NObj& userObj);
void clearPrivilegeDocuments(); void clearPrivilegeDocuments();
virtual bool _findUser(const std::string& usersNamespace, virtual Status getAllDatabaseNames(std::vector<std::string>* dbname
const BSONObj& query, s) const;
BSONObj* result) const;
virtual Status getAllV1PrivilegeDocsForDB(const std::string& dbname
,
std::vector<BSONObj>* pri
vDocs) const;
virtual Status _findUser(const std::string& usersNamespace,
const BSONObj& query,
BSONObj* result) const;
private: private:
unordered_map<std::string, BSONObj> _userDocuments; // dbname to us er document unordered_map<std::string, std::vector<BSONObj> > _userDocuments; / / dbname to user docs
}; };
} // namespace mongo } // namespace mongo
 End of changes. 4 change blocks. 
4 lines changed or deleted 18 lines changed or added


 authz_manager_external_state_s.h   authz_manager_external_state_s.h 
skipping to change at line 44 skipping to change at line 44
public: public:
AuthzManagerExternalStateMongos(); AuthzManagerExternalStateMongos();
virtual ~AuthzManagerExternalStateMongos(); virtual ~AuthzManagerExternalStateMongos();
virtual Status insertPrivilegeDocument(const std::string& dbname, virtual Status insertPrivilegeDocument(const std::string& dbname,
const BSONObj& userObj) cons t; const BSONObj& userObj) cons t;
virtual Status updatePrivilegeDocument(const UserName& user, virtual Status updatePrivilegeDocument(const UserName& user,
const BSONObj& updateObj) co nst; const BSONObj& updateObj) co nst;
virtual Status removePrivilegeDocuments(const std::string& dbname,
const BSONObj& query) const
;
virtual Status getAllDatabaseNames(std::vector<std::string>* dbname
s) const;
virtual Status getAllV1PrivilegeDocsForDB(const std::string& dbname
,
std::vector<BSONObj>* pri
vDocs) const;
protected: protected:
virtual bool _findUser(const string& usersNamespace, virtual Status _findUser(const string& usersNamespace,
const BSONObj& query, const BSONObj& query,
BSONObj* result) const; BSONObj* result) const;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
3 lines changed or deleted 15 lines changed or added


 authz_session_external_state.h   authz_session_external_state.h 
skipping to change at line 43 skipping to change at line 43
* state not stored in AuthorizationSession. This is primarily to make AuthorizationSession * state not stored in AuthorizationSession. This is primarily to make AuthorizationSession
* easier to test as well as to allow different implementations in mong os and mongod. * easier to test as well as to allow different implementations in mong os and mongod.
*/ */
class AuthzSessionExternalState { class AuthzSessionExternalState {
MONGO_DISALLOW_COPYING(AuthzSessionExternalState); MONGO_DISALLOW_COPYING(AuthzSessionExternalState);
public: public:
virtual ~AuthzSessionExternalState(); virtual ~AuthzSessionExternalState();
const AuthorizationManager& getAuthorizationManager() const; AuthorizationManager& getAuthorizationManager();
// Returns true if this connection should be treated as if it has f ull access to do // Returns true if this connection should be treated as if it has f ull access to do
// anything, regardless of the current auth state. Currently the r easons why this could be // anything, regardless of the current auth state. Currently the r easons why this could be
// are that auth isn't enabled, the connection is from localhost an d there are no admin // are that auth isn't enabled, the connection is from localhost an d there are no admin
// users, or the connection is a "god" connection. // users, or the connection is a "god" connection.
// NOTE: _checkShouldAllowLocalhost MUST be called at least once be fore any call to // NOTE: _checkShouldAllowLocalhost MUST be called at least once be fore any call to
// shouldIgnoreAuthChecks or we could ignore auth checks incorrectl y. // shouldIgnoreAuthChecks or we could ignore auth checks incorrectl y.
virtual bool shouldIgnoreAuthChecks() const = 0; virtual bool shouldIgnoreAuthChecks() const = 0;
// Should be called at the beginning of every new request. This pe rforms the checks // Should be called at the beginning of every new request. This pe rforms the checks
// necessary to determine if localhost connections should be given full access. // necessary to determine if localhost connections should be given full access.
virtual void startRequest() = 0; virtual void startRequest() = 0;
// Authorization event hooks // Authorization event hooks
// Handle any global state which needs to be updated when a new use r has been authorized // Handle any global state which needs to be updated when a new use r has been authorized
virtual void onAddAuthorizedPrincipal(Principal*) = 0; virtual void onAddAuthorizedUser() = 0;
// Handle any global state which needs to be updated when a user lo gs out // Handle any global state which needs to be updated when a user lo gs out
virtual void onLogoutDatabase(const std::string& dbname) = 0; virtual void onLogoutDatabase(const std::string& dbname) = 0;
protected: protected:
// This class should never be instantiated directly. // This class should never be instantiated directly.
AuthzSessionExternalState(AuthorizationManager* authzManager); AuthzSessionExternalState(AuthorizationManager* authzManager);
AuthorizationManager* _authzManager; AuthorizationManager* _authzManager;
}; };
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 authz_session_external_state_d.h   authz_session_external_state_d.h 
skipping to change at line 40 skipping to change at line 40
MONGO_DISALLOW_COPYING(AuthzSessionExternalStateMongod); MONGO_DISALLOW_COPYING(AuthzSessionExternalStateMongod);
public: public:
AuthzSessionExternalStateMongod(AuthorizationManager* authzManager) ; AuthzSessionExternalStateMongod(AuthorizationManager* authzManager) ;
virtual ~AuthzSessionExternalStateMongod(); virtual ~AuthzSessionExternalStateMongod();
virtual bool shouldIgnoreAuthChecks() const; virtual bool shouldIgnoreAuthChecks() const;
virtual void startRequest(); virtual void startRequest();
virtual void onAddAuthorizedPrincipal(Principal*); virtual void onAddAuthorizedUser();
virtual void onLogoutDatabase(const std::string&); virtual void onLogoutDatabase(const std::string&);
}; };
} // namespace mongo } // namespace mongo
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 authz_session_external_state_mock.h   authz_session_external_state_mock.h 
skipping to change at line 44 skipping to change at line 44
AuthzSessionExternalState(authzManager), _returnValue(false) {} AuthzSessionExternalState(authzManager), _returnValue(false) {}
virtual bool shouldIgnoreAuthChecks() const { virtual bool shouldIgnoreAuthChecks() const {
return _returnValue; return _returnValue;
} }
void setReturnValueForShouldIgnoreAuthChecks(bool returnValue) { void setReturnValueForShouldIgnoreAuthChecks(bool returnValue) {
_returnValue = returnValue; _returnValue = returnValue;
} }
virtual bool _findUser(const std::string& usersNamespace, virtual Status _findUser(const std::string& usersNamespace,
const BSONObj& query, const BSONObj& query,
BSONObj* result) const { BSONObj* result) const {
return false; return Status(ErrorCodes::UserNotFound, "User not found");
} }
virtual void startRequest() {} virtual void startRequest() {}
virtual void onAddAuthorizedPrincipal(Principal*) {} virtual void onAddAuthorizedUser() {}
virtual void onLogoutDatabase(const std::string& dbname) {} virtual void onLogoutDatabase(const std::string& dbname) {}
private: private:
bool _returnValue; bool _returnValue;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
5 lines changed or deleted 5 lines changed or added


 authz_session_external_state_s.h   authz_session_external_state_s.h 
skipping to change at line 38 skipping to change at line 38
*/ */
class AuthzSessionExternalStateMongos : public AuthzSessionExternalStat eServerCommon { class AuthzSessionExternalStateMongos : public AuthzSessionExternalStat eServerCommon {
MONGO_DISALLOW_COPYING(AuthzSessionExternalStateMongos); MONGO_DISALLOW_COPYING(AuthzSessionExternalStateMongos);
public: public:
AuthzSessionExternalStateMongos(AuthorizationManager* authzManager) ; AuthzSessionExternalStateMongos(AuthorizationManager* authzManager) ;
virtual ~AuthzSessionExternalStateMongos(); virtual ~AuthzSessionExternalStateMongos();
virtual void startRequest(); virtual void startRequest();
virtual void onAddAuthorizedPrincipal(Principal*); virtual void onAddAuthorizedUser();
virtual void onLogoutDatabase(const std::string&); virtual void onLogoutDatabase(const std::string&);
}; };
} // namespace mongo } // namespace mongo
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 bgsync.h   bgsync.h 
skipping to change at line 88 skipping to change at line 88
const Member* _currentSyncTarget; const Member* _currentSyncTarget;
// Notifier thread // Notifier thread
// used to wait until another op has been replicated // used to wait until another op has been replicated
boost::condition_variable _lastOpCond; boost::condition_variable _lastOpCond;
boost::mutex _lastOpMutex; boost::mutex _lastOpMutex;
const Member* _oplogMarkerTarget; const Member* _oplogMarkerTarget;
OplogReader _oplogMarker; // not locked, only used by notifier thre ad
OpTime _consumedOpTime; // not locked, only used by notifier thread OpTime _consumedOpTime; // not locked, only used by notifier thread
BackgroundSync(); BackgroundSync();
BackgroundSync(const BackgroundSync& s); BackgroundSync(const BackgroundSync& s);
BackgroundSync operator=(const BackgroundSync& s); BackgroundSync operator=(const BackgroundSync& s);
// Production thread // Production thread
void _producerThread(); void _producerThread();
// Adds elements to the list, up to maxSize. // Adds elements to the list, up to maxSize.
void produce(); void produce();
skipping to change at line 116 skipping to change at line 115
// stop syncing when this becomes a primary // stop syncing when this becomes a primary
void stop(); void stop();
// restart syncing // restart syncing
void start(); void start();
// Tracker thread // Tracker thread
// tells the sync target where this member is synced to // tells the sync target where this member is synced to
void markOplog(); void markOplog();
bool hasCursor(); bool hasCursor();
// Sets _oplogMarkerTarget and calls connect();
// used for both the notifier command and the older OplogReader sty
le notifier
bool connectOplogNotifier();
bool isAssumingPrimary(); bool isAssumingPrimary();
public: public:
static BackgroundSync* get(); static BackgroundSync* get();
static void shutdown(); static void shutdown();
static void notify(); static void notify();
virtual ~BackgroundSync() {} virtual ~BackgroundSync() {}
// starts the producer thread // starts the producer thread
 End of changes. 2 change blocks. 
1 lines changed or deleted 5 lines changed or added


 bson_db.h   bson_db.h 
skipping to change at line 29 skipping to change at line 29
This file contains the implementation of BSON-related methods that are required This file contains the implementation of BSON-related methods that are required
by the MongoDB database server. by the MongoDB database server.
Normally, for standalone BSON usage, you do not want this file - it wil l tend to 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 pull in some other files from the MongoDB project. Thus, bson.h (the ma in file
one would use) does not include this file. one would use) does not include this file.
*/ */
#pragma once #pragma once
#include "mongo/db/repl/optime.h" #include "mongo/bson/optime.h"
#include "../util/time_support.h" #include "mongo/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.
@param time - in millis (but stored in seconds) @param time - in millis (but stored in seconds)
*/ */
inline BSONObjBuilder& BSONObjBuilder::appendTimestamp( const StringDat a& fieldName , unsigned long long time , unsigned int inc ) { inline BSONObjBuilder& BSONObjBuilder::appendTimestamp( const StringDat a& fieldName , unsigned long long time , unsigned int inc ) {
OpTime t( (unsigned) (time / 1000) , inc ); OpTime t( (unsigned) (time / 1000) , inc );
 End of changes. 1 change blocks. 
2 lines changed or deleted 2 lines changed or added


 bsonelement.h   bsonelement.h 
skipping to change at line 67 skipping to change at line 67
value() value()
type() type()
*/ */
class BSONElement { class BSONElement {
public: public:
/** These functions, which start with a capital letter, throw a Msg AssertionException if the /** These functions, which start with a capital letter, throw a Msg AssertionException if the
element is not of the required type. Example: element is not of the required type. Example:
std::string foo = obj["foo"].String(); // std::exception if not a std::string type or DNE std::string foo = obj["foo"].String(); // std::exception if not a std::string type or DNE
*/ */
std::string String() const { return chk(mongo::String).value str(); } std::string String() const { return chk(mongo::String).str() ; }
Date_t Date() const { return chk(mongo::Date).date(); } Date_t Date() const { return chk(mongo::Date).date(); }
double Number() const { return chk(isNumber()).number() ; } double Number() const { return chk(isNumber()).number() ; }
double Double() const { return chk(NumberDouble)._numbe rDouble(); } double Double() const { return chk(NumberDouble)._numbe rDouble(); }
long long Long() const { return chk(NumberLong)._numberL ong(); } long long Long() const { return chk(NumberLong)._numberL ong(); }
int Int() const { return chk(NumberInt)._numberIn t(); } int Int() const { return chk(NumberInt)._numberIn t(); }
bool Bool() const { return chk(mongo::Bool).boolean (); } bool Bool() const { return chk(mongo::Bool).boolean (); }
std::vector<BSONElement> Array() const; // see implementation for d etailed comments std::vector<BSONElement> Array() const; // see implementation for d etailed comments
mongo::OID OID() const { return chk(jstOID).__oid(); } mongo::OID OID() const { return chk(jstOID).__oid(); }
void Null() const { chk(isNull()); } // throw MsgAs sertionException if not null void Null() const { chk(isNull()); } // throw MsgAs sertionException if not null
void OK() const { chk(ok()); } // throw MsgAs sertionException if element DNE void OK() const { chk(ok()); } // throw MsgAs sertionException if element DNE
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 bsonobj.h   bsonobj.h 
skipping to change at line 276 skipping to change at line 276
/** @return the raw data of the object */ /** @return the raw data of the object */
const char *objdata() const { const char *objdata() const {
return _objdata; return _objdata;
} }
/** @return total size of the BSON object in bytes */ /** @return total size of the BSON object in bytes */
int objsize() const { return *(reinterpret_cast<const int*>(objdata ())); } int objsize() const { return *(reinterpret_cast<const int*>(objdata ())); }
/** performs a cursory check on the object's size only. */ /** performs a cursory check on the object's size only. */
bool isValid() const; bool isValid() const;
/** @return if the user is a valid user doc /** @return ok if it can be stored as a valid embedded doc.
criter: isValid() no . or $ field names * Not valid if any field name:
* - contains a "."
* - starts with "$"
* -- unless it is a dbref ($ref/$id/[$db]/...)
*/ */
bool okForStorage() const; inline bool okForStorage() const {
return _okForStorage(false);
}
/** Same as above with the following extra restrictions
* Not valid if:
* - "_id" field is a
* -- Regex
* -- Array
*/
inline bool okForStorageAsRoot() const {
return _okForStorage(true);
}
/** @return true if object is empty -- i.e., {} */ /** @return true if object is empty -- i.e., {} */
bool isEmpty() const { return objsize() <= 5; } bool isEmpty() const { return objsize() <= 5; }
void dump() const; void dump() const;
/** Alternative output format */ /** Alternative output format */
std::string hexDump() const; std::string hexDump() const;
/**wo='well ordered'. fields must be in same order in each object. /**wo='well ordered'. fields must be in same order in each object.
skipping to change at line 530 skipping to change at line 545
void init(Holder *holder) { void init(Holder *holder) {
_holder = holder; // holder is now managed by intrusive_ptr _holder = holder; // holder is now managed by intrusive_ptr
init(holder->data); init(holder->data);
} }
void init(const char *data) { void init(const char *data) {
_objdata = data; _objdata = data;
if ( !isValid() ) if ( !isValid() )
_assertInvalid(); _assertInvalid();
} }
bool _okForStorage(bool root) const;
}; };
std::ostream& operator<<( std::ostream &s, const BSONObj &o ); std::ostream& operator<<( std::ostream &s, const BSONObj &o );
std::ostream& operator<<( std::ostream &s, const BSONElement &e ); std::ostream& operator<<( std::ostream &s, const BSONElement &e );
StringBuilder& operator<<( StringBuilder &s, const BSONObj &o ); StringBuilder& operator<<( StringBuilder &s, const BSONObj &o );
StringBuilder& operator<<( StringBuilder &s, const BSONElement &e ); StringBuilder& operator<<( StringBuilder &s, const BSONElement &e );
struct BSONArray : BSONObj { struct BSONArray : BSONObj {
// Don't add anything other than forwarding constructors!!! // Don't add anything other than forwarding constructors!!!
 End of changes. 3 change blocks. 
3 lines changed or deleted 20 lines changed or added


 btree.h   btree.h 
skipping to change at line 194 skipping to change at line 194
// A sentinel value sometimes used to identify a deallocated bucket . // A sentinel value sometimes used to identify a deallocated bucket .
static const int INVALID_N_SENTINEL = -1; static const int INVALID_N_SENTINEL = -1;
}; };
// a a a ofs ofs ofs ofs // a a a ofs ofs ofs ofs
class DiskLoc56Bit { class DiskLoc56Bit {
int ofs; int ofs;
unsigned char _a[3]; unsigned char _a[3];
unsigned long long Z() const { unsigned long long Z() const {
// endian // endian
return *((unsigned long long*)this) & 0x00ffffffffffffffULL; unsigned long long result = ofs;
char* cursor = reinterpret_cast<char *>(&result);
*reinterpret_cast<uint16_t*>(cursor + 4) = *reinterpret_cast<co
nst uint16_t*>(&_a[0]);
*reinterpret_cast<uint8_t*>(cursor + 6) = *reinterpret_cast<con
st uint8_t*>(&_a[2]);
*reinterpret_cast<uint8_t*>(cursor + 7) = uint8_t(0);
return result;
} }
enum { enum {
// first bit of offsets used in _KeyNode we don't use -1 here. // first bit of offsets used in _KeyNode we don't use -1 here.
OurNullOfs = -2 OurNullOfs = -2
}; };
public: public:
template< class V > template< class V >
const BtreeBucket<V> * btree() const { const BtreeBucket<V> * btree() const {
return DiskLoc(*this).btree<V>(); return DiskLoc(*this).btree<V>();
} }
 End of changes. 1 change blocks. 
1 lines changed or deleted 8 lines changed or added


 btree_stats.h   btree_stats.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/db/commands/server_status.h" #include "mongo/db/commands/server_status.h"
#include "mongo/db/pdfile.h" #include "mongo/db/pdfile.h"
#include "mongo/db/record.h" #include "mongo/db/storage/record.h"
#include "mongo/util/processinfo.h" #include "mongo/util/processinfo.h"
namespace mongo { namespace mongo {
class IndexCounters : public ServerStatusSection { class IndexCounters : public ServerStatusSection {
public: public:
IndexCounters(); IndexCounters();
virtual ~IndexCounters(); virtual ~IndexCounters();
virtual bool includeByDefault() const { return true; } virtual bool includeByDefault() const { return true; }
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 btreebuilder.h   btreebuilder.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 "btree.h" #include "mongo/db/btree.h"
namespace mongo { namespace mongo {
/** /**
* build btree from the bottom up * build btree from the bottom up
*/ */
template< class V > template< class V >
class BtreeBuilder { class BtreeBuilder {
typedef typename V::KeyOwned KeyOwned; typedef typename V::KeyOwned KeyOwned;
typedef typename V::Key Key; typedef typename V::Key Key;
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 btreecursor.h   btreecursor.h 
// DEPRECATED
/** /**
* Copyright (C) 2008 10gen Inc. * Copyright (C) 2008 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
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 lines changed or added


 chunk_version.h   chunk_version.h 
skipping to change at line 271 skipping to change at line 271
bool* canParse ) bool* canParse )
{ {
*canParse = false; *canParse = false;
ChunkVersion version; ChunkVersion version;
BSONObjIterator it( arr ); BSONObjIterator it( arr );
if( ! it.more() ) return version; if( ! it.more() ) return version;
version = fromBSON( it.next(), "", canParse ); version = fromBSON( it.next(), "", canParse );
if( ! canParse ) return version; if( ! (*canParse) ) return version;
*canParse = true; *canParse = true;
if( ! it.more() ) return version; if( ! it.more() ) return version;
BSONElement next = it.next(); BSONElement next = it.next();
if( next.type() != jstOID ) return version; if( next.type() != jstOID ) return version;
version._epoch = next.OID(); version._epoch = next.OID();
return version; return version;
} }
enum VersionChoice {
VersionChoice_Local,
VersionChoice_Remote,
VersionChoice_Unknown
};
/**
* Compares a remotely-loaded version 'remoteVersion' to the latest
local version of a
* collection, 'localVersion', and returns the newest.
*
* Because it isn't clear during epoch changes which epoch is newer
, the local version
* before the reload occurred, 'prevLocalVersion', is used to deter
mine whether the remote
* epoch is definitely newer, or we're not sure.
*/
static VersionChoice chooseNewestVersion( ChunkVersion prevLocalVer
sion,
ChunkVersion localVersion
,
ChunkVersion remoteVersio
n )
{
OID prevEpoch = prevLocalVersion.epoch();
OID localEpoch = localVersion.epoch();
OID remoteEpoch = remoteVersion.epoch();
// Everything changed in-flight, so we need to try again
if ( prevEpoch != localEpoch && localEpoch != remoteEpoch ) {
return VersionChoice_Unknown;
}
// We're in the same (zero) epoch as the latest metadata, nothi
ng to do
if ( localEpoch == remoteEpoch && !remoteEpoch.isSet() ) {
return VersionChoice_Local;
}
// We're in the same (non-zero) epoch as the latest metadata, s
o increment the version
if ( localEpoch == remoteEpoch && remoteEpoch.isSet() ) {
// Use the newer version if possible
if ( localVersion < remoteVersion ) {
return VersionChoice_Remote;
}
else {
return VersionChoice_Local;
}
}
// We're now sure we're installing a new epoch and the epoch di
dn't change during reload
dassert( prevEpoch == localEpoch && localEpoch != remoteEpoch )
;
return VersionChoice_Remote;
}
// //
// Currently our BSON output is to two different fields, to cleanly work with older // Currently our BSON output is to two different fields, to cleanly work with older
// versions that know nothing about epochs. // versions that know nothing about epochs.
// //
BSONObj toBSON( const string& prefixIn="" ) const { BSONObj toBSON( const string& prefixIn="" ) const {
BSONObjBuilder b; BSONObjBuilder b;
string prefix = prefixIn; string prefix = prefixIn;
if( prefix == "" ) prefix = "version"; if( prefix == "" ) prefix = "version";
 End of changes. 2 change blocks. 
1 lines changed or deleted 60 lines changed or added


 clientcursor.h   clientcursor.h 
/* clientcursor.h */
/** /**
* Copyright (C) 2008 10gen Inc. * Copyright (C) 2008 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.
* *
* You should have received a copy of the GNU Affero General Public Licen * You should have received a copy of the GNU Affero General Public Lice
se 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/>.
*/ */
/* Cursor -- and its derived classes -- are our internal cursors.
ClientCursor is a wrapper that represents a cursorid from our database
application's perspective.
*/
#pragma once #pragma once
#include "mongo/pch.h" #include "mongo/pch.h"
#include <boost/thread/recursive_mutex.hpp> #include <boost/thread/recursive_mutex.hpp>
#include "cursor.h" #include "mongo/db/cc_by_loc.h"
#include "jsobj.h" #include "mongo/db/cursor.h"
#include "../util/net/message.h" #include "mongo/db/diskloc.h"
#include "../util/background.h" #include "mongo/db/dbhelpers.h"
#include "cc_by_loc.h" #include "mongo/db/jsobj.h"
#include "diskloc.h"
#include "dbhelpers.h"
#include "matcher.h"
#include "projection.h"
#include "mongo/db/keypattern.h" #include "mongo/db/keypattern.h"
#include "mongo/db/matcher.h"
#include "mongo/db/projection.h"
#include "mongo/db/query/runner.h"
#include "mongo/s/collection_metadata.h" #include "mongo/s/collection_metadata.h"
#include "mongo/util/net/message.h"
#include "mongo/util/background.h"
#include "mongo/util/elapsed_tracker.h" #include "mongo/util/elapsed_tracker.h"
namespace mongo { namespace mongo {
typedef boost::recursive_mutex::scoped_lock recursive_scoped_lock; typedef boost::recursive_mutex::scoped_lock recursive_scoped_lock;
class Cursor; /* internal server cursor base class */
class ClientCursor; class ClientCursor;
class ParsedQuery; class ParsedQuery;
/* todo: make this map be per connection. this will prevent cursor hij /**
acking security attacks perhaps. * ClientCursor is a wrapper that represents a cursorid from our databa
* ERH: 9/2010 this may not work since some drivers send getMore se application's
over a different connection * perspective.
*/ */
typedef map<CursorId, ClientCursor*> CCById;
extern BSONObj id_obj;
class ClientCursor : private boost::noncopyable { class ClientCursor : private boost::noncopyable {
friend class CmdCursorInfo;
public: public:
static void assertNoCursors(); ClientCursor(int qopts, const shared_ptr<Cursor>& c, const string&
ns,
BSONObj query = BSONObj());
/* use this to assure we don't in the background time out cursor wh ClientCursor(Runner* runner, int qopts = 0, const BSONObj query = B
ile it is under use. SONObj());
if you are using noTimeout() already, there is no risk anyway.
Further, this mechanism guards against two getMore requests on t
he same cursor executing
at the same time - which might be bad. That should never happen
, but if a client driver
had a bug, it could (or perhaps some sort of attack situation).
*/
class Pin : boost::noncopyable {
public:
Pin( long long cursorid ) :
_cursorid( INVALID_CURSOR_ID ) {
recursive_scoped_lock lock( ccmutex );
ClientCursor *cursor = ClientCursor::find_inlock( cursorid,
true );
if ( cursor ) {
uassert( 12051, "clientcursor already in use? driver pr
oblem?",
cursor->_pinValue < 100 );
cursor->_pinValue += 100;
_cursorid = cursorid;
}
}
void release() {
if ( _cursorid == INVALID_CURSOR_ID ) {
return;
}
ClientCursor *cursor = c();
_cursorid = INVALID_CURSOR_ID;
if ( cursor ) {
verify( cursor->_pinValue >= 100 );
cursor->_pinValue -= 100;
}
}
~Pin() { DESTRUCTOR_GUARD( release(); ) }
ClientCursor *c() const { return ClientCursor::find( _cursorid
); }
private:
CursorId _cursorid;
};
/** Assures safe and reliable cleanup of a ClientCursor. */ ~ClientCursor();
class Holder : boost::noncopyable {
public:
Holder( ClientCursor *c = 0 ) :
_c( 0 ),
_id( INVALID_CURSOR_ID ) {
reset( c );
}
void reset( ClientCursor *c = 0 ) {
if ( c == _c )
return;
if ( _c ) {
// be careful in case cursor was deleted by someone els
e
ClientCursor::erase( _id );
}
if ( c ) {
_c = c;
_id = c->_cursorid;
}
else {
_c = 0;
_id = INVALID_CURSOR_ID;
}
}
~Holder() {
DESTRUCTOR_GUARD ( reset(); );
}
ClientCursor* get() { return _c; }
operator bool() { return _c; }
ClientCursor * operator-> () { return _c; }
const ClientCursor * operator-> () const { return _c; }
/** Release ownership of the ClientCursor. */
void release() {
_c = 0;
_id = INVALID_CURSOR_ID;
}
private:
ClientCursor *_c;
CursorId _id;
};
/** /**
* Iterates through all ClientCursors, under its own ccmutex lock. * Assert that there are no open cursors.
* Also supports deletion on the fly. * Called from DatabaseHolder::closeAll.
*/ */
class LockedIterator : boost::noncopyable { static void assertNoCursors();
public:
LockedIterator() : _lock( ccmutex ), _i( clientCursorsById.begi
n() ) {}
bool ok() const { return _i != clientCursorsById.end(); }
ClientCursor *current() const { return _i->second; }
void advance() { ++_i; }
/**
* Delete 'current' and advance. Properly handles cascading del
etions that may occur
* when one ClientCursor is directly deleted.
*/
void deleteAndAdvance();
private:
recursive_scoped_lock _lock;
CCById::const_iterator _i;
};
ClientCursor(int queryOptions, const shared_ptr<Cursor>& c, const s
tring& ns, BSONObj query = BSONObj() );
~ClientCursor();
// *************** basic accessors ******************* //
// Basic accessors
//
CursorId cursorid() const { return _cursorid; } CursorId cursorid() const { return _cursorid; }
string ns() const { return _ns; } string ns() const { return _ns; }
Database * db() const { return _db; } Database * db() const { return _db; }
const BSONObj& query() const { return _query; }
int queryOptions() const { return _queryOptions; }
DiskLoc lastLoc() const { return _lastLoc; } //
// Invalidation of DiskLocs and dropping of namespaces
//
/* Get rid of cursors for namespaces 'ns'. When dropping a db, ns i /**
s "dbname." * Get rid of cursors for namespaces 'ns'. When dropping a db, ns i
Used by drop, dropIndexes, dropDatabase. s "dbname." Used by drop,
*/ * dropIndexes, dropDatabase.
*/
static void invalidate(const char *ns); static void invalidate(const char *ns);
/** /**
* Called when the provided DiskLoc is about to change state via a
deletion or an update.
* All runners/cursors that might be using that DiskLoc must adapt.
*/
static void aboutToDelete(const StringData& ns,
const NamespaceDetails* nsd,
const DiskLoc& dl);
/**
* Register a runner so that it can be notified of deletion/invalid
ation during yields.
* Must be called before a runner yields. If a runner is cached (i
nside a ClientCursor) it
* MUST NOT be registered; the two are mutually exclusive.
*/
static void registerRunner(Runner* runner);
/**
* Remove a runner from the runner registry.
*/
static void deregisterRunner(Runner* runner);
//
// Yielding.
//
static void staticYield(int micros, const StringData& ns, Record* r
ec);
//
// Static methods about all ClientCursors TODO: Document.
//
static void appendStats( BSONObjBuilder& result );
//
// ClientCursor creation/deletion.
//
static unsigned numCursors() { return clientCursorsById.size(); }
static void find( const string& ns , set<CursorId>& all );
static ClientCursor* find(CursorId id, bool warn = true);
// Same as erase but checks to make sure this thread has read permi
ssion on the cursor's
// namespace. This should be called when receiving killCursors fro
m a client. This should
// not be called when ccmutex is held.
static int eraseIfAuthorized(int n, long long* ids);
static bool eraseIfAuthorized(CursorId id);
/**
* @return number of cursors found
*/
static int erase(int n, long long* ids);
/**
* Deletes the cursor with the provided @param 'id' if one exists.
* @throw if the cursor with the provided id is pinned.
* This does not do any auth checking and should be used only when
erasing cursors as part
* of cleaning up internal operations.
*/
static bool erase(CursorId id);
//
// Timing and timeouts
//
/**
* called every 4 seconds. millis is amount of idle time passed si
nce the last call --
* could be zero
*/
static void idleTimeReport(unsigned millis);
/**
* @param millis amount of idle passed time since last call
* note called outside of locks (other than ccmutex) so care must b
e exercised
*/
bool shouldTimeout( unsigned millis );
unsigned idleTime() const { return _idleAgeMillis; }
uint64_t getLeftoverMaxTimeMicros() const { return _leftoverMaxTime
Micros; }
void setLeftoverMaxTimeMicros( uint64_t leftoverMaxTimeMicros ) {
_leftoverMaxTimeMicros = leftoverMaxTimeMicros;
}
//
// Sharding-specific data. TODO: Document.
//
// future getMore.
void setCollMetadata( CollectionMetadataPtr metadata ){ _collMetada
ta = metadata; }
CollectionMetadataPtr getCollMetadata(){ return _collMetadata; }
//
// Replication-related stuff. TODO: Document and clean.
//
void updateSlaveLocation( CurOp& curop );
void slaveReadTill( const OpTime& t ) { _slaveReadTill = t; }
/** Just for testing. */
OpTime getSlaveReadTill() const { return _slaveReadTill; }
//
// Query-specific functionality that may be adapted for the Runner.
//
Runner* getRunner() const { return _runner.get(); }
int queryOptions() const { return _queryOptions; }
// Used by ops/query.cpp to stash how many results have been return
ed by a query.
int pos() const { return _pos; }
void incPos(int n) { _pos += n; }
void setPos(int n) { _pos = n; }
//
// Yielding that is DEPRECATED. Will be removed when we use runner
s and they yield
// internally.
//
/**
* DEPRECATED
* @param microsToSleep -1 : ask client * @param microsToSleep -1 : ask client
* >=0 : sleep for that amount * 0 : pthread_yield or equivilant
* >0 : sleep for that amount
* @param recordToLoad after yielding lock, load this record with o nly mmutex * @param recordToLoad after yielding lock, load this record with o nly mmutex
* do a dbtemprelease * do a dbtemprelease
* note: caller should check matcher.docMatcher().atomic() first an d not yield if atomic - * note: caller should check matcher.docMatcher().atomic() first an d not yield if atomic -
* we don't do herein as this->matcher (above) is only initia lized for true queries/getmore. * we don't do herein as this->matcher (above) is only initia lized for true queries/getmore.
* (ie not set for remote/update) * (ie not set for remote/update)
* @return if the cursor is still valid. * @return if the cursor is still valid.
* if false is returned, then this ClientCursor should be c onsidered deleted - * if false is returned, then this ClientCursor should be c onsidered deleted -
* in fact, the whole database could be gone. * in fact, the whole database could be gone.
*/ */
bool yield( int microsToSleep = -1 , Record * recordToLoad = 0 ); bool yield( int microsToSleep = -1, Record * recordToLoad = 0 );
enum RecordNeeds { enum RecordNeeds {
DontNeed = -1 , MaybeCovered = 0 , WillNeed = 100 DontNeed = -1 , MaybeCovered = 0 , WillNeed = 100
}; };
/** /**
* @param needRecord whether or not the next record has to be read from disk for sure * @param needRecord whether or not the next record has to be read from disk for sure
* if this is true, will yield of next record isn 't in memory * if this is true, will yield of next record isn 't in memory
* @param yielded true if a yield occurred, and potentially if a yi eld did not occur * @param yielded true if a yield occurred, and potentially if a yi eld did not occur
* @return same as yield() * @return same as yield()
*/ */
bool yieldSometimes( RecordNeeds need, bool *yielded = 0 ); bool yieldSometimes( RecordNeeds need, bool *yielded = 0 );
static int suggestYieldMicros();
static void staticYield( int micros , const StringData& ns , Record
* rec );
struct YieldData { CursorId _id; bool _doingDeletes; }; struct YieldData { CursorId _id; bool _doingDeletes; };
bool prepareToYield( YieldData &data ); bool prepareToYield( YieldData &data );
static bool recoverFromYield( const YieldData &data ); static bool recoverFromYield( const YieldData &data );
static int suggestYieldMicros();
struct YieldLock : boost::noncopyable { //
// Cursor-only DEPRECATED methods.
explicit YieldLock( ptr<ClientCursor> cc ); //
~YieldLock();
/**
* @return if the cursor is still ok
* if it is, we also relock
*/
bool stillOk();
void relock();
private: void storeOpForSlave( DiskLoc last );
const bool _canYield;
YieldData _data;
scoped_ptr<dbtempreleasecond> _unlock;
};
// --- some pass through helpers for Cursor --- // Only used by ops/query.cpp, which will stop using them when quer
ies are answered only by
// a runner.
const BSONObj& query() const { return _query; }
shared_ptr<ParsedQuery> pq;
// This one is used also by pipeline/document_source_cursor.cpp
shared_ptr<Projection> fields; // which fields query wants returned
DiskLoc lastLoc() const { return _lastLoc; }
Cursor* c() const { return _c.get(); } Cursor* c() const { return _c.get(); }
int pos() const { return _pos; }
void incPos( int n ) { _pos += n; } // TODO: this is bad
void setPos( int n ) { _pos = n; } // TODO : this is bad too
BSONObj indexKeyPattern() { return _c->indexKeyPattern(); }
bool modifiedKeys() const { return _c->modifiedKeys(); }
bool isMultiKey() const { return _c->isMultiKey(); }
bool ok() { return _c->ok(); } bool ok() { return _c->ok(); }
bool advance() { return _c->advance(); } bool advance() { return _c->advance(); }
BSONObj current() { return _c->current(); } BSONObj current() { return _c->current(); }
DiskLoc currLoc() { return _c->currLoc(); } DiskLoc currLoc() { return _c->currLoc(); }
BSONObj currKey() const { return _c->currKey(); } BSONObj currKey() const { return _c->currKey(); }
/**
* same as BSONObj::getFieldsDotted
* if it can be retrieved from key, it is
* @param holder keeps the currKey in scope by keeping a reference
to it here. generally you'll want
* holder and ret to destruct about the same time.
* @return if this was retrieved from key
*/
bool getFieldsDotted( const string& name, BSONElementSet &ret, BSON
Obj& holder );
/**
* same as BSONObj::getFieldDotted
* if it can be retrieved from key, it is
* @return if this was retrieved from key
*/
BSONElement getFieldDotted( const string& name , BSONObj& holder ,
bool * fromKey = 0 ) ;
/** extract items from object which match a pattern object.
* e.g., if pattern is { x : 1, y : 1 }, builds an object with
* x and y elements of this object, if they are present.
* returns elements with original field names
* NOTE: copied from BSONObj::extractFields
*/
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;
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 setCollMetadata( CollectionMetadataPtr metadata ){ _collMetada void setDoingDeletes( bool doingDeletes ) {_doingDeletes = doingDel
ta = metadata; } etes; }
CollectionMetadataPtr getCollMetadata(){ return _collMetadata; }
private: private:
void setLastLoc_inlock(DiskLoc); friend class ClientCursorHolder;
friend class ClientCursorPin;
friend struct ClientCursorYieldLock;
friend class CmdCursorInfo;
static ClientCursor* find_inlock(CursorId id, bool warn = true) { // A map from the CursorId to the ClientCursor behind it.
CCById::iterator it = clientCursorsById.find(id); // TODO: Consider making this per-connection.
if ( it == clientCursorsById.end() ) { typedef map<CursorId, ClientCursor*> CCById;
if ( warn ) { static CCById clientCursorsById;
OCCASIONALLY out() << "ClientCursor::find(): cursor not
found in map '" << id
<< "' (ok after a drop)" << endl;
}
return 0;
}
return it->second;
}
/* call when cursor's location changes so that we can update the // A list of NON-CACHED runners. Any runner that yields must be pu
cursorsbylocation map. if you are locked and internally iterating t into this map before
, only // yielding in order to be notified of invalidation and namespace d
need to call when you are ready to "unlock". eletion. Before the
*/ // runner is deleted, it must be removed from this map.
void updateLocation(); //
// TODO: This is temporary and as such is highly NOT optimized.
static set<Runner*> nonCachedRunners;
public: // How many cursors have timed out?
static ClientCursor* find(CursorId id, bool warn = true) { static long long numberTimedOut;
recursive_scoped_lock lock(ccmutex);
ClientCursor *c = find_inlock(id, warn); // This must be held when modifying any static member.
// if this asserts, your code was not thread safe - you either static boost::recursive_mutex& ccmutex;
need to set no timeout
// for the cursor or keep a ClientCursor::Pointer in scope for
it.
massert( 12521, "internal error: use of an unlocked ClientCurso
r", c == 0 || c->_pinValue );
return c;
}
/** /**
* Deletes the cursor with the provided @param 'id' if one exists. * Initialization common between Cursor and Runner.
* @throw if the cursor with the provided id is pinned. * TODO: Remove when we're all-runner.
* This does not do any auth checking and should be used only when
erasing cursors as part
* of cleaning up internal operations.
*/ */
static bool erase(CursorId id); void init();
// Same as erase but checks to make sure this thread has read permi
ssion on the cursor's
// namespace. This should be called when receiving killCursors fro
m a client. This should
// not be called when ccmutex is held.
static bool eraseIfAuthorized(CursorId id);
/** /**
* @return number of cursors found * Allocates a new CursorId.
* Called from init(...). Assumes ccmutex held.
*/ */
static int erase(int n, long long* ids); static CursorId allocCursorId_inlock();
static int eraseIfAuthorized(int n, long long* ids);
void mayUpgradeStorage() {
/* if ( !ids_.get() )
return;
stringstream ss;
ss << ns << "." << cursorid;
ids_->mayUpgradeStorage( ss.str() );*/
}
/** /**
* @param millis amount of idle passed time since last call * Find the ClientCursor with the provided ID. Optionally warn if
it's not found.
* Assumes ccmutex is held.
*/ */
bool shouldTimeout( unsigned millis );
void storeOpForSlave( DiskLoc last ); static ClientCursor* find_inlock(CursorId id, bool warn = true);
void updateSlaveLocation( CurOp& curop );
unsigned idleTime() const { return _idleAgeMillis; } /**
* Delete the ClientCursor with the provided ID. masserts if the c
ursor is pinned.
*/
static void _erase_inlock(ClientCursor* cursor);
void setDoingDeletes( bool doingDeletes ) {_doingDeletes = doingDel //
etes; } // ClientCursor-specific data, independent of the underlying execut
ion type.
//
void slaveReadTill( const OpTime& t ) { _slaveReadTill = t; } // The ID of the ClientCursor.
CursorId _cursorid;
/** Just for testing. */ // A variable indicating the state of the ClientCursor. Possible v
OpTime getSlaveReadTill() const { return _slaveReadTill; } alues:
// 0: Normal behavior. May time out.
// 1: No timing out of this ClientCursor.
// 100: Currently in use (via ClientCursorPin).
unsigned _pinValue;
public: // static methods // The namespace we're operating on.
string _ns;
static void idleTimeReport(unsigned millis); // The database we're operating on.
Database* _db;
static void appendStats( BSONObjBuilder& result ); // How many objects have been returned by the find() so far?
static unsigned numCursors() { return clientCursorsById.size(); } int _pos;
static void aboutToDelete( const StringData& ns,
const NamespaceDetails* nsd,
const DiskLoc& dl );
static void find( const string& ns , set<CursorId>& all );
private: // methods // The query that prompted this ClientCursor. Only used for debugg
ing.
BSONObj _query;
// cursors normally timeout after an inactivity period to prevent e // See the QueryOptions enum in dbclient.h
xcess memory use int _queryOptions;
// setting this prevents timeout of the cursor in question.
void noTimeout() { _pinValue++; }
Record* _recordForYield( RecordNeeds need ); // TODO: document better.
static bool _erase_inlock(ClientCursor* cursor); OpTime _slaveReadTill;
private: // How long has the cursor been idle?
unsigned _idleAgeMillis;
CursorId _cursorid; // TODO: Document.
uint64_t _leftoverMaxTimeMicros;
const string _ns; // For chunks that are being migrated, there is a period of time wh
Database * _db; en that chunks data is in
// two shards, the donor and the receiver one. That data is picked
up by a cursor on the
// receiver side, even before the migration was decided. The Colle
ctionMetadata allow one
// to inquiry if any given document of the collection belongs indee
d to this shard or if it
// is coming from (or a vestige of) an ongoing migration.
CollectionMetadataPtr _collMetadata;
const shared_ptr<Cursor> _c; //
map<string,int> _indexedFields; // map from indexed field to offse // The underlying execution machinery.
t in key object //
int _pos; // # objects into the cursor so fa
r // The new world: a runner.
scoped_ptr<Runner> _runner;
//
// Cursor-only private data and methods. DEPRECATED.
//
const BSONObj _query; // used for logging diags only; op // The old world: a cursor. DEPRECATED.
tional in constructor const shared_ptr<Cursor> _c;
int _queryOptions; // see enum QueryOptions dbclient.h
OpTime _slaveReadTill; /**
* call when cursor's location changes so that we can update the cu
rsorsbylocation map. if
* you are locked and internally iterating, only need to call when
you are ready to
* "unlock".
*/
void updateLocation();
void setLastLoc_inlock(DiskLoc);
Record* _recordForYield( RecordNeeds need );
DiskLoc _lastLoc; // use getter and setter n ot this (important) DiskLoc _lastLoc; // use getter and setter n ot this (important)
unsigned _idleAgeMillis; // how long has the cursor
been around, relative to server idle time
/* 0 = normal
1 = no timeout allowed
100 = in use (pinned) -- see Pointer class
*/
unsigned _pinValue;
bool _doingDeletes; // when true we are the delete and aboutToDelet e shouldn't manipulate us bool _doingDeletes; // when true we are the delete and aboutToDelet e shouldn't manipulate us
ElapsedTracker _yieldSometimesTracker;
CollectionMetadataPtr _collMetadata; // TODO: This will be moved into the runner.
ElapsedTracker _yieldSometimesTracker;
};
/**
* use this to assure we don't in the background time out cursor while
it is under use. if you
* are using noTimeout() already, there is no risk anyway. Further, th
is mechanism guards
* against two getMore requests on the same cursor executing at the sam
e time - which might be
* bad. That should never happen, but if a client driver had a bug, it
could (or perhaps some
* sort of attack situation).
*/
class ClientCursorPin : boost::noncopyable {
public: public:
shared_ptr<ParsedQuery> pq; ClientCursorPin( long long cursorid );
shared_ptr<Projection> fields; // which fields query wants returned ~ClientCursorPin();
void release();
private: // static members // Call this to delete the underlying ClientCursor.
void free();
static CCById clientCursorsById; ClientCursor *c() const;
static long long numberTimedOut; private:
static boost::recursive_mutex& ccmutex; // must use this for all CursorId _cursorid;
statics above! };
static CursorId allocCursorId_inlock();
/** Assures safe and reliable cleanup of a ClientCursor. */
class ClientCursorHolder : boost::noncopyable {
public:
ClientCursorHolder( ClientCursor *c = 0 );
~ClientCursorHolder();
void reset( ClientCursor *c = 0 );
ClientCursor* get();
operator bool() { return _c; }
ClientCursor * operator-> ();
const ClientCursor * operator-> () const;
/** Release ownership of the ClientCursor. */
void release();
private:
ClientCursor *_c;
CursorId _id;
}; };
/** thread for timing out old cursors */
class ClientCursorMonitor : public BackgroundJob { class ClientCursorMonitor : public BackgroundJob {
public: public:
string name() const { return "ClientCursorMonitor"; } string name() const { return "ClientCursorMonitor"; }
void run(); void run();
}; };
struct ClientCursorYieldLock : boost::noncopyable {
explicit ClientCursorYieldLock( ptr<ClientCursor> cc );
~ClientCursorYieldLock();
/**
* @return if the cursor is still ok
* if it is, we also relock
*/
bool stillOk();
void relock();
private:
const bool _canYield;
ClientCursor::YieldData _data;
scoped_ptr<dbtempreleasecond> _unlock;
};
} // namespace mongo } // namespace mongo
// ClientCursor should only be used with auto_ptr because it needs to be // ClientCursor should only be used with auto_ptr because it needs to be
// release()ed after a yield if stillOk() returns false and these pointer t ypes // release()ed after a yield if stillOk() returns false and these pointer t ypes
// do not support releasing. This will prevent them from being used acciden tally // do not support releasing. This will prevent them from being used acciden tally
// Instead of auto_ptr<>, which still requires some degree of manual manage ment // Instead of auto_ptr<>, which still requires some degree of manual manage ment
// of this, consider using ClientCursor::Holder which handles ClientCursor' s // of this, consider using ClientCursor::Holder which handles ClientCursor' s
// unusual self-deletion mechanics. // unusual self-deletion mechanics.
namespace boost{ namespace boost{
template<> class scoped_ptr<mongo::ClientCursor> {}; template<> class scoped_ptr<mongo::ClientCursor> {};
 End of changes. 65 change blocks. 
352 lines changed or deleted 352 lines changed or added


 cmdline.h   cmdline.h 
skipping to change at line 170 skipping to change at line 170
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, std::stringstream &ss); static bool 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( const std::vector<std::string>& 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 );
/** /**
skipping to change at line 198 skipping to change at line 198
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), indexBuildRetry(tru e), quiet(false), port(DefaultDBPort), rest(false), jsonp(false), indexBuildRetry(tru e), 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(true), oplogSize(0), defaultProfile(0), durOptions(0), objcheck(true), oplogSize(0), defaultProfile(0),
slowMS(100), defaultLocalThresholdMillis(15), pretouch(0), movePara noia( false ), slowMS(100), defaultLocalThresholdMillis(15), pretouch(0), movePara noia( true ),
syncdelay(60), noUnixSocket(false), doFork(0), socket("/tmp"), maxC onns(DEFAULT_MAX_CONN), syncdelay(60), noUnixSocket(false), doFork(0), socket("/tmp"), maxC onns(DEFAULT_MAX_CONN),
logAppend(false), logWithSyslog(false), isHttpInterfaceEnabled(fals e) logAppend(false), logWithSyslog(false), isHttpInterfaceEnabled(fals e)
{ {
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
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 collection.h   collection.h 
// @file collection.h // collection.h
/** /**
* Copyright (C) 2012 10gen Inc. * 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.
* *
* 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/namespace_details.h" #include <string>
#include "mongo/base/string_data.h"
#include "mongo/db/diskloc.h"
#include "mongo/db/exec/collection_scan_common.h"
namespace mongo { namespace mongo {
class Collection { class Database;
class ExtentManager;
class NamespaceDetails;
class CollectionIterator;
class FlatIterator;
class CappedIterator;
/**
* this is NOT safe through a yield right now
* not sure if it will be, or what yet
*/
class CollectionTemp {
public: public:
NamespaceDetails * const d; CollectionTemp( const StringData& fullNS,
NamespaceDetailsTransient * const nsd; NamespaceDetails* details,
Database* database );
~CollectionTemp();
bool ok() const { return _magic == 1357924; }
StringData ns() const { return _ns; }
CollectionIterator* getIterator( const DiskLoc& start, bool tailabl
e,
const CollectionScanParams::Direct
ion& dir) const;
private:
ExtentManager* getExtentManager();
const ExtentManager* getExtentManager() const;
int _magic;
std::string _ns;
NamespaceDetails* _details;
Database* _database;
friend class Database;
friend class FlatIterator;
friend class CappedIterator;
}; };
} }
 End of changes. 4 change blocks. 
5 lines changed or deleted 48 lines changed or added


 collection_metadata.h   collection_metadata.h 
skipping to change at line 114 skipping to change at line 114
* caller owns the metadata. * caller owns the metadata.
* *
* If a new metadata can't be created, returns NULL and fills in 'e rrMsg', if it was * If a new metadata can't be created, returns NULL and fills in 'e rrMsg', if it was
* provided. * provided.
*/ */
CollectionMetadata* cloneSplit( const ChunkType& chunk, CollectionMetadata* cloneSplit( const ChunkType& chunk,
const vector<BSONObj>& splitKeys, const vector<BSONObj>& splitKeys,
const ChunkVersion& newShardVersion , const ChunkVersion& newShardVersion ,
string* errMsg ) const; string* errMsg ) const;
/**
* Returns a new metadata instance by merging a key range which sta
rts and ends at existing
* chunks into a single chunk. The range may not have holes. The
resulting metadata will
* have the 'newShardVersion'. The caller owns the new metadata.
*
* If a new metadata can't be created, returns NULL and fills in 'e
rrMsg', if it was
* provided.
*/
CollectionMetadata* cloneMerge( const BSONObj& minKey,
const BSONObj& maxKey,
const ChunkVersion& newShardVersion
,
string* errMsg ) const;
// //
// verification logic // verification logic
// //
/** /**
* Returns true if the document key 'key' is a valid instance of a
shard key for this
* metadata. The 'key' must contain exactly the same fields as the
shard key pattern.
*/
bool isValidKey( const BSONObj& key ) const;
/**
* Returns true if the document key 'key' belongs to this chunkset. Recall that documents of * Returns true if the document key 'key' belongs to this chunkset. Recall that documents of
* an in-flight chunk migration may be present and should not be co nsidered part of the * an in-flight chunk migration may be present and should not be co nsidered part of the
* collection / chunkset yet. Key must be the full shard key. * collection / chunkset yet. Key must be the full shard key.
*/ */
bool keyBelongsToMe( const BSONObj& key ) const; bool keyBelongsToMe( const BSONObj& key ) const;
/** /**
* Returns true if the document key 'key' is or has been migrated t o this shard, and may * Returns true if the document key 'key' is or has been migrated t o this shard, and may
* belong to us after a subsequent config reload. Key must be the full shard key. * belong to us after a subsequent config reload. Key must be the full shard key.
*/ */
bool keyIsPending( const BSONObj& key ) const; bool keyIsPending( const BSONObj& key ) const;
/** /**
* Given the chunk's min key (or empty doc) in 'lookupKey', gets th * Given a key 'lookupKey' in the shard key range, get the next chu
e boundaries of the nk which overlaps or is
* chunk following that one (the first), and fills in 'foundChunk' * greater than this key. Returns true if a chunk exists, false ot
with those herwise.
* boundaries. If the next chunk happens to be the last one, retur *
ns true otherwise * Passing a key that is not a valid shard key for this range resul
* false. ts in undefined behavior.
*
* @param lookupKey passing a doc that does not belong to this meta
data is undefined.
* An empty doc is special and the chunk with the lowest range
will be set on
* foundChunk.
*/ */
bool getNextChunk( const BSONObj& lookupKey, ChunkType* foundChunk bool getNextChunk( const BSONObj& lookupKey, ChunkType* chunk ) con
) const; st;
/**
* Given a key in the shard key range, get the next range which ove
rlaps or is greater than
* this key.
*
* This allows us to do the following to iterate over all orphan ra
nges:
*
* KeyRange range;
* BSONObj lookupKey = metadata->getMinKey();
* while( metadata->getNextOrphanRange( lookupKey, &orphanRange ) )
{
* // Do stuff with range
* lookupKey = orphanRange.maxKey;
* }
*
* @param lookupKey passing a key that does not belong to this meta
data is undefined.
*/
bool getNextOrphanRange( const BSONObj& lookupKey, KeyRange* orphan
Range ) const;
// //
// accessors // accessors
// //
ChunkVersion getCollVersion() const { ChunkVersion getCollVersion() const {
return _collVersion; return _collVersion;
} }
ChunkVersion getShardVersion() const { ChunkVersion getShardVersion() const {
return _shardVersion; return _shardVersion;
} }
BSONObj getKeyPattern() const { BSONObj getKeyPattern() const {
return _keyPattern; return _keyPattern;
} }
BSONObj getMinKey() const;
BSONObj getMaxKey() const;
std::size_t getNumChunks() const { std::size_t getNumChunks() const {
return _chunksMap.size(); return _chunksMap.size();
} }
std::size_t getNumPending() const { std::size_t getNumPending() const {
return _pendingMap.size(); return _pendingMap.size();
} }
//
// reporting
//
/**
* BSON output of the metadata information.
*/
BSONObj toBSON() const;
/**
* BSON output of the metadata information, into a builder.
*/
void toBSON( BSONObjBuilder& bb ) const;
/**
* BSON output of the chunks metadata into a BSONArray
*/
void toBSONChunks( BSONArrayBuilder& bb ) const;
/**
* BSON output of the pending metadata into a BSONArray
*/
void toBSONPending( BSONArrayBuilder& bb ) const;
/**
* String output of the metadata information.
*/
string toString() const; string toString() const;
/** /**
* Use the MetadataLoader to fill the empty metadata from the confi g server, or use * Use the MetadataLoader to fill the empty metadata from the confi g server, or use
* clone*() methods to use existing metadatas to build new ones. * clone*() methods to use existing metadatas to build new ones.
* *
* Unless you are the MetadataLoader or a test you should probably not be using this * Unless you are the MetadataLoader or a test you should probably not be using this
* directly. * directly.
*/ */
CollectionMetadata(); CollectionMetadata();
skipping to change at line 223 skipping to change at line 286
/** /**
* Returns true if this metadata was loaded with all necessary info rmation. * Returns true if this metadata was loaded with all necessary info rmation.
*/ */
bool isValid() const; bool isValid() const;
/** /**
* Try to find chunks that are adjacent and record these intervals in the _rangesMap * Try to find chunks that are adjacent and record these intervals in the _rangesMap
*/ */
void fillRanges(); void fillRanges();
/**
* String representation of [inclusiveLower, exclusiveUpper)
*/
std::string rangeToString( const BSONObj& inclusiveLower,
const BSONObj& exclusiveUpper ) const;
/**
* String representation of overlapping ranges as a list "[range1),
[range2),..."
*/
std::string overlapToString( RangeVector overlap ) const;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 7 change blocks. 
27 lines changed or deleted 87 lines changed or added


 commands.h   commands.h 
skipping to change at line 34 skipping to change at line 34
#include "mongo/db/client_basic.h" #include "mongo/db/client_basic.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
namespace mongo { namespace mongo {
class BSONObj; class BSONObj;
class BSONObjBuilder; class BSONObjBuilder;
class Client; class Client;
class Timer; class Timer;
namespace mutablebson {
class Document;
} // namespace mutablebson
/** mongodb "commands" (sent via db.$cmd.findOne(...)) /** mongodb "commands" (sent via db.$cmd.findOne(...))
subclass to make a command. define a singleton object for it. subclass to make a command. define a singleton object for it.
*/ */
class Command { class Command {
protected: protected:
// The type of the first field in 'cmdObj' must be mongo::String. T
he first field is
// interpreted as a collection name.
string parseNsFullyQualified(const string& dbname, const BSONObj& c mdObj) const; string parseNsFullyQualified(const string& dbname, const BSONObj& c mdObj) const;
public: public:
// only makes sense for commands where 1st parm is the collection.
// Return the namespace for the command. If the first field in 'cmd
Obj' is of type
// mongo::String, then that field is interpreted as the collection
name, and is
// appended to 'dbname' after a '.' character. If the first field i
s not of type
// mongo::String, then 'dbname' is returned unmodified.
virtual string parseNs(const string& dbname, const BSONObj& cmdObj) const; virtual string parseNs(const string& dbname, const BSONObj& cmdObj) const;
// warning: isAuthorized uses the lockType() return values, and val ues are being passed // warning: isAuthorized uses the lockType() return values, and val ues are being passed
// around as ints so be careful as it isn't really typesafe and wil l need cleanup later // around as ints so be careful as it isn't really typesafe and wil l need cleanup later
enum LockType { READ = -1 , NONE = 0 , WRITE = 1 }; enum LockType { READ = -1 , NONE = 0 , WRITE = 1 };
const string name; const string name;
/* run the given command /* run the given command
implement this... implement this...
skipping to change at line 122 skipping to change at line 132
virtual void help( stringstream& help ) const; virtual void help( stringstream& help ) const;
/** /**
* Checks if the given client is authorized to run this command on database "dbname" * Checks if the given client is authorized to run this command on database "dbname"
* with the invocation described by "cmdObj". * with the invocation described by "cmdObj".
*/ */
virtual Status checkAuthForCommand(ClientBasic* client, virtual Status checkAuthForCommand(ClientBasic* client,
const std::string& dbname, const std::string& dbname,
const BSONObj& cmdObj); const BSONObj& cmdObj);
/**
* Redacts "cmdObj" in-place to a form suitable for writing to logs
.
*
* The default implementation does nothing.
*/
virtual void redactForLogging(mutablebson::Document* cmdObj);
/* Return true if a replica set secondary should go into "recoverin g" /* Return true if a replica set secondary should go into "recoverin g"
(unreadable) state while running this command. (unreadable) state while running this command.
*/ */
virtual bool maintenanceMode() const { return false; } virtual bool maintenanceMode() const { return false; }
/* Return true if command should be permitted when a replica set se condary is in "recovering" /* Return true if command should be permitted when a replica set se condary is in "recovering"
(unreadable) state. (unreadable) state.
*/ */
virtual bool maintenanceOk() const { return true; /* assumed true p rior to commit */ } virtual bool maintenanceOk() const { return true; /* assumed true p rior to commit */ }
skipping to change at line 200 skipping to change at line 217
static void execCommandClientBasic(Command* c, static void execCommandClientBasic(Command* c,
ClientBasic& client, ClientBasic& client,
int queryOptions, int queryOptions,
const char *ns, const char *ns,
BSONObj& cmdObj, BSONObj& cmdObj,
BSONObjBuilder& result, BSONObjBuilder& result,
bool fromRepl ); bool fromRepl );
// Helper for setting errmsg and ok field in command result object. // Helper for setting errmsg and ok field in command result object.
static void appendCommandStatus(BSONObjBuilder& result, bool ok, co nst std::string& errmsg); static void appendCommandStatus(BSONObjBuilder& result, bool ok, co nst std::string& errmsg);
static void appendCommandStatus(BSONObjBuilder& result, const Statu s& status);
// Set by command line. Controls whether or not testing-only comma nds should be available. // Set by command line. Controls whether or not testing-only comma nds should be available.
static int testCommandsEnabled; static int testCommandsEnabled;
private:
/**
* Checks to see if the client is authorized to run the given comma
nd with the given
* parameters on the given named database.
*
* fromRepl is true if this command is running as part of oplog app
lication, which for
* historic reasons has slightly different authorization semantics.
TODO(schwerin): Check
* to see if this oddity can now be eliminated.
*
* Returns Status::OK() if the command is authorized. Most likely
returns
* ErrorCodes::Unauthorized otherwise, but any return other than St
atus::OK implies not
* authorized.
*/
static Status _checkAuthorization(Command* c,
ClientBasic* client,
const std::string& dbname,
const BSONObj& cmdObj,
bool fromRepl);
}; };
bool _runCommands(const char *ns, BSONObj& jsobj, BufBuilder &b, BSONOb jBuilder& anObjBuilder, bool fromRepl, int queryOptions); bool _runCommands(const char *ns, BSONObj& jsobj, BufBuilder &b, BSONOb jBuilder& anObjBuilder, bool fromRepl, int queryOptions);
} // namespace mongo } // namespace mongo
 End of changes. 6 change blocks. 
1 lines changed or deleted 48 lines changed or added


 compiler.h   compiler.h 
// @file mongo/platform/compiler.h // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/* #ifndef V8_COMPILER_H_
* Copyright 2012 10gen Inc. #define V8_COMPILER_H_
*
* Licensed under the Apache License, Version 2.0 (the "License"); #include "allocation.h"
* you may not use this file except in compliance with the License. #include "ast.h"
* You may obtain a copy of the License at #include "zone.h"
*
* http://www.apache.org/licenses/LICENSE-2.0 namespace v8 {
* namespace internal {
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, class ScriptDataImpl;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and // CompilationInfo encapsulates some information known at compile time. It
* limitations under the License. // is constructed based on the resources available at compile-time.
*/ class CompilationInfo {
public:
#pragma once CompilationInfo(Handle<Script> script, Zone* zone);
CompilationInfo(Handle<SharedFunctionInfo> shared_info, Zone* zone);
/** CompilationInfo(Handle<JSFunction> closure, Zone* zone);
* Include "mongo/platform/compiler.h" to get compiler-specific macro defin
itions and utilities. virtual ~CompilationInfo();
*/
Isolate* isolate() {
#if defined(_MSC_VER) ASSERT(Isolate::Current() == isolate_);
#include "mongo/platform/compiler_msvc.h" return isolate_;
#elif defined(__GNUC__) }
#include "mongo/platform/compiler_gcc.h" Zone* zone() {
#else return zone_;
#error "Unsupported compiler family" }
bool is_lazy() const { return IsLazy::decode(flags_); }
bool is_eval() const { return IsEval::decode(flags_); }
bool is_global() const { return IsGlobal::decode(flags_); }
bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
bool is_extended_mode() const { return language_mode() == EXTENDED_MODE;
}
LanguageMode language_mode() const {
return LanguageModeField::decode(flags_);
}
bool is_in_loop() const { return IsInLoop::decode(flags_); }
FunctionLiteral* function() const { return function_; }
Scope* scope() const { return scope_; }
Scope* global_scope() const { return global_scope_; }
Handle<Code> code() const { return code_; }
Handle<JSFunction> closure() const { return closure_; }
Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
Handle<Script> script() const { return script_; }
v8::Extension* extension() const { return extension_; }
ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
Handle<Context> calling_context() const { return calling_context_; }
int osr_ast_id() const { return osr_ast_id_; }
void MarkAsEval() {
ASSERT(!is_lazy());
flags_ |= IsEval::encode(true);
}
void MarkAsGlobal() {
ASSERT(!is_lazy());
flags_ |= IsGlobal::encode(true);
}
void SetLanguageMode(LanguageMode language_mode) {
ASSERT(this->language_mode() == CLASSIC_MODE ||
this->language_mode() == language_mode ||
language_mode == EXTENDED_MODE);
flags_ = LanguageModeField::update(flags_, language_mode);
}
void MarkAsInLoop() {
ASSERT(is_lazy());
flags_ |= IsInLoop::encode(true);
}
void MarkAsNative() {
flags_ |= IsNative::encode(true);
}
bool is_native() const {
return IsNative::decode(flags_);
}
void SetFunction(FunctionLiteral* literal) {
ASSERT(function_ == NULL);
function_ = literal;
}
void SetScope(Scope* scope) {
ASSERT(scope_ == NULL);
scope_ = scope;
}
void SetGlobalScope(Scope* global_scope) {
ASSERT(global_scope_ == NULL);
global_scope_ = global_scope;
}
void SetCode(Handle<Code> code) { code_ = code; }
void SetExtension(v8::Extension* extension) {
ASSERT(!is_lazy());
extension_ = extension;
}
void SetPreParseData(ScriptDataImpl* pre_parse_data) {
ASSERT(!is_lazy());
pre_parse_data_ = pre_parse_data;
}
void SetCallingContext(Handle<Context> context) {
ASSERT(is_eval());
calling_context_ = context;
}
void SetOsrAstId(int osr_ast_id) {
ASSERT(IsOptimizing());
osr_ast_id_ = osr_ast_id;
}
void MarkCompilingForDebugging(Handle<Code> current_code) {
ASSERT(mode_ != OPTIMIZE);
ASSERT(current_code->kind() == Code::FUNCTION);
flags_ |= IsCompilingForDebugging::encode(true);
if (current_code->is_compiled_optimizable()) {
EnableDeoptimizationSupport();
} else {
mode_ = CompilationInfo::NONOPT;
}
}
bool IsCompilingForDebugging() {
return IsCompilingForDebugging::decode(flags_);
}
bool has_global_object() const {
return !closure().is_null() && (closure()->context()->global() != NULL)
;
}
GlobalObject* global_object() const {
return has_global_object() ? closure()->context()->global() : NULL;
}
// Accessors for the different compilation modes.
bool IsOptimizing() const { return mode_ == OPTIMIZE; }
bool IsOptimizable() const { return mode_ == BASE; }
void SetOptimizing(int osr_ast_id) {
SetMode(OPTIMIZE);
osr_ast_id_ = osr_ast_id;
}
void DisableOptimization();
// Deoptimization support.
bool HasDeoptimizationSupport() const {
return SupportsDeoptimization::decode(flags_);
}
void EnableDeoptimizationSupport() {
ASSERT(IsOptimizable());
flags_ |= SupportsDeoptimization::encode(true);
}
// Determines whether or not to insert a self-optimization header.
bool ShouldSelfOptimize();
// Disable all optimization attempts of this info for the rest of the
// current compilation pipeline.
void AbortOptimization();
void set_deferred_handles(DeferredHandles* deferred_handles) {
ASSERT(deferred_handles_ == NULL);
deferred_handles_ = deferred_handles;
}
void SaveHandles() {
SaveHandle(&closure_);
SaveHandle(&shared_info_);
SaveHandle(&calling_context_);
SaveHandle(&script_);
}
private:
Isolate* isolate_;
// Compilation mode.
// BASE is generated by the full codegen, optionally prepared for bailout
s.
// OPTIMIZE is optimized code generated by the Hydrogen-based backend.
// NONOPT is generated by the full codegen and is not prepared for
// recompilation/bailouts. These functions are never recompiled.
enum Mode {
BASE,
OPTIMIZE,
NONOPT
};
void Initialize(Mode mode) {
mode_ = V8::UseCrankshaft() ? mode : NONOPT;
ASSERT(!script_.is_null());
if (script_->type()->value() == Script::TYPE_NATIVE) {
MarkAsNative();
}
if (!shared_info_.is_null()) {
ASSERT(language_mode() == CLASSIC_MODE);
SetLanguageMode(shared_info_->language_mode());
}
}
void SetMode(Mode mode) {
ASSERT(V8::UseCrankshaft());
mode_ = mode;
}
// Flags using template class BitField<type, start, length>. All are
// false by default.
//
// Compilation is either eager or lazy.
class IsLazy: public BitField<bool, 0, 1> {};
// Flags that can be set for eager compilation.
class IsEval: public BitField<bool, 1, 1> {};
class IsGlobal: public BitField<bool, 2, 1> {};
// Flags that can be set for lazy compilation.
class IsInLoop: public BitField<bool, 3, 1> {};
// Strict mode - used in eager compilation.
class LanguageModeField: public BitField<LanguageMode, 4, 2> {};
// Is this a function from our natives.
class IsNative: public BitField<bool, 6, 1> {};
// Is this code being compiled with support for deoptimization..
class SupportsDeoptimization: public BitField<bool, 7, 1> {};
// If compiling for debugging produce just full code matching the
// initial mode setting.
class IsCompilingForDebugging: public BitField<bool, 8, 1> {};
unsigned flags_;
// Fields filled in by the compilation pipeline.
// AST filled in by the parser.
FunctionLiteral* function_;
// The scope of the function literal as a convenience. Set to indicate
// that scopes have been analyzed.
Scope* scope_;
// The global scope provided as a convenience.
Scope* global_scope_;
// The compiled code.
Handle<Code> code_;
// Possible initial inputs to the compilation process.
Handle<JSFunction> closure_;
Handle<SharedFunctionInfo> shared_info_;
Handle<Script> script_;
// Fields possibly needed for eager compilation, NULL by default.
v8::Extension* extension_;
ScriptDataImpl* pre_parse_data_;
// The context of the caller is needed for eval code, and will be a null
// handle otherwise.
Handle<Context> calling_context_;
// Compilation mode flag and whether deoptimization is allowed.
Mode mode_;
int osr_ast_id_;
// The zone from which the compilation pipeline working on this
// CompilationInfo allocates.
Zone* zone_;
DeferredHandles* deferred_handles_;
template<typename T>
void SaveHandle(Handle<T> *object) {
if (!object->is_null()) {
Handle<T> handle(*(*object));
*object = handle;
}
}
DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
};
// Exactly like a CompilationInfo, except also creates and enters a
// Zone on construction and deallocates it on exit.
class CompilationInfoWithZone: public CompilationInfo {
public:
explicit CompilationInfoWithZone(Handle<Script> script)
: CompilationInfo(script, &zone_),
zone_(script->GetIsolate()),
zone_scope_(&zone_, DELETE_ON_EXIT) {}
explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info)
: CompilationInfo(shared_info, &zone_),
zone_(shared_info->GetIsolate()),
zone_scope_(&zone_, DELETE_ON_EXIT) {}
explicit CompilationInfoWithZone(Handle<JSFunction> closure)
: CompilationInfo(closure, &zone_),
zone_(closure->GetIsolate()),
zone_scope_(&zone_, DELETE_ON_EXIT) {}
private:
Zone zone_;
ZoneScope zone_scope_;
};
// A wrapper around a CompilationInfo that detaches the Handles from
// the underlying DeferredHandleScope and stores them in info_ on
// destruction.
class CompilationHandleScope BASE_EMBEDDED {
public:
explicit CompilationHandleScope(CompilationInfo* info)
: deferred_(info->isolate()), info_(info) {}
~CompilationHandleScope() {
info_->set_deferred_handles(deferred_.Detach());
}
private:
DeferredHandleScope deferred_;
CompilationInfo* info_;
};
class HGraph;
class HGraphBuilder;
class LChunk;
// A helper class that calls the three compilation phases in
// Crankshaft and keeps track of its state. The three phases
// CreateGraph, OptimizeGraph and GenerateAndInstallCode can either
// fail, bail-out to the full code generator or succeed. Apart from
// their return value, the status of the phase last run can be checked
// using last_status().
class OptimizingCompiler: public ZoneObject {
public:
explicit OptimizingCompiler(CompilationInfo* info)
: info_(info),
oracle_(NULL),
graph_builder_(NULL),
graph_(NULL),
chunk_(NULL),
time_taken_to_create_graph_(0),
time_taken_to_optimize_(0),
time_taken_to_codegen_(0),
last_status_(FAILED) { }
enum Status {
FAILED, BAILED_OUT, SUCCEEDED
};
MUST_USE_RESULT Status CreateGraph();
MUST_USE_RESULT Status OptimizeGraph();
MUST_USE_RESULT Status GenerateAndInstallCode();
Status last_status() const { return last_status_; }
CompilationInfo* info() const { return info_; }
MUST_USE_RESULT Status AbortOptimization() {
info_->AbortOptimization();
info_->shared_info()->DisableOptimization();
return SetLastStatus(BAILED_OUT);
}
private:
CompilationInfo* info_;
TypeFeedbackOracle* oracle_;
HGraphBuilder* graph_builder_;
HGraph* graph_;
LChunk* chunk_;
int64_t time_taken_to_create_graph_;
int64_t time_taken_to_optimize_;
int64_t time_taken_to_codegen_;
Status last_status_;
MUST_USE_RESULT Status SetLastStatus(Status status) {
last_status_ = status;
return last_status_;
}
void RecordOptimizationStats();
struct Timer {
Timer(OptimizingCompiler* compiler, int64_t* location)
: compiler_(compiler),
start_(OS::Ticks()),
location_(location) { }
~Timer() {
*location_ += (OS::Ticks() - start_);
}
OptimizingCompiler* compiler_;
int64_t start_;
int64_t* location_;
};
};
// The V8 compiler
//
// General strategy: Source code is translated into an anonymous function w
/o
// parameters which then can be executed. If the source code contains other
// functions, they will be compiled and allocated as part of the compilatio
n
// of the source code.
// Please note this interface returns shared function infos. This means yo
u
// need to call Factory::NewFunctionFromSharedFunctionInfo before you have
a
// real function with a context.
class Compiler : public AllStatic {
public:
// Default maximum number of function optimization attempts before we
// give up.
static const int kDefaultMaxOptCount = 10;
static const int kMaxInliningLevels = 3;
// Call count before primitive functions trigger their own optimization.
static const int kCallsUntilPrimitiveOpt = 200;
// All routines return a SharedFunctionInfo.
// If an error occurs an exception is raised and the return handle
// contains NULL.
// Compile a String source within a context.
static Handle<SharedFunctionInfo> Compile(Handle<String> source,
Handle<Object> script_name,
int line_offset,
int column_offset,
v8::Extension* extension,
ScriptDataImpl* pre_data,
Handle<Object> script_data,
NativesFlag is_natives_code);
// Compile a String source within a context for Eval.
static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
Handle<Context> context,
bool is_global,
LanguageMode language_mode,
int scope_position);
// Compile from function info (used for lazy compilation). Returns true o
n
// success and false if the compilation resulted in a stack overflow.
static bool CompileLazy(CompilationInfo* info);
static void RecompileParallel(Handle<JSFunction> function);
// Compile a shared function info object (the function is possibly lazily
// compiled).
static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node
,
Handle<Script> script
);
// Set the function info for a newly compiled function.
static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
FunctionLiteral* lit,
bool is_toplevel,
Handle<Script> script);
static void InstallOptimizedCode(OptimizingCompiler* info);
#ifdef ENABLE_DEBUGGER_SUPPORT
static bool MakeCodeForLiveEdit(CompilationInfo* info);
#endif #endif
static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
CompilationInfo* info,
Handle<SharedFunctionInfo> shared);
};
} } // namespace v8::internal
#endif // V8_COMPILER_H_
 End of changes. 3 change blocks. 
30 lines changed or deleted 471 lines changed or added


 count.h   count.h 
skipping to change at line 19 skipping to change at line 19
* *
* 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.
* *
* 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/>.
*/ */
#include "../jsobj.h" #include "mongo/db/diskloc.h"
#include "../diskloc.h" #include "mongo/db/jsobj.h"
namespace mongo { namespace mongo {
/** /**
* { count: "collectionname"[, query: <query>] } * { count: "collectionname"[, query: <query>] }
* @return -1 on ns does not exist error and other errors, 0 on other e rrors, otherwise the match count. * @return -1 on ns does not exist error and other errors, 0 on other e rrors, otherwise the match count.
*/ */
long long runCount(const char *ns, const BSONObj& cmd, string& err, int & errCode ); long long runCount(const char *ns, const BSONObj& cmd, string& err, int & errCode );
} // namespace mongo } // namespace mongo
 End of changes. 1 change blocks. 
2 lines changed or deleted 2 lines changed or added


 counters.h   counters.h 
// Copyright 2012 the V8 project authors. All rights reserved. // counters.h
// Redistribution and use in source and binary forms, with or without /*
// modification, are permitted provided that the following conditions are * Copyright (C) 2010 10gen Inc.
// met: *
// * This program is free software: you can redistribute it and/or modify
// * Redistributions of source code must retain the above copyright * it under the terms of the GNU Affero General Public License, version
// notice, this list of conditions and the following disclaimer. 3,
// * Redistributions in binary form must reproduce the above * as published by the Free Software Foundation.
// copyright notice, this list of conditions and the following *
// disclaimer in the documentation and/or other materials provided * This program is distributed in the hope that it will be useful,
// with the distribution. * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * Neither the name of Google Inc. nor the names of its * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// contributors may be used to endorse or promote products derived * GNU Affero General Public License for more details.
// from this software without specific prior written permission. *
// * You should have received a copy of the GNU Affero General Public Lice
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS nse
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * along with this program. If not, see <http://www.gnu.org/licenses/>.
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, #pragma once
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, #include "mongo/pch.h"
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY #include "../jsobj.h"
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT #include "../../util/net/message.h"
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #include "../../util/processinfo.h"
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../../util/concurrency/spin_lock.h"
#include "mongo/db/pdfile.h"
#ifndef V8_COUNTERS_H_
#define V8_COUNTERS_H_ namespace mongo {
#include "../include/v8.h" /**
#include "allocation.h" * for storing operation counters
* note: not thread safe. ok with that for speed
namespace v8 { */
namespace internal { class OpCounters {
public:
// StatsCounters is an interface for plugging into external
// counters for monitoring. Counters can be looked up and OpCounters();
// manipulated by name. void incInsertInWriteLock(int n) { _insert.x += n; }
void gotInsert() { _insert++; }
class StatsTable { void gotQuery() { _query++; }
public: void gotUpdate() { _update++; }
// Register an application-defined function where void gotDelete() { _delete++; }
// counters can be looked up. void gotGetMore() { _getmore++; }
void SetCounterFunction(CounterLookupCallback f) { void gotCommand() { _command++; }
lookup_function_ = f;
} void gotOp( int op , bool isCommand );
// Register an application-defined function to create BSONObj getObj() const;
// a histogram for passing to the AddHistogramSample function
void SetCreateHistogramFunction(CreateHistogramCallback f) { // thse are used by snmp, and other things, do not remove
create_histogram_function_ = f; const AtomicUInt * getInsert() const { return &_insert; }
} const AtomicUInt * getQuery() const { return &_query; }
const AtomicUInt * getUpdate() const { return &_update; }
// Register an application-defined function to add a sample const AtomicUInt * getDelete() const { return &_delete; }
// to a histogram created with CreateHistogram function const AtomicUInt * getGetMore() const { return &_getmore; }
void SetAddHistogramSampleFunction(AddHistogramSampleCallback f) { const AtomicUInt * getCommand() const { return &_command; }
add_histogram_sample_function_ = f;
} private:
void _checkWrap();
bool HasCounterFunction() const {
return lookup_function_ != NULL; // todo: there will be a lot of cache line contention on these. ne
} ed to do something
// else eventually.
// Lookup the location of a counter by name. If the lookup AtomicUInt _insert;
// is successful, returns a non-NULL pointer for writing the AtomicUInt _query;
// value of the counter. Each thread calling this function AtomicUInt _update;
// may receive a different location to store it's counter. AtomicUInt _delete;
// The return value must not be cached and re-used across AtomicUInt _getmore;
// threads, although a single thread is free to cache it. AtomicUInt _command;
int* FindLocation(const char* name) { };
if (!lookup_function_) return NULL;
return lookup_function_(name); extern OpCounters globalOpCounters;
} extern OpCounters replOpCounters;
// Create a histogram by name. If the create is successful, class NetworkCounter {
// returns a non-NULL pointer for use with AddHistogramSample public:
// function. min and max define the expected minimum and maximum NetworkCounter() : _bytesIn(0), _bytesOut(0), _requests(0), _overfl
// sample values. buckets is the maximum number of buckets ows(0) {}
// that the samples will be grouped into. void hit( long long bytesIn , long long bytesOut );
void* CreateHistogram(const char* name, void append( BSONObjBuilder& b );
int min, private:
int max, long long _bytesIn;
size_t buckets) { long long _bytesOut;
if (!create_histogram_function_) return NULL; long long _requests;
return create_histogram_function_(name, min, max, buckets);
}
// Add a sample to a histogram created with the CreateHistogram
// function.
void AddHistogramSample(void* histogram, int sample) {
if (!add_histogram_sample_function_) return;
return add_histogram_sample_function_(histogram, sample);
}
private:
StatsTable();
CounterLookupCallback lookup_function_;
CreateHistogramCallback create_histogram_function_;
AddHistogramSampleCallback add_histogram_sample_function_;
friend class Isolate;
DISALLOW_COPY_AND_ASSIGN(StatsTable);
};
// StatsCounters are dynamically created values which can be tracked in
// the StatsTable. They are designed to be lightweight to create and
// easy to use.
//
// Internally, a counter represents a value in a row of a StatsTable.
// The row has a 32bit value for each process/thread in the table and also
// a name (stored in the table metadata). Since the storage location can b
e
// thread-specific, this class cannot be shared across threads.
//
// This class is designed to be POD initialized. It will be registered wit
h
// the counter system on first use. For example:
// StatsCounter c = { "c:myctr", NULL, false };
struct StatsCounter {
const char* name_;
int* ptr_;
bool lookup_done_;
// Sets the counter to a specific value.
void Set(int value) {
int* loc = GetPtr();
if (loc) *loc = value;
}
// Increments the counter.
void Increment() {
int* loc = GetPtr();
if (loc) (*loc)++;
}
void Increment(int value) {
int* loc = GetPtr();
if (loc)
(*loc) += value;
}
// Decrements the counter.
void Decrement() {
int* loc = GetPtr();
if (loc) (*loc)--;
}
void Decrement(int value) {
int* loc = GetPtr();
if (loc) (*loc) -= value;
}
// Is this counter enabled?
// Returns false if table is full.
bool Enabled() {
return GetPtr() != NULL;
}
// Get the internal pointer to the counter. This is used
// by the code generator to emit code that manipulates a
// given counter without calling the runtime system.
int* GetInternalPointer() {
int* loc = GetPtr();
ASSERT(loc != NULL);
return loc;
}
protected:
// Returns the cached address of this counter location.
int* GetPtr() {
if (lookup_done_) return ptr_;
lookup_done_ = true;
ptr_ = FindLocationInStatsTable();
return ptr_;
}
private:
int* FindLocationInStatsTable() const;
};
// StatsCounterTimer t = { { L"t:foo", NULL, false }, 0, 0 };
struct StatsCounterTimer {
StatsCounter counter_;
int64_t start_time_;
int64_t stop_time_;
// Start the timer.
void Start();
// Stop the timer and record the results.
void Stop();
// Returns true if the timer is running.
bool Running() {
return counter_.Enabled() && start_time_ != 0 && stop_time_ == 0;
}
};
// A Histogram represents a dynamically created histogram in the StatsTable
.
//
// This class is designed to be POD initialized. It will be registered wit
h
// the histogram system on first use. For example:
// Histogram h = { "myhist", 0, 10000, 50, NULL, false };
struct Histogram {
const char* name_;
int min_;
int max_;
int num_buckets_;
void* histogram_;
bool lookup_done_;
// Add a single sample to this histogram.
void AddSample(int sample);
// Returns true if this histogram is enabled.
bool Enabled() {
return GetHistogram() != NULL;
}
protected:
// Returns the handle to the histogram.
void* GetHistogram() {
if (!lookup_done_) {
lookup_done_ = true;
histogram_ = CreateHistogram();
}
return histogram_;
}
private:
void* CreateHistogram() const;
};
// A HistogramTimer allows distributions of results to be created
// HistogramTimer t = { {L"foo", 0, 10000, 50, NULL, false}, 0, 0 };
struct HistogramTimer {
Histogram histogram_;
int64_t start_time_;
int64_t stop_time_;
// Start the timer.
void Start();
// Stop the timer and record the results.
void Stop();
// Returns true if the timer is running.
bool Running() {
return histogram_.Enabled() && (start_time_ != 0) && (stop_time_ == 0);
}
};
// Helper class for scoping a HistogramTimer.
class HistogramTimerScope BASE_EMBEDDED {
public:
explicit HistogramTimerScope(HistogramTimer* timer) :
timer_(timer) {
timer_->Start();
}
~HistogramTimerScope() {
timer_->Stop();
}
private:
HistogramTimer* timer_;
};
} } // namespace v8::internal long long _overflows;
#endif // V8_COUNTERS_H_ SpinLock _lock;
};
extern NetworkCounter networkCounter;
}
 End of changes. 3 change blocks. 
273 lines changed or deleted 86 lines changed or added


 curop-inl.h   curop-inl.h 
skipping to change at line 17 skipping to change at line 17
* *
* 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.
* *
* 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 "curop.h" #include "mongo/db/curop.h"
 End of changes. 1 change blocks. 
0 lines changed or deleted 0 lines changed or added


 curop.h   curop.h 
skipping to change at line 82 skipping to change at line 82
// detailed options // detailed options
long long cursorid; long long cursorid;
int ntoreturn; int ntoreturn;
int ntoskip; int ntoskip;
bool exhaust; bool exhaust;
// debugging/profile info // debugging/profile info
long long nscanned; long long nscanned;
bool idhack; // indicates short circuited code path on an u pdate to make the update faster bool idhack; // indicates short circuited code path on an u pdate to make the update faster
bool scanAndOrder; // scanandorder query plan aspect was used bool scanAndOrder; // scanandorder query plan aspect was used
long long nupdated; // number of records updated long long nupdated; // number of records updated (including no-ops
)
long long nupdateNoops; // number of records updated which were no
ops
long long nmoved; // updates resulted in a move (moves are expen sive) long long nmoved; // updates resulted in a move (moves are expen sive)
long long ninserted; long long ninserted;
long long ndeleted; long long ndeleted;
bool fastmod; bool fastmod;
bool fastmodinsert; // upsert of an $operation. builds a default o bject bool fastmodinsert; // upsert of an $operation. builds a default o bject
bool upsert; // true if the update actually did an insert bool upsert; // true if the update actually did an insert
int keyUpdates; int keyUpdates;
// error handling // error handling
ExceptionInfo exceptionInfo; ExceptionInfo exceptionInfo;
skipping to change at line 177 skipping to change at line 178
*/ */
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() const { 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();
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; }
int profileLevel() const { return _dbprofile; } int profileLevel() const { return _dbprofile; }
const char * getNS() const { return _ns; } const char * getNS() const { return _ns; }
bool shouldDBProfile( int ms ) const { bool shouldDBProfile( int ms ) const {
skipping to change at line 202 skipping to change at line 201
return _dbprofile >= 2 || ms >= cmdLine.slowMS; return _dbprofile >= 2 || ms >= cmdLine.slowMS;
} }
AtomicUInt opNum() const { return _opNum; } AtomicUInt opNum() const { return _opNum; }
/** if this op is running */ /** if this op is running */
bool active() const { return _active; } bool active() const { return _active; }
bool displayInCurop() const { return _active && ! _suppressFromCuro p; } bool displayInCurop() const { return _active && ! _suppressFromCuro p; }
int getOp() const { return _op; } int getOp() const { return _op; }
//
// Methods for controlling CurOp "max time".
//
/**
* Sets the amount of time operation this should be allowed to run,
units of microseconds.
* The special value 0 is "allow to run indefinitely".
*/
void setMaxTimeMicros(uint64_t maxTimeMicros);
/**
* Checks whether this operation has been running longer than its t
ime limit. Returns
* false if not, or if the operation has no time limit.
*
* Note that KillCurrentOp objects are responsible for interrupting
CurOp objects that
* have exceeded their allotted time; CurOp objects do not interrup
t themselves.
*/
bool maxTimeHasExpired();
/**
* Returns the number of microseconds remaining for this operation'
s time limit, or the
* special value 0 if the operation has no time limit.
*
* Calling this method is more expensive than calling its sibling "
maxTimeHasExpired()",
* since an accurate measure of remaining time needs to be calculat
ed.
*/
uint64_t getRemainingMaxTimeMicros() const;
//
// Methods for getting/setting elapsed time.
//
void ensureStarted();
bool isStarted() const { return _start > 0; }
unsigned long long startTime() { // micros unsigned long long startTime() { // micros
ensureStarted(); ensureStarted();
return _start; return _start;
} }
void done() { void done() {
_active = false; _active = false;
_end = curTimeMicros64(); _end = curTimeMicros64();
} }
unsigned long long totalTimeMicros() { unsigned long long totalTimeMicros() {
massert( 12601 , "CurOp not marked done yet" , ! _active ); massert( 12601 , "CurOp not marked done yet" , ! _active );
return _end - startTime(); return _end - startTime();
} }
int totalTimeMillis() { return (int) (totalTimeMicros() / 1000); } int totalTimeMillis() { return (int) (totalTimeMicros() / 1000); }
unsigned long long elapsedMicros() {
return curTimeMicros64() - startTime();
}
int elapsedMillis() { int elapsedMillis() {
unsigned long long total = curTimeMicros64() - startTime(); return (int) (elapsedMicros() / 1000);
return (int) (total / 1000);
} }
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();
// Fetches less information than "info()"; used to search for ops w ith certain criteria // Fetches less information than "info()"; used to search for ops w ith certain criteria
BSONObj description(); BSONObj description();
string getRemoteString( bool includePort = true ) { return _remote. toString(includePort); } string getRemoteString( bool includePort = true ) { return _remote. toString(includePort); }
ProgressMeter& setMessage(const char * msg, ProgressMeter& setMessage(const char * msg,
skipping to change at line 292 skipping to change at line 330
AtomicInt32 _killPending; AtomicInt32 _killPending;
int _numYields; int _numYields;
LockStat _lockStat; LockStat _lockStat;
// _notifyList is protected by the global killCurrentOp's mtx. // _notifyList is protected by the global killCurrentOp's mtx.
std::vector<bool*> _notifyList; 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;
/** Nested class that implements a time limit ($maxTimeMS) for a Cu
rOp object. */
class MaxTimeTracker {
MONGO_DISALLOW_COPYING(MaxTimeTracker);
public:
/** Newly-constructed MaxTimeTracker objects have the time limi
t disabled. */
MaxTimeTracker();
/** Disables the time limit. */
void reset();
/**
* Enables the time limit to be "durationMicros" microseconds f
rom "startEpochMicros"
* (units of microseconds since the epoch).
*
* "durationMicros" must be nonzero.
*/
void setTimeLimit(uint64_t startEpochMicros, uint64_t durationM
icros);
/**
* Checks whether the time limit has been hit. Returns false i
f not, or if the time
* limit is disabled.
*/
bool checkTimeLimit();
/**
* Returns the number of microseconds remaining for the time li
mit, or the special
* value 0 if the time limit is disabled.
*
* Calling this method is more expensive than calling its sibli
ng "checkInterval()",
* since an accurate measure of remaining time needs to be calc
ulated.
*/
uint64_t getRemainingMicros() const;
private:
// Whether or not this operation is subject to a time limit.
bool _enabled;
// Point in time at which the time limit is hit. Units of micr
oseconds since the
// epoch.
uint64_t _targetEpochMicros;
// Approximate point in time at which the time limit is hit.
Units of milliseconds
// since the server process was started.
int64_t _approxTargetServerMillis;
} _maxTimeTracker;
}; };
} }
 End of changes. 8 change blocks. 
5 lines changed or deleted 108 lines changed or added


 d_logic.h   d_logic.h 
skipping to change at line 26 skipping to change at line 26
*/ */
#pragma once #pragma once
#include "mongo/pch.h" #include "mongo/pch.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/s/collection_metadata.h" #include "mongo/s/collection_metadata.h"
#include "mongo/s/chunk_version.h" #include "mongo/s/chunk_version.h"
#include "mongo/util/concurrency/ticketholder.h" #include "mongo/util/concurrency/ticketholder.h"
#include "mongo/util/net/message.h"
namespace mongo { namespace mongo {
class Database; class Database;
class DiskLoc; class DiskLoc;
// -------------- // --------------
// --- global state --- // --- global state ---
// -------------- // --------------
skipping to change at line 65 skipping to change at line 66
/** 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
bool hasVersion( const string& ns ); bool hasVersion( const string& ns );
bool hasVersion( const string& ns , ChunkVersion& version ); bool hasVersion( const string& ns , ChunkVersion& version );
const ChunkVersion getVersion( const string& ns ) const; const ChunkVersion getVersion( const string& ns ) const;
/** /**
* Uninstalls the metadata for a given collection. This should be u * If the metadata for 'ns' at this shard is at or above the reques
sed when the collection ted version,
* is dropped. * 'reqShardVersion', returns OK and fills in 'latestShardVersion'
* with the latest shard
* NOTE: * version. The latter is always greater or equal than 'reqShardVe
* An existing collection with no chunks on this shard will have rsion' if in the same
metadata on version 0, * epoch.
* which is different than a dropped collection, which will not h *
ave metadata. * Otherwise, falls back to refreshMetadataNow.
* *
* TODO: * This call blocks if there are more than N threads
* All collections should have metadata. (The non-sharded ones ar * currently refreshing metadata. (N is the number of
e a degenerate case of * tickets in ShardingState::_configServerTickets,
* one-chunk collections). * currently 3.)
* *
* @param ns the collection to be dropped * Locking Note:
*/ * + Must NOT be called with the write lock because this call may
void resetVersion( const string& ns ); go into the network,
* and deadlocks may occur with shard-as-a-config. Therefore,
/** nothing here guarantees
* Requests to access a collection at a certain version. If the col * that 'latestShardVersion' is indeed the current one on retur
lection's metadata is not n.
* at that version it will try to update itself to the newest versi */
on. The request is only Status refreshMetadataIfNeeded( const string& ns,
* granted if the version is the current or the newest one. const ChunkVersion& reqShardVersion
* ,
* @param ns collection to be accessed ChunkVersion* latestShardVersion );
* @param version (IN) the client believe this collection is on and
(OUT) the version the /**
* metadata is actually in * Refreshes collection metadata by asking the config server for th
* @return true if the access can be allowed at the provided versio e latest information.
n * Starts a new config server request.
*
* Locking Notes:
* + Must NOT be called with the write lock because this call may
go into the network,
* and deadlocks may occur with shard-as-a-config. Therefore,
nothing here guarantees
* that 'latestShardVersion' is indeed the current one on retur
n.
*
* + Because this call must not be issued with the DBLock held, b
y the time the config
* server sent us back the collection metadata information, som
eone else may have
* updated the previously stored collection metadata. There ar
e cases when one can't
* tell which of updated or loaded metadata are the freshest. T
here are also cases where
* the data coming from configs do not correspond to a consiste
nt snapshot.
* In these cases, return RemoteChangeDetected. (This usually m
eans this call needs to
* be issued again, at caller discretion)
*
* @return OK if remote metadata successfully loaded (may or may no
t have been installed)
* @return RemoteChangeDetected if something changed while reloadin
g and we may retry
* @return !OK if something else went wrong during reload
* @return latestShardVersion the version that is now stored for th
is collection
*/ */
bool trySetVersion( const string& ns , ChunkVersion& version ); Status refreshMetadataNow( const string& ns, ChunkVersion* latestSh ardVersion );
void appendInfo( BSONObjBuilder& b ); void appendInfo( BSONObjBuilder& b );
// querying support // querying support
bool needCollectionMetadata( const string& ns ) const; bool needCollectionMetadata( const string& ns ) const;
CollectionMetadataPtr getCollectionMetadata( const string& ns ); CollectionMetadataPtr getCollectionMetadata( const string& ns );
// chunk migrate and split support // chunk migrate and split support
skipping to change at line 142 skipping to change at line 161
* into it. This data can then be protected against cleanup of orp haned data. * into it. This data can then be protected against cleanup of orp haned data.
* *
* Overlapping pending ranges will be removed, so it is only safe t o use this when you know * Overlapping pending ranges will be removed, so it is only safe t o use this when you know
* your metadata view is definitive, such as at the start of a migr ation. * your metadata view is definitive, such as at the start of a migr ation.
* *
* @return false with errMsg if the range is owned by this shard * @return false with errMsg if the range is owned by this shard
*/ */
bool notePending( const string& ns, bool notePending( const string& ns,
const BSONObj& min, const BSONObj& min,
const BSONObj& max, const BSONObj& max,
const OID& epoch,
string* errMsg ); string* errMsg );
/** /**
* Stops tracking a chunk range between 'min' and 'max' that previo usly was having data * Stops tracking a chunk range between 'min' and 'max' that previo usly was having data
* migrated into it. This data is no longer protected against clea nup of orphaned data. * migrated into it. This data is no longer protected against clea nup of orphaned data.
* *
* To avoid removing pending ranges of other operations, ensure tha t this is only used when * To avoid removing pending ranges of other operations, ensure tha t this is only used when
* a migration is still active. * a migration is still active.
* TODO: Because migrations may currently be active when a collecti on drops, an epoch is * TODO: Because migrations may currently be active when a collecti on drops, an epoch is
* necessary to ensure the pending metadata change is still applica ble. * necessary to ensure the pending metadata change is still applica ble.
skipping to change at line 178 skipping to change at line 198
* as the current shards, clients shouldn't perceive the split. * as the current shards, clients shouldn't perceive the split.
* *
* @param ns the collection * @param ns the collection
* @param min max the chunk that should be split * @param min max the chunk that should be split
* @param splitKeys point in which to split * @param splitKeys point in which to split
* @param version at which the new metadata should be at * @param version at which the new metadata should be at
*/ */
void splitChunk( const string& ns , const BSONObj& min , const BSON Obj& max , const vector<BSONObj>& splitKeys , void splitChunk( const string& ns , const BSONObj& min , const BSON Obj& max , const vector<BSONObj>& splitKeys ,
ChunkVersion version ); ChunkVersion version );
/**
* Creates and installs a new chunk metadata for a given collection
by merging a range of
* chunks ['minKey', 'maxKey') into a single chunk with version 'me
rgedVersion'.
* The current metadata must overlap the range completely and minKe
y and maxKey must not
* divide an existing chunk.
*
* The merged chunk version must have a greater version than the cu
rrent shard version,
* and if it has a greater major version clients will need to reloa
d metadata.
*
* @param ns the collection
* @param minKey maxKey the range which should be merged
* @param newShardVersion the shard version the newly merged chunk
should have
*/
void mergeChunks( const string& ns,
const BSONObj& minKey,
const BSONObj& maxKey,
ChunkVersion mergedVersion );
bool inCriticalMigrateSection(); bool inCriticalMigrateSection();
/** /**
* @return true if we are NOT in the critical section * @return true if we are NOT in the critical section
*/ */
bool waitTillNotInCriticalSection( int maxSecondsToWait ); bool waitTillNotInCriticalSection( int maxSecondsToWait );
/**
* TESTING ONLY
* Uninstalls the metadata for a given collection.
*/
void resetMetadata( const string& ns );
private: private:
/**
* Refreshes collection metadata by asking the config server for th
e latest information.
* May or may not be based on a requested version.
*/
Status doRefreshMetadata( const string& ns,
const ChunkVersion& reqShardVersion,
bool useRequestedVersion,
ChunkVersion* latestShardVersion );
bool _enabled; bool _enabled;
string _configServer; string _configServer;
string _shardName; string _shardName;
string _shardHost; string _shardHost;
// protects state below // protects state below
mutable mongo::mutex _mutex; mutable mongo::mutex _mutex;
// protects accessing the config server // protects accessing the config server
 End of changes. 7 change blocks. 
33 lines changed or deleted 106 lines changed or added


 database.h   database.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
#include "mongo/db/cc_by_loc.h" #include "mongo/db/cc_by_loc.h"
#include "mongo/db/cmdline.h" #include "mongo/db/cmdline.h"
#include "mongo/db/namespace_details.h" #include "mongo/db/namespace_details.h"
#include "mongo/db/record.h" #include "mongo/db/storage/record.h"
#include "mongo/db/storage/extent_manager.h"
#include "mongo/db/structure/collection.h"
namespace mongo { namespace mongo {
class Extent; class Extent;
class MongoDataFile; class DataFile;
/** /**
* Database represents a database database * Database represents a database database
* Each database database has its own set of files -- dbname.ns, dbname .0, dbname.1, ... * Each database database has its own set of files -- dbname.ns, dbname .0, dbname.1, ...
* NOT memory mapped * NOT memory mapped
*/ */
class Database { class Database {
public: public:
// you probably need to be in dbHolderMutex when constructing this // you probably need to be in dbHolderMutex when constructing this
Database(const char *nm, /*out*/ bool& newDb, const string& path = dbpath); Database(const char *nm, /*out*/ bool& newDb, const string& path = dbpath);
skipping to change at line 61 skipping to change at line 63
/** /**
* tries to make sure that this hasn't been deleted * tries to make sure that this hasn't been deleted
*/ */
bool isOk() const { return _magic == 781231; } bool isOk() const { return _magic == 781231; }
bool isEmpty() { return ! _namespaceIndex.allocated(); } bool isEmpty() { return ! _namespaceIndex.allocated(); }
/** /**
* total file size of Database in bytes * total file size of Database in bytes
*/ */
long long fileSize() const; long long fileSize() const { return _extentManager.fileSize(); }
int numFiles() const; int numFiles() const { return _extentManager.numFiles(); }
/**
* returns file valid for file number n
*/
boost::filesystem::path fileName( int n ) const;
/** /**
* return file n. if it doesn't exist, create it * return file n. if it doesn't exist, create it
*/ */
MongoDataFile* getFile( int n, int sizeNeeded = 0, bool preallocate DataFile* getFile( int n, int sizeNeeded = 0, bool preallocateOnly
Only = false ); = false ) {
_namespaceIndex.init();
return _extentManager.getFile( n, sizeNeeded, preallocateOnly )
;
}
MongoDataFile* addAFile( int sizeNeeded, bool preallocateNextFile ) DataFile* addAFile( int sizeNeeded, bool preallocateNextFile ) {
; return _extentManager.addAFile( sizeNeeded, preallocateNextFile
);
}
/** /**
* makes sure we have an extra file at the end that is empty * makes sure we have an extra file at the end that is empty
* safe to call this multiple times - the implementation will only preallocate one file * safe to call this multiple times - the implementation will only preallocate one file
*/ */
void preallocateAFile() { getFile( numFiles() , 0, true ); } void preallocateAFile() { _extentManager.preallocateAFile(); }
MongoDataFile* suitableFile( const char *ns, int sizeNeeded, bool p
reallocate, bool enforceQuota );
Extent* allocExtent( const char *ns, int size, bool capped, bool en forceQuota ); Extent* allocExtent( const char *ns, int size, bool capped, bool en forceQuota );
MongoDataFile* newestFile();
/** /**
* @return true if success. false if bad level or error creating p rofile ns * @return true if success. false if bad level or error creating p rofile ns
*/ */
bool setProfilingLevel( int newLevel , string& errmsg ); bool setProfilingLevel( int newLevel , string& errmsg );
void flushFiles( bool sync ); void flushFiles( bool sync ) { return _extentManager.flushFiles( sy nc ); }
/** /**
* @return true if ns is part of the database * @return true if ns is part of the database
* ns=foo.bar, db=foo returns true * ns=foo.bar, db=foo returns true
*/ */
bool ownsNS( const string& ns ) const { bool ownsNS( const string& ns ) const {
if ( ! startsWith( ns , _name ) ) if ( ! startsWith( ns , _name ) )
return false; return false;
return ns[_name.size()] == '.'; return ns[_name.size()] == '.';
} }
skipping to change at line 117 skipping to change at line 115
RecordStats& recordStats() { return _recordStats; } RecordStats& recordStats() { return _recordStats; }
int getProfilingLevel() const { return _profile; } int getProfilingLevel() const { return _profile; }
const char* getProfilingNS() const { return _profileName.c_str(); } const char* getProfilingNS() const { return _profileName.c_str(); }
CCByLoc& ccByLoc() { return _ccByLoc; } CCByLoc& ccByLoc() { return _ccByLoc; }
const NamespaceIndex& namespaceIndex() const { return _namespaceInd ex; } const NamespaceIndex& namespaceIndex() const { return _namespaceInd ex; }
NamespaceIndex& namespaceIndex() { return _namespaceIndex; } NamespaceIndex& namespaceIndex() { return _namespaceIndex; }
// TODO: do not think this method should exist, so should try and e
ncapsulate better
ExtentManager& getExtentManager() { return _extentManager; }
const ExtentManager& getExtentManager() const { return _extentManag
er; }
void dropCollection( const StringData& fullns );
/**
* @param ns - this is fully qualified, which is maybe not ideal ??
?
*/
CollectionTemp* getCollectionTemp( const StringData& ns );
/** /**
* @return name of an existing database with same text name but dif ferent * @return name of an existing database with same text name but dif ferent
* casing, if one exists. Otherwise the empty string is returned. If * casing, if one exists. Otherwise the empty string is returned. If
* 'duplicates' is specified, it is filled with all duplicate names . * 'duplicates' is specified, it is filled with all duplicate names .
*/ */
static string duplicateUncasedName( bool inholderlockalready, const string &name, const string &path, set< string > *duplicates = 0 ); static string duplicateUncasedName( bool inholderlockalready, const string &name, const string &path, set< string > *duplicates = 0 );
static Status validateDBName( const StringData& dbname );
private: private:
~Database(); // closes files and other cleanup see below. ~Database(); // closes files and other cleanup see below.
/** /**
* @throws DatabaseDifferCaseCode if the name is a duplicate based on * @throws DatabaseDifferCaseCode if the name is a duplicate based on
* case insensitive matching. * case insensitive matching.
*/ */
void checkDuplicateUncasedNames(bool inholderlockalready) const; void checkDuplicateUncasedNames(bool inholderlockalready) const;
bool exists(int n) const;
void openAllFiles(); void openAllFiles();
/** /**
* throws exception if error encounted * throws exception if error encounted
* @return true if the file was opened * @return true if the file was opened
* false if no errors, but file doesn't exist * false if no errors, but file doesn't exist
*/ */
bool openExistingFile( int n ); bool openExistingFile( int n );
const string _name; // "alleyinsider" const string _name; // "alleyinsider"
const string _path; // "/data/db" const string _path; // "/data/db"
// must be in the dbLock when touching this (and write locked when
writing to of course)
// however during Database object construction we aren't, which is
ok as it isn't yet visible
// to others and we are in the dbholder lock then.
vector<MongoDataFile*> _files;
NamespaceIndex _namespaceIndex; NamespaceIndex _namespaceIndex;
ExtentManager _extentManager;
const string _profileName; // "alleyinsider.system.profile" const string _profileName; // "alleyinsider.system.profile"
CCByLoc _ccByLoc; // use by ClientCursor CCByLoc _ccByLoc; // use by ClientCursor
RecordStats _recordStats; RecordStats _recordStats;
int _profile; // 0=off. int _profile; // 0=off.
int _magic; // used for making sure the object is still loaded in m emory int _magic; // used for making sure the object is still loaded in m emory
// TODO: probably shouldn't be a std::map
// TODO: make sure deletes go through
// this in some ways is a dupe of _namespaceIndex
// but it points to a much more useful data structure
typedef std::map< std::string, CollectionTemp* > CollectionMap;
CollectionMap _collections;
mutex _collectionLock;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 15 change blocks. 
28 lines changed or deleted 44 lines changed or added


 db.h   db.h 
skipping to change at line 23 skipping to change at line 23
* 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/client.h" #include "mongo/db/client.h"
#include "mongo/db/curop.h" #include "mongo/db/curop.h"
#include "mongo/db/databaseholder.h" #include "mongo/db/database_holder.h"
#include "mongo/db/pdfile.h" #include "mongo/db/pdfile.h"
#include "mongo/util/net/message.h" #include "mongo/util/net/message.h"
namespace mongo { namespace mongo {
// todo: relocked is being called when there was no unlock below. // todo: relocked is being called when there was no unlock below.
// that is weird. // that is weird.
struct dbtemprelease { struct dbtemprelease {
Client::Context * _context; Client::Context * _context;
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 dbclient_rs.h   dbclient_rs.h 
skipping to change at line 209 skipping to change at line 209
/** /**
* checks all sets for current master and new secondaries * checks all sets for current master and new secondaries
* usually only called from a BackgroundJob * usually only called from a BackgroundJob
*/ */
static void checkAll(); static void checkAll();
/** /**
* Removes the ReplicaSetMonitor for the given set name from _sets, which will delete it. * Removes the ReplicaSetMonitor for the given set name from _sets, which will delete it.
* If clearSeedCache is true, then the cached seed string for this Replica Set will be removed * If clearSeedCache is true, then the cached seed string for this Replica Set will be removed
* from _setServers. * from _seedServers.
*/ */
static void remove( const string& name, bool clearSeedCache = false ); static void remove( const string& name, bool clearSeedCache = false );
static int getMaxFailedChecks() { return _maxFailedChecks; }; static int getMaxFailedChecks() { return _maxFailedChecks; };
static void setMaxFailedChecks(int numChecks) { _maxFailedChecks = numChecks; }; static void setMaxFailedChecks(int numChecks) { _maxFailedChecks = numChecks; };
/** /**
* this is called whenever the config of any replica set changes * this is called whenever the config of any replica set changes
* currently only 1 globally * currently only 1 globally
* asserts if one already exists * asserts if one already exists
* ownership passes to ReplicaSetMonitor and the hook will actually never be deleted * ownership passes to ReplicaSetMonitor and the hook will actually never be deleted
*/ */
static void setConfigChangeHook( ConfigChangeHook hook ); static void setConfigChangeHook( ConfigChangeHook hook );
/**
* Stops all monitoring on replica sets and clears all cached infor
mation as well.
* Note that this does not prevent new monitors from being created
afterwards or even
* while this is being executed. As a consequence, NEVER call this
if you have other
* threads that has a DBClientReplicaSet instance or will create on
e before this
* fully terminates as it will cause a deadlock. This is intended f
or performing cleanups
* in unit tests.
*
* Warning: Make sure that the monitor thread is running, otherwise
this can hang
* indefinitely.
*/
static void cleanup();
~ReplicaSetMonitor(); ~ReplicaSetMonitor();
/** @return HostAndPort or throws an exception */ /** @return HostAndPort or throws an exception */
HostAndPort getMaster(); HostAndPort getMaster();
/** /**
* notify the monitor that server has faild * notify the monitor that server has faild
*/ */
void notifyFailure( const HostAndPort& server ); void notifyFailure( const HostAndPort& server );
skipping to change at line 327 skipping to change at line 340
* @param verbose * @param verbose
* @param nodesOffset - offset into _nodes array, -1 for not in it * @param nodesOffset - offset into _nodes array, -1 for not in it
* *
* @return true if the connection is good or false if invariant * @return true if the connection is good or false if invariant
* is broken * is broken
*/ */
bool _checkConnection( DBClientConnection* conn, string& maybePrima ry, bool _checkConnection( DBClientConnection* conn, string& maybePrima ry,
bool verbose, int nodesOffset ); bool verbose, int nodesOffset );
/** /**
* Save the seed list for the current set into the _setServers map * Save the seed list for the current set into the _seedServers map
* Should only be called if you're already holding _setsLock and th is * Should only be called if you're already holding _setsLock and th is
* monitor's _lock. * monitor's _lock.
*/ */
void _cacheServerAddresses_inlock(); void _cacheServerAddresses_inlock();
string _getServerAddress_inlock() const; string _getServerAddress_inlock() const;
NodeDiff _getHostDiff_inlock( const BSONObj& hostList ); NodeDiff _getHostDiff_inlock( const BSONObj& hostList );
bool _shouldChangeHosts( const BSONObj& hostList, bool inlock ); bool _shouldChangeHosts( const BSONObj& hostList, bool inlock );
skipping to change at line 391 skipping to change at line 404
std::vector<Node> _nodes; std::vector<Node> _nodes;
int _master; // which node is the current master. -1 means no mast er is known int _master; // which node is the current master. -1 means no mast er is known
int _nextSlave; // which node is the current slave, only used by th e deprecated getSlave int _nextSlave; // which node is the current slave, only used by th e deprecated getSlave
// last host returned by _selectNode, used for round robin selectio n // last host returned by _selectNode, used for round robin selectio n
HostAndPort _lastReadPrefHost; HostAndPort _lastReadPrefHost;
// The number of consecutive times the set has been checked and eve ry member in the set was down. // The number of consecutive times the set has been checked and eve ry member in the set was down.
int _failedChecks; int _failedChecks;
static mongo::mutex _setsLock; // protects _sets and _setServers static mongo::mutex _setsLock; // protects _seedServers and _sets
static map<string,ReplicaSetMonitorPtr> _sets; // set name to Monit
or // set name to seed list.
static map<string,vector<HostAndPort> > _seedServers; // set name t // Used to rebuild the monitor if it is cleaned up but then the set
o seed list. Used to rebuild the monitor if it is cleaned up but then the s is accessed again.
et is accessed again. static map<string, vector<HostAndPort> > _seedServers;
static map<string, ReplicaSetMonitorPtr> _sets; // set name to Moni
tor
static ConfigChangeHook _hook; static ConfigChangeHook _hook;
int _localThresholdMillis; // local ping latency threshold (protect ed by _lock) int _localThresholdMillis; // local ping latency threshold (protect ed by _lock)
static int _maxFailedChecks; static int _maxFailedChecks;
}; };
/** Use this class to connect to a replica set of servers. The class w ill manage /** Use this class to connect to a replica set of servers. The class w ill manage
checking for which server in a replica set is master, and do failove r automatically. checking for which server in a replica set is master, and do failove r automatically.
 End of changes. 4 change blocks. 
8 lines changed or deleted 29 lines changed or added


 dbclientinterface.h   dbclientinterface.h 
skipping to change at line 701 skipping to change at line 701
/** Get error result from the last write operation (insert/update/d elete) on this connection. /** Get error result from the last write operation (insert/update/d elete) on this connection.
db doesn't change the command's behavior - it is just for auth checks. db doesn't change the command's behavior - it is just for auth checks.
@return error message text, or empty string if no error. @return error message text, or empty string if no error.
*/ */
string getLastError(const std::string& db, string getLastError(const std::string& db,
bool fsync = false, bool fsync = false,
bool j = false, bool j = false,
int w = 0, int w = 0,
int wtimeout = 0); int wtimeout = 0);
// Same as above but defaults to using admin DB /**
* Same as the form of getLastError that takes a dbname, but just u
ses the admin DB.
*/
string getLastError(bool fsync = false, bool j = false, int w = 0, int wtimeout = 0); string getLastError(bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
/** Get error result from the last write operation (insert/update/d elete) on this connection. /** Get error result from the last write operation (insert/update/d elete) on this connection.
db doesn't change the command's behavior - it is just for auth checks. db doesn't change the command's behavior - it is just for auth checks.
@return full error object. @return full error object.
If "w" is -1, wait for propagation to majority of nodes. If "w" is -1, wait for propagation to majority of nodes.
If "wtimeout" is 0, the operation will block indefinitely if ne eded. If "wtimeout" is 0, the operation will block indefinitely if ne eded.
*/ */
virtual BSONObj getLastErrorDetailed(const std::string& db, virtual BSONObj getLastErrorDetailed(const std::string& db,
bool fsync = false, bool fsync = false,
bool j = false, bool j = false,
int w = 0, int w = 0,
int wtimeout = 0); int wtimeout = 0);
// Same as above but defaults to using admin DB /**
* Same as the form of getLastErrorDetailed that takes a dbname, bu
t just uses the admin DB.
*/
virtual BSONObj getLastErrorDetailed(bool fsync = false, bool j = f alse, int w = 0, int wtimeout = 0); virtual BSONObj getLastErrorDetailed(bool fsync = false, bool j = f alse, int w = 0, int wtimeout = 0);
/** Can be called with the returned value from getLastErrorDetailed to extract an error string. /** Can be called with the returned value from getLastErrorDetailed to extract an error string.
If all you need is the string, just call getLastError() instead . If all you need is the string, just call getLastError() instead .
*/ */
static string getLastErrorString( const BSONObj& res ); static string getLastErrorString( const BSONObj& res );
/** Return the last error which has occurred, even if not the very last operation. /** Return the last error which has occurred, even if not the very last operation.
@return { err : <error message>, nPrev : <how_many_ops_back_occu rred>, ok : 1 } @return { err : <error message>, nPrev : <how_many_ops_back_occu rred>, ok : 1 }
skipping to change at line 1134 skipping to change at line 1138
public: public:
using DBClientBase::query; using DBClientBase::query;
/** /**
@param _autoReconnect if true, automatically reconnect on a conn ection failure @param _autoReconnect if true, automatically reconnect on a conn ection failure
@param cp used by DBClientReplicaSet. You do not need to specif y this parameter @param cp used by DBClientReplicaSet. You do not need to specif y this parameter
@param timeout tcp timeout in seconds - this is for read/write, not connect. @param timeout tcp timeout in seconds - this is for read/write, not connect.
Connect timeout is fixed, but short, at 5 seconds. Connect timeout is fixed, but short, at 5 seconds.
*/ */
DBClientConnection(bool _autoReconnect=false, DBClientReplicaSet* c p=0, double so_timeout=0) : DBClientConnection(bool _autoReconnect=false, DBClientReplicaSet* c p=0, double so_timeout=0) :
clientSet(cp), _failed(false), autoReconnect(_autoReconnect), l astReconnectTry(0), _so_timeout(so_timeout) { clientSet(cp), _failed(false), autoReconnect(_autoReconnect), a utoReconnectBackoff(1000, 2000), _so_timeout(so_timeout) {
_numConnections++; _numConnections++;
} }
virtual ~DBClientConnection() { virtual ~DBClientConnection() {
_numConnections--; _numConnections--;
} }
/** Connect to a Mongo database server. /** Connect to a Mongo database server.
If autoReconnect is true, you can try to use the DBClientConnect ion even when If autoReconnect is true, you can try to use the DBClientConnect ion even when
skipping to change at line 1275 skipping to change at line 1279
protected: protected:
friend class SyncClusterConnection; friend class SyncClusterConnection;
virtual void _auth(const BSONObj& params); virtual void _auth(const BSONObj& params);
virtual void sayPiggyBack( Message &toSend ); virtual void sayPiggyBack( Message &toSend );
DBClientReplicaSet *clientSet; DBClientReplicaSet *clientSet;
boost::scoped_ptr<MessagingPort> p; boost::scoped_ptr<MessagingPort> p;
boost::scoped_ptr<SockAddr> server; boost::scoped_ptr<SockAddr> server;
bool _failed; bool _failed;
const bool autoReconnect; const bool autoReconnect;
time_t lastReconnectTry; Backoff autoReconnectBackoff;
HostAndPort _server; // remember for reconnects HostAndPort _server; // remember for reconnects
string _serverString; string _serverString;
void _checkConnection(); void _checkConnection();
// throws SocketException if in failed state and not reconnecting o r if waiting to reconnect // throws SocketException if in failed state and not reconnecting o r if waiting to reconnect
void checkConnection() { if( _failed ) _checkConnection(); } void checkConnection() { if( _failed ) _checkConnection(); }
map<string, BSONObj> authCache; map<string, BSONObj> authCache;
double _so_timeout; double _so_timeout;
bool _connect( string& errmsg ); bool _connect( string& errmsg );
 End of changes. 4 change blocks. 
4 lines changed or deleted 10 lines changed or added


 dbclientmockcursor.h   dbclientmockcursor.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 "dbclientcursor.h" #include "mongo/client/dbclientcursor.h"
namespace mongo { namespace mongo {
class DBClientMockCursor : public DBClientCursorInterface { class DBClientMockCursor : public DBClientCursorInterface {
public: public:
DBClientMockCursor( const BSONArray& mockCollection ) : _iter( mock Collection ) {} DBClientMockCursor( const BSONArray& mockCollection ) : _iter( mock Collection ) {}
virtual ~DBClientMockCursor() {} virtual ~DBClientMockCursor() {}
bool more() { return _iter.more(); } bool more() { return _iter.more(); }
BSONObj next() { return _iter.next().Obj(); } BSONObj next() { return _iter.next().Obj(); }
 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 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/bson/bson_validate.h" #include "mongo/bson/bson_validate.h"
#include "mongo/client/constants.h" #include "mongo/client/constants.h"
#include "mongo/db/instance.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/util/net/message.h" #include "mongo/util/net/message.h"
#include "mongo/util/net/message_port.h"
namespace mongo { namespace mongo {
/* db response format /* db response format
Query or GetMore: // see struct QueryResult Query or GetMore: // see struct QueryResult
int resultFlags; int resultFlags;
int64 cursorID; int64 cursorID;
int startingFrom; int startingFrom;
int nReturned; int nReturned;
skipping to change at line 131 skipping to change at line 131
/** the 32 bit field before the ns /** the 32 bit field before the ns
* track all bit usage here as its cross op * track all bit usage here as its cross op
* 0: InsertOption_ContinueOnError * 0: InsertOption_ContinueOnError
* 1: fromWriteback * 1: fromWriteback
*/ */
int& reservedField() { return *reserved; } int& reservedField() { return *reserved; }
const char * getns() const { const char * getns() const {
return data; return data;
} }
void getns(Namespace& ns) const {
ns = data;
}
const char * afterNS() const { const char * afterNS() const {
return data + strlen( data ) + 1; return data + strlen( data ) + 1;
} }
int getInt( int num ) const { int getInt( int num ) const {
const int * foo = (const int*)afterNS(); const int * foo = (const int*)afterNS();
return foo[num]; return foo[num];
} }
skipping to change at line 268 skipping to change at line 265
ntoskip = d.pullInt(); ntoskip = d.pullInt();
ntoreturn = d.pullInt(); ntoreturn = d.pullInt();
query = d.nextJsObj(); query = d.nextJsObj();
if ( d.moreJSObjs() ) { if ( d.moreJSObjs() ) {
fields = d.nextJsObj(); fields = d.nextJsObj();
} }
queryOptions = d.msg().header()->dataAsInt(); queryOptions = d.msg().header()->dataAsInt();
} }
}; };
/**
* A response to a DbMessage.
*/
struct DbResponse {
Message *response;
MSGID responseTo;
string exhaustNS; /* points to ns if exhaust mode. 0=normal mode*/
DbResponse(Message *r, MSGID rt) : response(r), responseTo(rt){ }
DbResponse() {
response = 0;
}
~DbResponse() { delete response; }
};
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,
 End of changes. 4 change blocks. 
4 lines changed or deleted 15 lines changed or added


 diskloc.h   diskloc.h 
skipping to change at line 34 skipping to change at line 34
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/platform/cstdint.h" #include "mongo/platform/cstdint.h"
#include "mongo/platform/unordered_set.h" #include "mongo/platform/unordered_set.h"
namespace mongo { namespace mongo {
class Record; class Record;
class DeletedRecord; class DeletedRecord;
class Extent; class Extent;
class MongoDataFile; class DataFile;
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 {
skipping to change at line 78 skipping to change at line 78
return ofs < -1 || return ofs < -1 ||
_a < -1 || _a < -1 ||
_a > 524288; _a > 524288;
} }
bool isNull() const { return _a == -1; } bool isNull() const { return _a == -1; }
void Null() { void Null() {
_a = -1; _a = -1;
ofs = 0; /* note NullOfs is different. todo clean up. see refs to NullOfs in code - use is valid but outside DiskLoc context so confusing as-is. */ ofs = 0; /* note NullOfs is different. todo clean up. see refs to NullOfs in code - use is valid but outside DiskLoc context so confusing as-is. */
} }
void assertOk() { verify(!isNull()); } void assertOk() const { verify(!isNull()); }
void setInvalid() { void setInvalid() {
_a = -2; _a = -2;
ofs = 0; ofs = 0;
} }
bool isValid() const { return _a != -2; } bool isValid() const { return _a != -2; }
string toString() const { string toString() const {
if ( isNull() ) if ( isNull() )
return "null"; return "null";
stringstream ss; stringstream ss;
skipping to change at line 167 skipping to change at line 167
DeletedRecord* drec() const; DeletedRecord* drec() const;
Extent* ext() const; Extent* ext() const;
template< class V > template< class V >
const BtreeBucket<V> * btree() const; const BtreeBucket<V> * btree() const;
// Explicitly signals we are writing and casts away const // Explicitly signals we are writing and casts away const
template< class V > template< class V >
BtreeBucket<V> * btreemod() const; BtreeBucket<V> * btreemod() const;
/*MongoDataFile& pdf() const;*/ /*DataFile& pdf() const;*/
/// members for Sorter /// members for Sorter
struct SorterDeserializeSettings {}; // unused struct SorterDeserializeSettings {}; // unused
void serializeForSorter(BufBuilder& buf) const { buf.appendStruct(* this); } void serializeForSorter(BufBuilder& buf) const { buf.appendStruct(* this); }
static DiskLoc deserializeForSorter(BufReader& buf, const SorterDes erializeSettings&) { static DiskLoc deserializeForSorter(BufReader& buf, const SorterDes erializeSettings&) {
return buf.read<DiskLoc>(); return buf.read<DiskLoc>();
} }
int memUsageForSorter() const { return sizeof(DiskLoc); } int memUsageForSorter() const { return sizeof(DiskLoc); }
DiskLoc getOwned() const { return *this; } DiskLoc getOwned() const { return *this; }
}; };
 End of changes. 3 change blocks. 
3 lines changed or deleted 3 lines changed or added


 distlock.h   distlock.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 "mongo/pch.h" #include "mongo/pch.h"
#include "connpool.h" #include "mongo/client/connpool.h"
#include "syncclusterconnection.h" #include "mongo/client/syncclusterconnection.h"
#define LOCK_TIMEOUT (15 * 60 * 1000) #define LOCK_TIMEOUT (15 * 60 * 1000)
#define LOCK_SKEW_FACTOR (30) #define LOCK_SKEW_FACTOR (30)
#define LOCK_PING (LOCK_TIMEOUT / LOCK_SKEW_FACTOR) #define LOCK_PING (LOCK_TIMEOUT / LOCK_SKEW_FACTOR)
#define MAX_LOCK_NET_SKEW (LOCK_TIMEOUT / LOCK_SKEW_FACTOR) #define MAX_LOCK_NET_SKEW (LOCK_TIMEOUT / LOCK_SKEW_FACTOR)
#define MAX_LOCK_CLOCK_SKEW (LOCK_TIMEOUT / LOCK_SKEW_FACTOR) #define MAX_LOCK_CLOCK_SKEW (LOCK_TIMEOUT / LOCK_SKEW_FACTOR)
#define NUM_LOCK_SKEW_CHECKS (3) #define NUM_LOCK_SKEW_CHECKS (3)
// The maximum clock skew we need to handle between config servers is // The maximum clock skew we need to handle between config servers is
// 2 * MAX_LOCK_NET_SKEW + MAX_LOCK_CLOCK_SKEW. // 2 * MAX_LOCK_NET_SKEW + MAX_LOCK_CLOCK_SKEW.
 End of changes. 1 change blocks. 
2 lines changed or deleted 2 lines changed or added


 document.h   document.h 
skipping to change at line 126 skipping to change at line 126
/** Calculate a hash value. /** Calculate a hash value.
* *
* Meant to be used to create composite hashes suitable for * Meant to be used to create composite hashes suitable for
* hashed container classes such as unordered_map. * hashed container classes such as unordered_map.
*/ */
void hash_combine(size_t &seed) const; void hash_combine(size_t &seed) const;
/// Add this document to the BSONObj under construction with the gi ven BSONObjBuilder. /// Add this document to the BSONObj under construction with the gi ven BSONObjBuilder.
void toBson(BSONObjBuilder *pBsonObjBuilder) const; void toBson(BSONObjBuilder *pBsonObjBuilder) const;
BSONObj toBson() const;
// Support BSONObjBuilder and BSONArrayBuilder "stream" API // Support BSONObjBuilder and BSONArrayBuilder "stream" API
friend BSONObjBuilder& operator << (BSONObjBuilderValueStream& buil der, const Document& d); friend BSONObjBuilder& operator << (BSONObjBuilderValueStream& buil der, const Document& d);
/** Return the abstract Position of a field, suitable to pass to op erator[] or getField(). /** Return the abstract Position of a field, suitable to pass to op erator[] or getField().
* This can potentially save time if you need to refer to a field multiple times. * This can potentially save time if you need to refer to a field multiple times.
*/ */
Position positionOf(StringData fieldName) const { return storage(). findField(fieldName); } Position positionOf(StringData fieldName) const { return storage(). findField(fieldName); }
/** Clone a document. /** Clone a document.
skipping to change at line 152 skipping to change at line 153
*/ */
Document clone() const { return Document(storage().clone().get()); } Document clone() const { return Document(storage().clone().get()); }
/// members for Sorter /// members for Sorter
struct SorterDeserializeSettings {}; // unused struct SorterDeserializeSettings {}; // unused
void serializeForSorter(BufBuilder& buf) const; void serializeForSorter(BufBuilder& buf) const;
static Document deserializeForSorter(BufReader& buf, const SorterDe serializeSettings&); static Document deserializeForSorter(BufReader& buf, const SorterDe serializeSettings&);
int memUsageForSorter() const { return getApproximateSize(); } int memUsageForSorter() const { return getApproximateSize(); }
Document getOwned() const { return *this; } Document getOwned() const { return *this; }
// TEMP for compatibility with legacy intrusive_ptr<Document> /// only for testing
Document& operator*() { return *this; }
const Document& operator*() const { return *this; }
Document* operator->() { return this; }
const Document* operator->() const { return this; }
const void* getPtr() const { return _storage.get(); } const void* getPtr() const { return _storage.get(); }
void reset() { return _storage.reset(); }
static Document createFromBsonObj(BSONObj* pBsonObj) { return Docum
ent(*pBsonObj); }
size_t getFieldCount() const { return size(); }
Value getValue(StringData fieldName) const { return getField(fieldN
ame); }
// TODO: replace with logical equality once all current usages are
fixed
bool operator== (const Document& lhs) const { return _storage == lh
s._storage; }
explicit Document(const DocumentStorage* ptr) : _storage(ptr) {};
private: private:
friend class FieldIterator; friend class FieldIterator;
friend class ValueStorage; friend class ValueStorage;
friend class MutableDocument; friend class MutableDocument;
friend class MutableValue;
explicit Document(const DocumentStorage* ptr) : _storage(ptr) {};
const DocumentStorage& storage() const { const DocumentStorage& storage() const {
return (_storage ? *_storage : DocumentStorage::emptyDoc()); return (_storage ? *_storage : DocumentStorage::emptyDoc());
} }
intrusive_ptr<const DocumentStorage> _storage; intrusive_ptr<const DocumentStorage> _storage;
}; };
inline bool operator== (const Document& l, const Document& r) {
return Document::compare(l, r) == 0;
}
inline bool operator!= (const Document& l, const Document& r) {
return Document::compare(l, r) != 0;
}
inline bool operator< (const Document& l, const Document& r) {
return Document::compare(l, r) < 0;
}
inline bool operator<= (const Document& l, const Document& r) {
return Document::compare(l, r) <= 0;
}
inline bool operator> (const Document& l, const Document& r) {
return Document::compare(l, r) > 0;
}
inline bool operator>= (const Document& l, const Document& r) {
return Document::compare(l, r) >= 0;
}
/** This class is returned by MutableDocument to allow you to modify it s values. /** This class is returned by MutableDocument to allow you to modify it s values.
* You are not allowed to hold variables of this type (enforced by the type system). * You are not allowed to hold variables of this type (enforced by the type system).
*/ */
class MutableValue { class MutableValue {
public: public:
void operator= (const Value& v) { _val = v; } void operator= (const Value& v) { _val = v; }
/** These are designed to allow things like mutDoc["a"]["b"]["c"] = Value(10); /** These are designed to allow things like mutDoc["a"]["b"]["c"] = Value(10);
* It is safe to use even on nonexistent fields. * It is safe to use even on nonexistent fields.
*/ */
skipping to change at line 204 skipping to change at line 214
private: private:
friend class MutableDocument; friend class MutableDocument;
/// can only be constructed or copied by self and friends /// can only be constructed or copied by self and friends
MutableValue(const MutableValue& other): _val(other._val) {} MutableValue(const MutableValue& other): _val(other._val) {}
explicit MutableValue(Value& val): _val(val) {} explicit MutableValue(Value& val): _val(val) {}
/// Used by MutableDocument(MutableValue) /// Used by MutableDocument(MutableValue)
const RefCountable*& getDocPtr() { const RefCountable*& getDocPtr() {
if (_val.getType() != Object) if (_val.getType() != Object || _val._storage.genericRCPtr == N
*this = Value(Document()); ULL) {
// If the current value isn't an object we replace it with
a Object-typed Value.
// Note that we can't just use Document() here because that
is a NULL pointer and
// Value doesn't refcount NULL pointers. This led to a memo
ry leak (SERVER-10554)
// because MutableDocument::newStorage() would set a non-NU
LL pointer into the Value
// without setting the refCounter bit. While allocating a D
ocumentStorage here could
// result in an allocation where none is needed, in practic
e this is only called
// when we are about to add a field to the sub-document so
this just changes where
// the allocation is done.
_val = Value(Document(new DocumentStorage()));
}
return _val._storage.genericRCPtr; return _val._storage.genericRCPtr;
} }
MutableValue& operator= (const MutableValue&); // not assignable wi th another MutableValue MutableValue& operator= (const MutableValue&); // not assignable wi th another MutableValue
Value& _val; Value& _val;
}; };
/** MutableDocument is a Document builder that supports both adding and updating fields. /** MutableDocument is a Document builder that supports both adding and updating fields.
 End of changes. 6 change blocks. 
20 lines changed or deleted 43 lines changed or added


 document_source.h   document_source.h 
skipping to change at line 21 skipping to change at line 21
* 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 License * You should have received a copy of the GNU Affero General Public License
* 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 <boost/optional.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <deque>
#include "mongo/db/clientcursor.h" #include "mongo/db/clientcursor.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/matcher.h" #include "mongo/db/matcher.h"
#include "mongo/db/pipeline/document.h" #include "mongo/db/pipeline/document.h"
#include "mongo/db/pipeline/expression_context.h" #include "mongo/db/pipeline/expression_context.h"
#include "mongo/db/pipeline/expression.h" #include "mongo/db/pipeline/expression.h"
#include "mongo/db/pipeline/value.h" #include "mongo/db/pipeline/value.h"
#include "mongo/db/projection.h" #include "mongo/db/projection.h"
#include "mongo/db/sorter/sorter.h" #include "mongo/db/sorter/sorter.h"
#include "mongo/s/shard.h" #include "mongo/s/shard.h"
#include "mongo/s/strategy.h"
#include "mongo/util/intrusive_counter.h" #include "mongo/util/intrusive_counter.h"
namespace mongo { namespace mongo {
class Accumulator; class Accumulator;
class Cursor; class Cursor;
class Document; class Document;
class Expression; class Expression;
class ExpressionContext;
class ExpressionFieldPath; class ExpressionFieldPath;
class ExpressionObject; class ExpressionObject;
class DocumentSourceLimit; class DocumentSourceLimit;
class DocumentSource : public IntrusiveCounterUnsigned { class DocumentSource : public IntrusiveCounterUnsigned {
public: public:
virtual ~DocumentSource(); virtual ~DocumentSource() {}
/** /**
Set the step for a user-specified pipeline step. Set the step for a user-specified pipeline step.
The step is used for diagnostics. The step is used for diagnostics.
@param step step number 0 to n. @param step step number 0 to n.
*/ */
void setPipelineStep(int step); void setPipelineStep(int step);
/** /**
Get the user-specified pipeline step. Get the user-specified pipeline step.
@returns the step number, or -1 if it has never been set @returns the step number, or -1 if it has never been set
*/ */
int getPipelineStep() const; int getPipelineStep() const;
/** /** Returns the next Document if there is one or boost::none if at
Is the source at EOF? EOF.
* Subclasses must call pExpCtx->checkForInterupt().
@returns true if the source has no more Documents to return.
*/
virtual bool eof() = 0;
/**
Advance the state of the DocumentSource so that it will return th
e
next Document.
The default implementation returns false, after checking for
interrupts. Derived classes can call the default implementation
in their own implementations in order to check for interrupts.
@returns whether there is another document to fetch, i.e., whethe
r or
not getCurrent() will succeed. This default implementation alw
ays
returns false.
*/
virtual bool advance();
/** @returns the current Document without advancing.
*
* It is illegal to call this without first checking eof() == fals
e or advance() == true.
*
* While it is legal to call getCurrent() multiple times between c
alls to advance, and
* you will get the same Document returned, some DocumentSources d
o expensive work in
* getCurrent(). You are advised to cache the result if you plan t
o access it more than
* once.
*/ */
virtual Document getCurrent() = 0; virtual boost::optional<Document> getNext() = 0;
/** /**
* Inform the source that it is no longer needed and may release it s resources. After * Inform the source that it is no longer needed and may release it s resources. After
* dispose() is called the source must still be able to handle iter ation requests, but may * dispose() is called the source must still be able to handle iter ation requests, but may
* become eof(). * become eof().
* NOTE: For proper mutex yielding, dispose() must be called on any DocumentSource that will * NOTE: For proper mutex yielding, dispose() must be called on any DocumentSource that will
* not be advanced until eof(), see SERVER-6123. * not be advanced until eof(), see SERVER-6123.
*/ */
virtual void dispose(); virtual void dispose();
skipping to change at line 201 skipping to change at line 176
array being built here. array being built here.
A subclass may choose to overwrite this rather than addToBsonArra y A subclass may choose to overwrite this rather than addToBsonArra y
if it should output multiple stages. if it should output multiple stages.
@param pBuilder the array builder to add the operation to. @param pBuilder the array builder to add the operation to.
@param explain create explain output @param explain create explain output
*/ */
virtual void addToBsonArray(BSONArrayBuilder *pBuilder, bool explai n=false) const; virtual void addToBsonArray(BSONArrayBuilder *pBuilder, bool explai n=false) const;
/// Returns true if doesn't require an input source (most DocumentS
ources do).
virtual bool isValidInitialSource() const { return false; }
protected: protected:
/** /**
Base constructor. Base constructor.
*/ */
DocumentSource(const intrusive_ptr<ExpressionContext> &pExpCtx); DocumentSource(const intrusive_ptr<ExpressionContext> &pExpCtx);
/** /**
Create an object that represents the document source. The object Create an object that represents the document source. The object
will have a single field whose name is the source's name. This will have a single field whose name is the source's name. This
will be used by the default implementation of addToBsonArray() will be used by the default implementation of addToBsonArray()
skipping to change at line 248 skipping to change at line 226
/* /*
for explain: # of rows returned by this source for explain: # of rows returned by this source
This is *not* unsigned so it can be passed to BSONObjBuilder.appe nd(). This is *not* unsigned so it can be passed to BSONObjBuilder.appe nd().
*/ */
long long nRowsOut; long long nRowsOut;
}; };
/** This class marks DocumentSources that should be split between the r outer and the shards /** This class marks DocumentSources that should be split between the r outer and the shards
* See Pipeline::splitForSharded() for details * See Pipeline::splitForSharded() for details
*
* TODO inheriting from DocumentSource here was a mistake. It should b
e separate.
*/ */
class SplittableDocumentSource : public DocumentSource { class SplittableDocumentSource : public DocumentSource {
public: public:
/** returns a source to be run on the shards. /** returns a source to be run on the shards.
* if NULL, don't run on shards * if NULL, don't run on shards
*/ */
virtual intrusive_ptr<DocumentSource> getShardSource() = 0; virtual intrusive_ptr<DocumentSource> getShardSource() = 0;
/** returns a source that combines results from shards. /** returns a source that combines results from shards.
* if NULL, don't run on router * if NULL, don't run on router
*/ */
virtual intrusive_ptr<DocumentSource> getRouterSource() = 0; virtual intrusive_ptr<DocumentSource> getRouterSource() = 0;
protected: protected:
SplittableDocumentSource(intrusive_ptr<ExpressionContext> ctx) :Doc umentSource(ctx) {} SplittableDocumentSource(intrusive_ptr<ExpressionContext> ctx) :Doc umentSource(ctx) {}
}; };
/** This class marks DocumentSources which need mongod-specific functio
nality.
* It causes a MongodInterface to be injected when in a mongod and pre
vents mongos from
* merging pipelines containing this stage.
*/
class DocumentSourceNeedsMongod {
public:
// Wraps mongod-specific functions to allow linking into mongos.
class MongodInterface {
public:
virtual ~MongodInterface() {};
virtual DBClientBase* directClient() = 0; // Always returns a D
BDirectClient
// Note that in some rare cases this could return a false negat
ive but will never return
// a false positive. This method will be fixed in the future on
ce it becomes possible to
// avoid false negatives.
virtual bool isSharded(const NamespaceString& ns) = 0;
// Add new methods as needed.
};
void injectMongodInterface(boost::shared_ptr<MongodInterface> mongo
d) {
_mongod = mongod;
}
protected:
// It is invalid to delete through a DocumentSourceNeedsMongod-type
d pointer.
virtual ~DocumentSourceNeedsMongod() {}
// Gives subclasses access to a MongodInterface implementation
shared_ptr<MongodInterface> _mongod;
};
class DocumentSourceBsonArray : class DocumentSourceBsonArray :
public DocumentSource { public DocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceBsonArray(); virtual boost::optional<Document> getNext();
virtual bool eof();
virtual bool advance();
virtual Document getCurrent();
virtual void setSource(DocumentSource *pSource); virtual void setSource(DocumentSource *pSource);
virtual bool isValidInitialSource() const { return true; }
/** /**
Create a document source based on a BSON array. Create a document source based on a BSON array.
This is usually put at the beginning of a chain of document sourc es This is usually put at the beginning of a chain of document sourc es
in order to fetch data from the database. in order to fetch data from the database.
CAUTION: the BSON is not read until the source is used. Any CAUTION: the BSON is not read until the source is used. Any
elements that appear after these documents must not be read until elements that appear after these documents must not be read until
this source is exhausted. this source is exhausted.
skipping to change at line 302 skipping to change at line 313
protected: protected:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst; virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst;
private: private:
DocumentSourceBsonArray(BSONElement *pBsonElement, DocumentSourceBsonArray(BSONElement *pBsonElement,
const intrusive_ptr<ExpressionContext> &pExpCtx); const intrusive_ptr<ExpressionContext> &pExpCtx);
BSONObj embeddedObject; BSONObj embeddedObject;
BSONObjIterator arrayIterator; BSONObjIterator arrayIterator;
BSONElement currentElement;
bool haveCurrent;
}; };
class DocumentSourceCommandShards : class DocumentSourceCommandShards :
public DocumentSource { public DocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceCommandShards(); virtual boost::optional<Document> getNext();
virtual bool eof();
virtual bool advance();
virtual Document getCurrent();
virtual void setSource(DocumentSource *pSource); virtual void setSource(DocumentSource *pSource);
virtual bool isValidInitialSource() const { return true; }
/* convenient shorthand for a commonly used type */ /* convenient shorthand for a commonly used type */
typedef map<Shard, BSONObj> ShardOutput; typedef vector<Strategy::CommandResult> ShardOutput;
/** /**
Create a DocumentSource that wraps the output of many shards Create a DocumentSource that wraps the output of many shards
@param shardOutput output from the individual shards @param shardOutput output from the individual shards
@param pExpCtx the expression context for the pipeline @param pExpCtx the expression context for the pipeline
@returns the newly created DocumentSource @returns the newly created DocumentSource
*/ */
static intrusive_ptr<DocumentSourceCommandShards> create( static intrusive_ptr<DocumentSourceCommandShards> create(
const ShardOutput& shardOutput, const ShardOutput& shardOutput,
skipping to change at line 365 skipping to change at line 372
/** /**
* Constructs and returns Documents from the BSONObj objects produced b y a supplied Cursor. * Constructs and returns Documents from the BSONObj objects produced b y a supplied Cursor.
* An object of this type may only be used by one thread, see SERVER-61 23. * An object of this type may only be used by one thread, see SERVER-61 23.
*/ */
class DocumentSourceCursor : class DocumentSourceCursor :
public DocumentSource { public DocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceCursor(); virtual ~DocumentSourceCursor();
virtual bool eof(); virtual boost::optional<Document> getNext();
virtual bool advance();
virtual Document getCurrent();
virtual void setSource(DocumentSource *pSource); virtual void setSource(DocumentSource *pSource);
virtual bool coalesce(const intrusive_ptr<DocumentSource>& nextSour
ce);
virtual bool isValidInitialSource() const { return true; }
/** /**
* Release the Cursor and the read lock it requires, but without ch anging the other data. * Release the Cursor and the read lock it requires, but without ch anging the other data.
* Releasing the lock is required for proper concurrency, see SERVE R-6123. This * Releasing the lock is required for proper concurrency, see SERVE R-6123. This
* functionality is also used by the explain version of pipeline ex ecution. * functionality is also used by the explain version of pipeline ex ecution.
*/ */
virtual void dispose(); virtual void dispose();
/** /**
* Create a document source based on a passed-in cursor. * Create a document source based on a passed-in cursor.
skipping to change at line 429 skipping to change at line 436
This should be captured after any optimizations are applied to This should be captured after any optimizations are applied to
the pipeline so that it reflects what is really used. the pipeline so that it reflects what is really used.
This gets used for explain output. This gets used for explain output.
@param pBsonObj the sort to record @param pBsonObj the sort to record
*/ */
void setSort(const BSONObj& sort) { _sort = sort; } void setSort(const BSONObj& sort) { _sort = sort; }
void setProjection(const BSONObj& projection, const ParsedDeps& dep s); void setProjection(const BSONObj& projection, const ParsedDeps& dep s);
/// returns -1 for no limit
long long getLimit() const;
protected: protected:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst; virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst;
private: private:
DocumentSourceCursor( DocumentSourceCursor(
const string& ns, const string& ns,
CursorId cursorId, CursorId cursorId,
const intrusive_ptr<ExpressionContext> &pExpCtx); const intrusive_ptr<ExpressionContext> &pExpCtx);
void findNext(); void loadBatch();
bool unstarted; std::deque<Document> _currentBatch;
bool hasCurrent;
Document pCurrent;
// BSONObj members must outlive _projection and cursor. // BSONObj members must outlive _projection and cursor.
BSONObj _query; BSONObj _query;
BSONObj _sort; BSONObj _sort;
shared_ptr<Projection> _projection; // shared with pClientCursor shared_ptr<Projection> _projection; // shared with pClientCursor
ParsedDeps _dependencies; ParsedDeps _dependencies;
intrusive_ptr<DocumentSourceLimit> _limit;
long long _docsAddedToBatches; // for _limit enforcement
string ns; // namespace string ns; // namespace
CursorId _cursorId; CursorId _cursorId;
CollectionMetadataPtr _collMetadata; CollectionMetadataPtr _collMetadata;
bool canUseCoveredIndex(ClientCursor* cursor); bool canUseCoveredIndex(ClientCursor* cursor);
/* /*
Yield the cursor sometimes. Yield the cursor sometimes.
skipping to change at line 478 skipping to change at line 488
/* /*
This contains all the basic mechanics for filtering a stream of This contains all the basic mechanics for filtering a stream of
Documents, except for the actual predicate evaluation itself. This w as Documents, except for the actual predicate evaluation itself. This w as
factored out so we could create DocumentSources that use both Matcher factored out so we could create DocumentSources that use both Matcher
style predicates as well as full Expressions. style predicates as well as full Expressions.
*/ */
class DocumentSourceFilterBase : class DocumentSourceFilterBase :
public DocumentSource { public DocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceFilterBase(); virtual boost::optional<Document> getNext();
virtual bool eof();
virtual bool advance();
virtual Document getCurrent();
/** /**
Create a BSONObj suitable for Matcher construction. Create a BSONObj suitable for Matcher construction.
This is used after filter analysis has moved as many filters to This is used after filter analysis has moved as many filters to
as early a point as possible in the document processing pipeline. as early a point as possible in the document processing pipeline.
See db/Matcher.h and the associated documentation for the format. See db/Matcher.h and the associated documentation for the format.
This conversion is used to move back to the low-level find() This conversion is used to move back to the low-level find()
Cursor mechanism. Cursor mechanism.
skipping to change at line 510 skipping to change at line 517
/** /**
Test the given document against the predicate and report if it Test the given document against the predicate and report if it
should be accepted or not. should be accepted or not.
@param pDocument the document to test @param pDocument the document to test
@returns true if the document matches the filter, false otherwise @returns true if the document matches the filter, false otherwise
*/ */
virtual bool accept(const Document& pDocument) const = 0; virtual bool accept(const Document& pDocument) const = 0;
private: private:
void findNext();
bool unstarted; bool unstarted;
bool hasCurrent;
Document pCurrent;
};
class DocumentSourceFilter :
public DocumentSourceFilterBase {
public:
// virtuals from DocumentSource
virtual ~DocumentSourceFilter();
virtual bool coalesce(const intrusive_ptr<DocumentSource> &pNextSou
rce);
virtual void optimize();
virtual const char *getSourceName() const;
/**
Create a filter.
@param pBsonElement the raw BSON specification for the filter
@param pExpCtx the expression context for the pipeline
@returns the filter
*/
static intrusive_ptr<DocumentSource> createFromBson(
BSONElement *pBsonElement,
const intrusive_ptr<ExpressionContext> &pExpCtx);
/**
Create a filter.
@param pFilter the expression to use to filter
@param pExpCtx the expression context for the pipeline
@returns the filter
*/
static intrusive_ptr<DocumentSourceFilter> create(
const intrusive_ptr<Expression> &pFilter,
const intrusive_ptr<ExpressionContext> &pExpCtx);
/**
Create a BSONObj suitable for Matcher construction.
This is used after filter analysis has moved as many filters to
as early a point as possible in the document processing pipeline.
See db/Matcher.h and the associated documentation for the format.
This conversion is used to move back to the low-level find()
Cursor mechanism.
@param pBuilder the builder to write to
*/
void toMatcherBson(BSONObjBuilder *pBuilder) const;
static const char filterName[];
protected:
// virtuals from DocumentSource
virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c
onst;
// virtuals from DocumentSourceFilterBase
virtual bool accept(const Document& pDocument) const;
private:
DocumentSourceFilter(const intrusive_ptr<Expression> &pFilter,
const intrusive_ptr<ExpressionContext> &pExpCt
x);
intrusive_ptr<Expression> pFilter;
}; };
class DocumentSourceGroup : class DocumentSourceGroup :
public SplittableDocumentSource { public SplittableDocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceGroup(); virtual boost::optional<Document> getNext();
virtual bool eof();
virtual bool advance();
virtual const char *getSourceName() const; virtual const char *getSourceName() const;
virtual Document getCurrent();
virtual GetDepsReturn getDependencies(set<string>& deps) const; virtual GetDepsReturn getDependencies(set<string>& deps) const;
virtual void dispose(); virtual void dispose();
/** /**
Create a new grouping DocumentSource. Create a new grouping 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<DocumentSourceGroup> create( static intrusive_ptr<DocumentSourceGroup> create(
skipping to change at line 626 skipping to change at line 565
@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(const std::string& fieldName, void addAccumulator(const std::string& fieldName,
intrusive_ptr<Accumulator> (*pAccumulatorFactor y)(), intrusive_ptr<Accumulator> (*pAccumulatorFactor y)(),
const intrusive_ptr<Expression> &pExpression); const intrusive_ptr<Expression> &pExpression);
/// Tell this source if it is doing a merge from shards. Defaults t
o false.
void setDoingMerge(bool doingMerge) { _doingMerge = doingMerge; }
/** /**
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.
@param pBsonElement the BSONELement that defines the group @param pBsonElement the BSONELement that defines the group
@param pExpCtx the expression context @param pExpCtx the expression context
@returns the grouping DocumentSource @returns the grouping DocumentSource
skipping to change at line 693 skipping to change at line 635
accumulators for each new group. accumulators for each new group.
These three vectors parallel each other. These three vectors parallel each other.
*/ */
vector<string> vFieldName; vector<string> vFieldName;
vector<intrusive_ptr<Accumulator> (*)()> vpAccumulatorFactory; vector<intrusive_ptr<Accumulator> (*)()> vpAccumulatorFactory;
vector<intrusive_ptr<Expression> > vpExpression; vector<intrusive_ptr<Expression> > vpExpression;
Document makeDocument(const Value& id, const Accumulators& accums, bool mergeableOutput); Document makeDocument(const Value& id, const Accumulators& accums, bool mergeableOutput);
bool _doingMerge;
bool _spilled; bool _spilled;
const bool _extSortAllowed; const bool _extSortAllowed;
const int _maxMemoryUsageBytes; const int _maxMemoryUsageBytes;
// only used when !_spilled // only used when !_spilled
GroupsMap::iterator groupsIterator; GroupsMap::iterator groupsIterator;
// only used when _spilled // only used when _spilled
scoped_ptr<Sorter<Value, Value>::Iterator> _sorterIterator; scoped_ptr<Sorter<Value, Value>::Iterator> _sorterIterator;
pair<Value, Value> _firstPartOfNextGroup; pair<Value, Value> _firstPartOfNextGroup;
Value _currentId; Value _currentId;
Accumulators _currentAccumulators; Accumulators _currentAccumulators;
bool _doneAfterNextAdvance;
bool _done;
}; };
class DocumentSourceMatch : class DocumentSourceMatch :
public DocumentSourceFilterBase { public DocumentSourceFilterBase {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceMatch();
virtual const char *getSourceName() const; virtual const char *getSourceName() const;
/** /**
Create a filter. Create a filter.
@param pBsonElement the raw BSON specification for the filter @param pBsonElement the raw BSON specification for the filter
@returns the filter @returns the filter
*/ */
static intrusive_ptr<DocumentSource> createFromBson( static intrusive_ptr<DocumentSource> createFromBson(
BSONElement *pBsonElement, BSONElement *pBsonElement,
skipping to change at line 755 skipping to change at line 695
// virtuals from DocumentSourceFilterBase // virtuals from DocumentSourceFilterBase
virtual bool accept(const Document& pDocument) const; virtual bool accept(const Document& pDocument) const;
private: private:
DocumentSourceMatch(const BSONObj &query, DocumentSourceMatch(const BSONObj &query,
const intrusive_ptr<ExpressionContext> &pExpCtx); const intrusive_ptr<ExpressionContext> &pExpCtx);
Matcher matcher; Matcher matcher;
}; };
class DocumentSourceOut : class DocumentSourceMergeCursors :
public DocumentSource { public DocumentSource {
public: public:
typedef vector<pair<ConnectionString, CursorId> > CursorIds;
// virtuals from DocumentSource
boost::optional<Document> getNext();
virtual void setSource(DocumentSource *pSource);
virtual const char *getSourceName() const;
virtual void dispose();
virtual bool isValidInitialSource() const { return true; }
static intrusive_ptr<DocumentSource> createFromBson(
BSONElement *pBsonElement,
const intrusive_ptr<ExpressionContext> &pExpCtx);
static intrusive_ptr<DocumentSource> create(
const CursorIds& cursorIds,
const intrusive_ptr<ExpressionContext> &pExpCtx);
static const char name[];
protected:
// virtuals from DocumentSource
virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c
onst;
private:
struct CursorAndConnection {
CursorAndConnection(ConnectionString host, NamespaceString ns,
CursorId id);
ScopedDbConnection connection;
DBClientCursor cursor;
};
// using list to enable removing arbitrary elements
typedef list<boost::shared_ptr<CursorAndConnection> > Cursors;
DocumentSourceMergeCursors(
const CursorIds& cursorIds,
const intrusive_ptr<ExpressionContext> &pExpCtx);
// This is the description of cursors to merge.
const CursorIds _cursorIds;
// These are the actual cursors we are merging. Created lazily.
Cursors _cursors;
Cursors::iterator _currentCursor;
bool _unstarted;
};
class DocumentSourceOut : public SplittableDocumentSource
, public DocumentSourceNeedsMongod {
public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceOut(); virtual ~DocumentSourceOut();
virtual bool eof(); virtual boost::optional<Document> getNext();
virtual bool advance();
virtual const char *getSourceName() const; virtual const char *getSourceName() const;
virtual Document getCurrent();
// Virtuals for SplittableDocumentSource
virtual intrusive_ptr<DocumentSource> getShardSource() { return NUL
L; }
virtual intrusive_ptr<DocumentSource> getRouterSource() { return th
is; }
const NamespaceString& getOutputNs() const { return _outputNs; }
/** /**
Create a document source for output and pass-through. Create a document source for output and pass-through.
This can be put anywhere in a pipeline and will store content as This can be put anywhere in a pipeline and will store content as
well as pass it on. well as pass it on.
@param pBsonElement the raw BSON specification for the source @param pBsonElement the raw BSON specification for the source
@param pExpCtx the expression context for the pipeline @param pExpCtx the expression context for the pipeline
@returns the newly created document source @returns the newly created document source
*/ */
static intrusive_ptr<DocumentSourceOut> createFromBson( static intrusive_ptr<DocumentSource> createFromBson(
BSONElement *pBsonElement, BSONElement *pBsonElement,
const intrusive_ptr<ExpressionContext> &pExpCtx); const intrusive_ptr<ExpressionContext> &pExpCtx);
static const char outName[]; static const char outName[];
protected: protected:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst; virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst;
private: private:
DocumentSourceOut(BSONElement *pBsonElement, DocumentSourceOut(const NamespaceString& outputNs,
const intrusive_ptr<ExpressionContext> &pExpCtx); const intrusive_ptr<ExpressionContext> &pExpCtx);
// Sets _tempsNs and prepares it to receive data.
void prepTempCollection();
void spill(DBClientBase* conn, const vector<BSONObj>& toInsert);
bool _done;
NamespaceString _tempNs; // output goes here as it is being process
ed.
const NamespaceString _outputNs; // output will go here after all d
ata is processed.
}; };
class DocumentSourceProject : class DocumentSourceProject :
public DocumentSource { public DocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceProject(); virtual boost::optional<Document> getNext();
virtual bool eof();
virtual bool advance();
virtual const char *getSourceName() const; virtual const char *getSourceName() const;
virtual Document getCurrent();
virtual void optimize(); virtual void optimize();
virtual GetDepsReturn getDependencies(set<string>& deps) const; virtual GetDepsReturn getDependencies(set<string>& deps) const;
/** /**
Create a new projection DocumentSource from BSON. Create a new projection DocumentSource from BSON.
This is a convenience for directly handling BSON, and relies on t he This is a convenience for directly handling BSON, and relies on t he
above methods. above methods.
skipping to change at line 840 skipping to change at line 841
// configuration state // configuration state
intrusive_ptr<ExpressionObject> pEO; intrusive_ptr<ExpressionObject> pEO;
BSONObj _raw; BSONObj _raw;
#if defined(_DEBUG) #if defined(_DEBUG)
// this is used in DEBUG builds to ensure we are compatible // this is used in DEBUG builds to ensure we are compatible
Projection _simpleProjection; Projection _simpleProjection;
#endif #endif
}; };
class DocumentSourceRedact :
public DocumentSource {
public:
virtual boost::optional<Document> getNext();
virtual const char* getSourceName() const;
virtual void optimize();
static const char redactName[];
static intrusive_ptr<DocumentSource> createFromBson(BSONElement* bs
onElement,
const intrusive_ptr<ExpressionContext>& expCtx);
protected:
virtual void sourceToBson(BSONObjBuilder* pBuilder, bool explain) c
onst;
private:
DocumentSourceRedact(const intrusive_ptr<ExpressionContext>& expCtx
,
const intrusive_ptr<Expression>& previsit);
boost::optional<Document> redactObject(const Variables& in);
Value redactValue(const Variables& vars, const Value& in);
intrusive_ptr<Expression> _expression;
};
class DocumentSourceSort : class DocumentSourceSort :
public SplittableDocumentSource { public SplittableDocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceSort(); virtual boost::optional<Document> getNext();
virtual bool eof();
virtual bool advance();
virtual const char *getSourceName() const; virtual const char *getSourceName() const;
virtual Document getCurrent();
virtual void addToBsonArray(BSONArrayBuilder *pBuilder, bool explai n=false) const; virtual void addToBsonArray(BSONArrayBuilder *pBuilder, bool explai n=false) const;
virtual bool coalesce(const intrusive_ptr<DocumentSource> &pNextSou rce); virtual bool coalesce(const intrusive_ptr<DocumentSource> &pNextSou rce);
virtual void dispose(); virtual void dispose();
virtual GetDepsReturn getDependencies(set<string>& deps) const; virtual GetDepsReturn getDependencies(set<string>& deps) const;
// Virtuals for SplittableDocumentSource // Virtuals for SplittableDocumentSource
// All work for sort is done in router currently if there is no lim it. // All work for sort is done in router currently if there is no lim it.
// If there is a limit, the $sort/$limit combination is performed o n the // If there is a limit, the $sort/$limit combination is performed o n the
// shards, then the results are resorted and limited on mongos // shards, then the results are resorted and limited on mongos
skipping to change at line 954 skipping to change at line 976
int operator()(const MySorter::Data& lhs, const MySorter::Data& rhs) const { int operator()(const MySorter::Data& lhs, const MySorter::Data& rhs) const {
return _source.compare(lhs.first, rhs.first); return _source.compare(lhs.first, rhs.first);
} }
private: private:
const DocumentSourceSort& _source; const DocumentSourceSort& _source;
}; };
intrusive_ptr<DocumentSourceLimit> limitSrc; intrusive_ptr<DocumentSourceLimit> limitSrc;
bool _done; bool _done;
Document _current;
scoped_ptr<MySorter::Iterator> _output; scoped_ptr<MySorter::Iterator> _output;
}; };
class DocumentSourceLimit : class DocumentSourceLimit :
public SplittableDocumentSource { public SplittableDocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceLimit(); virtual boost::optional<Document> getNext();
virtual bool eof();
virtual bool advance();
virtual 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 {
return SEE_NEXT; // This doesn't affect needed fields return SEE_NEXT; // This doesn't affect needed fields
} }
/** /**
Create a new limiting DocumentSource. Create a new limiting DocumentSource.
skipping to change at line 1024 skipping to change at line 1042
long long limit); long long limit);
long long limit; long long limit;
long long count; long long count;
}; };
class DocumentSourceSkip : class DocumentSourceSkip :
public SplittableDocumentSource { public SplittableDocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceSkip(); virtual boost::optional<Document> getNext();
virtual bool eof();
virtual bool advance();
virtual 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 {
return SEE_NEXT; // This doesn't affect needed fields return SEE_NEXT; // This doesn't affect needed fields
} }
/** /**
Create a new skipping DocumentSource. Create a new skipping DocumentSource.
skipping to change at line 1049 skipping to change at line 1064
@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 // Virtuals for SplittableDocumentSource
// Need to run on rounter. Can't run on shards. // Need to run on rounter. Can't run on shards.
virtual intrusive_ptr<DocumentSource> getShardSource() { return NUL L; } virtual intrusive_ptr<DocumentSource> getShardSource() { return NUL L; }
virtual intrusive_ptr<DocumentSource> getRouterSource() { return th is; } virtual intrusive_ptr<DocumentSource> getRouterSource() { return th is; }
long long getSkip() const { return skip; } long long getSkip() const { return _skip; }
void setSkip(long long newSkip) { skip = newSkip; } 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
skipping to change at line 1076 skipping to change at line 1091
static const char skipName[]; static const char skipName[];
protected: protected:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst; virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst;
private: private:
DocumentSourceSkip(const intrusive_ptr<ExpressionContext> &pExpCtx) ; DocumentSourceSkip(const intrusive_ptr<ExpressionContext> &pExpCtx) ;
/* long long _skip;
Skips initial documents. bool _needToSkip;
*/
void skipper();
long long skip;
long long count;
Document pCurrent;
}; };
class DocumentSourceUnwind : class DocumentSourceUnwind :
public DocumentSource { public DocumentSource {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceUnwind(); virtual boost::optional<Document> getNext();
virtual bool eof();
virtual bool advance();
virtual const char *getSourceName() const; virtual const char *getSourceName() const;
virtual Document getCurrent();
virtual GetDepsReturn getDependencies(set<string>& deps) const; virtual GetDepsReturn getDependencies(set<string>& deps) const;
/** /**
Create a new projection DocumentSource from BSON. Create a new projection DocumentSource from BSON.
This is a convenience for directly handling BSON, and relies on t he This is a convenience for directly handling BSON, and relies on t he
above methods. above methods.
@param pBsonElement the BSONElement with an object named $project @param pBsonElement the BSONElement with an object named $project
skipping to change at line 1121 skipping to change at line 1127
static const char unwindName[]; static const char unwindName[];
protected: protected:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst; virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst;
private: private:
DocumentSourceUnwind(const intrusive_ptr<ExpressionContext> &pExpCt x); DocumentSourceUnwind(const intrusive_ptr<ExpressionContext> &pExpCt x);
/**
* Lazily construct the _unwinder and initialize the iterator state
of this DocumentSource.
* To be called by all members that depend on the iterator state.
*/
void lazyInit();
/**
* If the _unwinder is exhausted and the source may be advanced, ad
vance the pSource and
* reset the _unwinder's source document.
*/
void mayAdvanceSource();
/** Specify the field to unwind. */ /** Specify the field to unwind. */
void unwindPath(const FieldPath &fieldPath); void unwindPath(const FieldPath &fieldPath);
// Configuration state. // Configuration state.
scoped_ptr<FieldPath> _unwindPath; scoped_ptr<FieldPath> _unwindPath;
// Iteration state. // Iteration state.
class Unwinder; class Unwinder;
scoped_ptr<Unwinder> _unwinder; scoped_ptr<Unwinder> _unwinder;
}; };
class DocumentSourceGeoNear : public SplittableDocumentSource { class DocumentSourceGeoNear : public SplittableDocumentSource
, public DocumentSourceNeedsMongod {
public: public:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual ~DocumentSourceGeoNear(); virtual boost::optional<Document> getNext();
virtual bool eof();
virtual bool advance();
virtual Document getCurrent();
virtual const char *getSourceName() const; virtual const char *getSourceName() const;
virtual void setSource(DocumentSource *pSource); // errors out sinc e this must be first virtual void setSource(DocumentSource *pSource); // errors out sinc e this must be first
virtual bool coalesce(const intrusive_ptr<DocumentSource> &pNextSou rce); virtual bool coalesce(const intrusive_ptr<DocumentSource> &pNextSou rce);
virtual bool isValidInitialSource() const { return true; }
// Virtuals for SplittableDocumentSource // Virtuals for SplittableDocumentSource
virtual intrusive_ptr<DocumentSource> getShardSource(); virtual intrusive_ptr<DocumentSource> getShardSource();
virtual intrusive_ptr<DocumentSource> getRouterSource(); virtual intrusive_ptr<DocumentSource> getRouterSource();
static intrusive_ptr<DocumentSource> createFromBson( static intrusive_ptr<DocumentSource> createFromBson(
BSONElement *pBsonElement, BSONElement *pBsonElement,
const intrusive_ptr<ExpressionContext> &pCtx); const intrusive_ptr<ExpressionContext> &pCtx);
static char geoNearName[]; static char geoNearName[];
skipping to change at line 1179 skipping to change at line 1172
const intrusive_ptr<ExpressionContext> &pCtx); const intrusive_ptr<ExpressionContext> &pCtx);
protected: protected:
// virtuals from DocumentSource // virtuals from DocumentSource
virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst; virtual void sourceToBson(BSONObjBuilder *pBuilder, bool explain) c onst;
private: private:
DocumentSourceGeoNear(const intrusive_ptr<ExpressionContext> &pExpC tx); DocumentSourceGeoNear(const intrusive_ptr<ExpressionContext> &pExpC tx);
void parseOptions(BSONObj options); void parseOptions(BSONObj options);
BSONObj buildGeoNearCmd(const StringData& collection) const; BSONObj buildGeoNearCmd() const;
void runCommand(); void runCommand();
// These fields describe the command to run. // These fields describe the command to run.
// coords and distanceField are required, rest are optional // coords and distanceField are required, rest are optional
BSONObj coords; // "near" option, but near is a reserved keyword on windows BSONObj coords; // "near" option, but near is a reserved keyword on windows
bool coordsIsArray; bool coordsIsArray;
scoped_ptr<FieldPath> distanceField; // Using scoped_ptr because Fi eldPath can't be empty scoped_ptr<FieldPath> distanceField; // Using scoped_ptr because Fi eldPath can't be empty
long long limit; long long limit;
double maxDistance; double maxDistance;
BSONObj query; BSONObj query;
bool spherical; bool spherical;
double distanceMultiplier; double distanceMultiplier;
scoped_ptr<FieldPath> includeLocs; scoped_ptr<FieldPath> includeLocs;
bool uniqueDocs; bool uniqueDocs;
// These fields are injected by PipelineD. This division of labor a
llows the
// DocumentSourceGeoNear class to be linked into both mongos and mo
ngod while
// allowing it to run a command using DBDirectClient when in mongod
.
string db;
string collection;
boost::scoped_ptr<DBClientWithCommands> client; // either NULL or a
DBDirectClient
friend class PipelineD;
// these fields are used while processing the results // these fields are used while processing the results
BSONObj cmdOutput; BSONObj cmdOutput;
boost::scoped_ptr<BSONObjIterator> resultsIterator; // iterator ove r cmdOutput["results"] boost::scoped_ptr<BSONObjIterator> resultsIterator; // iterator ove r cmdOutput["results"]
Document currentDoc;
bool hasCurrent;
}; };
} }
/* ======================= INLINED IMPLEMENTATIONS ======================== == */ /* ======================= INLINED IMPLEMENTATIONS ======================== == */
namespace mongo { namespace mongo {
inline void DocumentSource::setPipelineStep(int s) { inline void DocumentSource::setPipelineStep(int s) {
step = s; step = s;
} }
 End of changes. 56 change blocks. 
208 lines changed or deleted 196 lines changed or added


 dur.h   dur.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/db/diskloc.h" #include "mongo/db/diskloc.h"
#include "mongo/db/mongommf.h" #include "mongo/db/storage/durable_mapped_file.h"
namespace mongo { namespace mongo {
class NamespaceDetails; class NamespaceDetails;
void mongoAbort(const char *msg); void mongoAbort(const char *msg);
void abort(); // not defined -- use mongoAbort() instead void abort(); // not defined -- use mongoAbort() instead
namespace dur { namespace dur {
skipping to change at line 138 skipping to change at line 138
/** Declare write intent for an int */ /** Declare write intent for an int */
inline int& writingInt(int& d) { return *static_cast<int*>(writ ingPtr( &d, sizeof(d))); } inline int& writingInt(int& d) { return *static_cast<int*>(writ ingPtr( &d, sizeof(d))); }
/** "assume i've already indicated write intent, let me write" /** "assume i've already indicated write intent, let me write"
redeclaration is fine too, but this is faster. redeclaration is fine too, but this is faster.
*/ */
template <typename T> template <typename T>
inline inline
T* alreadyDeclared(T *x) { T* alreadyDeclared(T *x) {
#if defined(_TESTINTENT) #if defined(_TESTINTENT)
return (T*) MongoMMF::switchToPrivateView(x); return (T*) DurableMappedFile::switchToPrivateView(x);
#else #else
return x; return x;
#endif #endif
} }
/** declare intent to write to x for sizeof(*x) */ /** declare intent to write to x for sizeof(*x) */
template <typename T> template <typename T>
inline inline
T* writing(T *x) { T* writing(T *x) {
return (T*) writingPtr(x, sizeof(T)); return (T*) writingPtr(x, sizeof(T));
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 dur_recover.h   dur_recover.h 
skipping to change at line 29 skipping to change at line 29
#pragma once #pragma once
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <list> #include <list>
#include "mongo/db/dur_journalformat.h" #include "mongo/db/dur_journalformat.h"
#include "mongo/util/concurrency/mutex.h" #include "mongo/util/concurrency/mutex.h"
#include "mongo/util/file.h" #include "mongo/util/file.h"
namespace mongo { namespace mongo {
class MongoMMF; class DurableMappedFile;
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 { static class Last {
public: public:
Last(); Last();
MongoMMF* newEntry(const ParsedJournalEntry&, RecoveryJob&) ; DurableMappedFile* newEntry(const ParsedJournalEntry&, Reco veryJob&);
private: private:
MongoMMF *mmf; DurableMappedFile *mmf;
string dbName; string dbName;
int fileNo; int fileNo;
} last; } 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. */
skipping to change at line 65 skipping to change at line 65
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(Last& last, const ParsedJournalEntry& entry); // act ually writes to the file void write(Last& last, const ParsedJournalEntry& entry); // act ually writes to the file
void applyEntry(Last& last, const ParsedJournalEntry& entry, bo ol apply, bool dump); void applyEntry(Last& last, const ParsedJournalEntry& entry, bo 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); DurableMappedFile* getDurableMappedFile(const ParsedJournalEntr y& entry);
list<boost::shared_ptr<MongoMMF> > _mmfs; list<boost::shared_ptr<DurableMappedFile> > _mmfs;
unsigned long long _lastDataSyncedFromLastRun; unsigned long long _lastDataSyncedFromLastRun;
unsigned long long _lastSeqMentionedInConsoleLog; unsigned long long _lastSeqMentionedInConsoleLog;
public: public:
mongo::mutex _mx; // protects _mmfs mongo::mutex _mx; // protects _mmfs
private: private:
bool _recovering; // are we in recovery or WRITETODATAFILES bool _recovering; // are we in recovery or WRITETODATAFILES
static RecoveryJob &_instance; static RecoveryJob &_instance;
}; };
 End of changes. 5 change blocks. 
5 lines changed or deleted 5 lines changed or added


 element-inl.h   element-inl.h 
skipping to change at line 92 skipping to change at line 92
} }
inline bool Element::isValueMinKey() const { inline bool Element::isValueMinKey() const {
return isType(mongo::MinKey); return isType(mongo::MinKey);
} }
inline bool Element::isValueMaxKey() const { inline bool Element::isValueMaxKey() const {
return isType(mongo::MaxKey); return isType(mongo::MaxKey);
} }
inline SafeNum Element::getValueSafeNum() const {
switch (getType()) {
case mongo::NumberInt:
return static_cast<int>(getValueInt());
case mongo::NumberLong:
return static_cast<long long int>(getValueLong());
case mongo::NumberDouble:
return getValueDouble();
default:
verify(false);
}
}
inline Document& Element::getDocument() { inline Document& Element::getDocument() {
return *_doc; return *_doc;
} }
inline const Document& Element::getDocument() const { inline const Document& Element::getDocument() const {
return *_doc; return *_doc;
} }
inline bool Element::isType(BSONType type) const { inline bool Element::isType(BSONType type) const {
return (getType() == type); return (getType() == type);
 End of changes. 1 change blocks. 
13 lines changed or deleted 0 lines changed or added


 element.h   element.h 
skipping to change at line 284 skipping to change at line 284
/** Get the value from a long valued Element. */ /** Get the value from a long valued Element. */
inline int64_t getValueLong() const; inline int64_t getValueLong() const;
/** Returns true if this Element is the min key type. */ /** Returns true if this Element is the min key type. */
inline bool isValueMinKey() const; inline bool isValueMinKey() const;
/** Returns true if this Element is the max key type. */ /** Returns true if this Element is the max key type. */
inline bool isValueMaxKey() const; inline bool isValueMaxKey() const;
/** Returns the numeric value as a SafeNum */ /** Returns the numeric value as a SafeNum */
inline SafeNum getValueSafeNum() const; SafeNum getValueSafeNum() const;
// //
// Comparision API. // Comparision API.
// //
/** Compare this Element with Element 'other'. The two Elements may belong to different /** Compare this Element with Element 'other'. The two Elements may belong to different
* Documents. You should not call this on the root Element of the Document because the * Documents. You should not call this on the root Element of the Document because the
* root Element does not have a field name. Use compareWithBSONObj to handle that * root Element does not have a field name. Use compareWithBSONObj to handle that
* case. * case.
* *
skipping to change at line 544 skipping to change at line 544
friend class ConstElement; friend class ConstElement;
friend bool operator==(const Element&, const Element&); friend bool operator==(const Element&, const Element&);
inline Element(Document* doc, RepIdx repIdx); inline Element(Document* doc, RepIdx repIdx);
Status addChild(Element e, bool front); Status addChild(Element e, bool front);
StringData getValueStringOrSymbol() const; StringData getValueStringOrSymbol() const;
Status setValue(Element* newValue, bool inPlace = false); Status setValue(Element::RepIdx newValueIdx);
template<typename Builder> template<typename Builder>
inline void writeElement(Builder* builder, const StringData* fieldN ame = NULL) const; inline void writeElement(Builder* builder, const StringData* fieldN ame = NULL) const;
template<typename Builder> template<typename Builder>
inline void writeChildren(Builder* builder) const; inline void writeChildren(Builder* builder) const;
Document* _doc; Document* _doc;
RepIdx _repIdx; RepIdx _repIdx;
}; };
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 error_codes.h   error_codes.h 
skipping to change at line 77 skipping to change at line 77
PrivilegeNotFound = 33, PrivilegeNotFound = 33,
CannotBackfillArray = 34, CannotBackfillArray = 34,
UserModificationFailed = 35, UserModificationFailed = 35,
RemoteChangeDetected = 36, RemoteChangeDetected = 36,
FileRenameFailed = 37, FileRenameFailed = 37,
FileNotOpen = 38, FileNotOpen = 38,
FileStreamFailed = 39, FileStreamFailed = 39,
ConflictingUpdateOperators = 40, ConflictingUpdateOperators = 40,
FileAlreadyOpen = 41, FileAlreadyOpen = 41,
LogWriteFailed = 42, LogWriteFailed = 42,
CursorNotFound = 43,
KeyNotFound = 44,
MaxError MaxError
}; };
static const char* errorString(Error err); static const char* errorString(Error err);
/** /**
* Parse an Error from its "name". Returns UnknownError if "name" is unrecognized. * Parse an Error from its "name". Returns UnknownError if "name" is unrecognized.
* *
* NOTE: Also returns UnknownError for the string "UnknownError". * NOTE: Also returns UnknownError for the string "UnknownError".
*/ */
 End of changes. 1 change blocks. 
0 lines changed or deleted 2 lines changed or added


 expression.h   expression.h 
skipping to change at line 48 skipping to change at line 48
// array types // array types
ALL, ELEM_MATCH_OBJECT, ELEM_MATCH_VALUE, SIZE, ALL, ELEM_MATCH_OBJECT, ELEM_MATCH_VALUE, SIZE,
// leaf types // leaf types
LTE, LT, EQ, GT, GTE, REGEX, MOD, EXISTS, MATCH_IN, NIN, LTE, LT, EQ, GT, GTE, REGEX, MOD, EXISTS, MATCH_IN, NIN,
// special types // special types
TYPE_OPERATOR, GEO, WHERE, TYPE_OPERATOR, GEO, WHERE,
// things that maybe shouldn't even be nodes // things that maybe shouldn't even be nodes
ATOMIC, ALWAYS_FALSE ATOMIC, ALWAYS_FALSE,
// Things that we parse but cannot be answered without an index
.
// TODO: Text goes here eventually.
GEO_NEAR,
}; };
MatchExpression( MatchType type ); MatchExpression( MatchType type );
virtual ~MatchExpression(){} virtual ~MatchExpression(){}
/** /**
* determins if the doc matches the expression * determins if the doc matches the expression
* there could be an expression that looks at fields, or the entire doc * there could be an expression that looks at fields, or the entire doc
*/ */
virtual bool matches( const MatchableDocument* doc, MatchDetails* d etails = 0 ) const = 0; virtual bool matches( const MatchableDocument* doc, MatchDetails* d etails = 0 ) const = 0;
skipping to change at line 127 skipping to change at line 131
return false; return false;
} }
virtual void debugString( StringBuilder& debug, int level = 0 ) con st; virtual void debugString( StringBuilder& debug, int level = 0 ) con st;
virtual bool equivalent( const MatchExpression* other ) const { virtual bool equivalent( const MatchExpression* other ) const {
return other->matchType() == ALWAYS_FALSE; return other->matchType() == ALWAYS_FALSE;
} }
}; };
} }
 End of changes. 2 change blocks. 
1 lines changed or deleted 7 lines changed or added


 expression_array.h   expression_array.h 
skipping to change at line 115 skipping to change at line 115
/** /**
* @param e has to be an array * @param e has to be an array
*/ */
virtual bool matchesSingleElement( const BSONElement& e ) const; virtual bool matchesSingleElement( const BSONElement& e ) const;
virtual void debugString( StringBuilder& debug, int level ) const; virtual void debugString( StringBuilder& debug, int level ) const;
virtual bool equivalent( const MatchExpression* other ) const; virtual bool equivalent( const MatchExpression* other ) const;
virtual size_t numChildren() const { return _list.size(); }
virtual const ArrayMatchingMatchExpression* getChild( size_t i ) co
nst { return _list[i]; }
const StringData& path() const { return _path; }
private: private:
bool _allMatch( const BSONObj& anArray ) const; bool _allMatch( const BSONObj& anArray ) const;
StringData _path; StringData _path;
ElementPath _elementPath; ElementPath _elementPath;
std::vector< const ArrayMatchingMatchExpression* > _list; std::vector< const ArrayMatchingMatchExpression* > _list;
}; };
class SizeMatchExpression : public ArrayMatchingMatchExpression { class SizeMatchExpression : public ArrayMatchingMatchExpression {
public: public:
SizeMatchExpression() : ArrayMatchingMatchExpression( SIZE ){} SizeMatchExpression() : ArrayMatchingMatchExpression( SIZE ){}
Status init( const StringData& path, int size ); Status init( const StringData& path, int size );
virtual bool matchesArray( const BSONObj& anArray, MatchDetails* de tails ) const; virtual bool matchesArray( const BSONObj& anArray, MatchDetails* de tails ) const;
virtual void debugString( StringBuilder& debug, int level ) const; virtual void debugString( StringBuilder& debug, int level ) const;
virtual bool equivalent( const MatchExpression* other ) const; virtual bool equivalent( const MatchExpression* other ) const;
int getData() const { return _size; }
private: private:
int _size; // >= 0 real, < 0, nothing will match int _size; // >= 0 real, < 0, nothing will match
}; };
} }
 End of changes. 2 change blocks. 
0 lines changed or deleted 8 lines changed or added


 expression_context.h   expression_context.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 License * You should have received a copy of the GNU Affero General Public License
* 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/db/interrupt_status.h"
#include "mongo/db/namespace_string.h"
#include "util/intrusive_counter.h" #include "mongo/util/intrusive_counter.h"
namespace mongo { namespace mongo {
class InterruptStatus; struct ExpressionContext : public IntrusiveCounterUnsigned {
class ExpressionContext :
public IntrusiveCounterUnsigned {
public: public:
virtual ~ExpressionContext(); ExpressionContext(const InterruptStatus& status, const NamespaceStr
ing& ns)
void setDoingMerge(bool b); : inShard(false)
void setInShard(bool b); , inRouter(false)
void setInRouter(bool b); , extSortAllowed(false)
void setExtSortAllowed(bool b) { extSortAllowed = b; } , interruptStatus(status)
, ns(ns)
bool getDoingMerge() const; {}
bool getInShard() const; /** Used by a pipeline to check for interrupts so that killOp() wor
bool getInRouter() const; ks.
bool getExtSortAllowed() const { return extSortAllowed; } * @throws if the operation has been interrupted
/**
Used by a pipeline to check for interrupts so that killOp() work
s.
@throws if the operation has been interrupted
*/ */
void checkForInterrupt(); void checkForInterrupt() {
// The check could be expensive, at least in relative terms.
ExpressionContext* clone(); RARELY interruptStatus.checkForInterrupt();
}
static ExpressionContext *create(InterruptStatus *pStatus);
private:
ExpressionContext(InterruptStatus *pStatus);
bool doingMerge;
bool inShard; bool inShard;
bool inRouter; bool inRouter;
bool extSortAllowed; bool extSortAllowed;
unsigned intCheckCounter; // interrupt check counter const InterruptStatus& interruptStatus;
InterruptStatus *const pStatus; NamespaceString ns;
}; };
} }
/* ======================= INLINED IMPLEMENTATIONS ========================
== */
namespace mongo {
inline void ExpressionContext::setDoingMerge(bool b) {
doingMerge = b;
}
inline void ExpressionContext::setInShard(bool b) {
inShard = b;
}
inline void ExpressionContext::setInRouter(bool b) {
inRouter = b;
}
inline bool ExpressionContext::getDoingMerge() const {
return doingMerge;
}
inline bool ExpressionContext::getInShard() const {
return inShard;
}
inline bool ExpressionContext::getInRouter() const {
return inRouter;
}
};
 End of changes. 7 change blocks. 
35 lines changed or deleted 21 lines changed or added


 expression_geo.h   expression_geo.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 "mongo/db/geo/geonear.h"
#include "mongo/db/geo/geoquery.h" #include "mongo/db/geo/geoquery.h"
#include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression.h"
#include "mongo/db/matcher/expression_leaf.h" #include "mongo/db/matcher/expression_leaf.h"
namespace mongo { namespace mongo {
class GeoMatchExpression : public LeafMatchExpression { class GeoMatchExpression : public LeafMatchExpression {
public: public:
GeoMatchExpression() : LeafMatchExpression( GEO ){} GeoMatchExpression() : LeafMatchExpression( GEO ){}
virtual ~GeoMatchExpression(){} virtual ~GeoMatchExpression(){}
skipping to change at line 46 skipping to change at line 47
virtual void debugString( StringBuilder& debug, int level = 0 ) con st; virtual void debugString( StringBuilder& debug, int level = 0 ) con st;
virtual bool equivalent( const MatchExpression* other ) const; virtual bool equivalent( const MatchExpression* other ) const;
virtual LeafMatchExpression* shallowClone() const; virtual LeafMatchExpression* shallowClone() const;
private: private:
GeoQuery _query; GeoQuery _query;
}; };
} class GeoNearMatchExpression : public LeafMatchExpression {
public:
GeoNearMatchExpression() : LeafMatchExpression( GEO_NEAR ){}
virtual ~GeoNearMatchExpression(){}
Status init( const StringData& path, const NearQuery& query );
// This shouldn't be called and as such will crash. GeoNear always
requires an index.
virtual bool matchesSingleElement( const BSONElement& e ) const;
virtual void debugString( StringBuilder& debug, int level = 0 ) con
st;
virtual bool equivalent( const MatchExpression* other ) const;
virtual LeafMatchExpression* shallowClone() const;
const NearQuery& getData() const { return _query; }
private:
NearQuery _query;
};
} // namespace mongo
 End of changes. 2 change blocks. 
0 lines changed or deleted 1 lines changed or added


 expression_leaf.h   expression_leaf.h 
skipping to change at line 73 skipping to change at line 73
virtual ~ComparisonMatchExpression(){} virtual ~ComparisonMatchExpression(){}
virtual bool matchesSingleElement( const BSONElement& e ) const; virtual bool matchesSingleElement( const BSONElement& e ) const;
virtual const BSONElement& getRHS() const { return _rhs; } virtual const BSONElement& getRHS() const { return _rhs; }
virtual void debugString( StringBuilder& debug, int level = 0 ) con st; virtual void debugString( StringBuilder& debug, int level = 0 ) con st;
virtual bool equivalent( const MatchExpression* other ) const; virtual bool equivalent( const MatchExpression* other ) const;
const BSONElement& getData() const { return _rhs; }
protected: protected:
BSONElement _rhs; BSONElement _rhs;
}; };
class EqualityMatchExpression : public ComparisonMatchExpression { class EqualityMatchExpression : public ComparisonMatchExpression {
public: public:
EqualityMatchExpression() : ComparisonMatchExpression( EQ ){} EqualityMatchExpression() : ComparisonMatchExpression( EQ ){}
virtual LeafMatchExpression* shallowClone() const { virtual LeafMatchExpression* shallowClone() const {
ComparisonMatchExpression* e = new EqualityMatchExpression(); ComparisonMatchExpression* e = new EqualityMatchExpression();
e->init( path(), _rhs ); e->init( path(), _rhs );
skipping to change at line 157 skipping to change at line 159
e->init( path(), _regex, _flags ); e->init( path(), _regex, _flags );
return e; return e;
} }
virtual bool matchesSingleElement( const BSONElement& e ) const; virtual bool matchesSingleElement( const BSONElement& e ) const;
virtual void debugString( StringBuilder& debug, int level ) const; virtual void debugString( StringBuilder& debug, int level ) const;
virtual bool equivalent( const MatchExpression* other ) const; virtual bool equivalent( const MatchExpression* other ) const;
const string& getString() const { return _regex; }
const string& getFlags() const { return _flags; }
private: private:
std::string _regex; std::string _regex;
std::string _flags; std::string _flags;
boost::scoped_ptr<pcrecpp::RE> _re; boost::scoped_ptr<pcrecpp::RE> _re;
}; };
class ModMatchExpression : public LeafMatchExpression { class ModMatchExpression : public LeafMatchExpression {
public: public:
ModMatchExpression() : LeafMatchExpression( MOD ){} ModMatchExpression() : LeafMatchExpression( MOD ){}
skipping to change at line 181 skipping to change at line 186
m->init( path(), _divisor, _remainder ); m->init( path(), _divisor, _remainder );
return m; return m;
} }
virtual bool matchesSingleElement( const BSONElement& e ) const; virtual bool matchesSingleElement( const BSONElement& e ) const;
virtual void debugString( StringBuilder& debug, int level ) const; virtual void debugString( StringBuilder& debug, int level ) const;
virtual bool equivalent( const MatchExpression* other ) const; virtual bool equivalent( const MatchExpression* other ) const;
int getDivisor() const { return _divisor; }
int getRemainder() const { return _remainder; }
private: private:
int _divisor; int _divisor;
int _remainder; int _remainder;
}; };
class ExistsMatchExpression : public LeafMatchExpression { class ExistsMatchExpression : public LeafMatchExpression {
public: public:
ExistsMatchExpression() : LeafMatchExpression( EXISTS ){} ExistsMatchExpression() : LeafMatchExpression( EXISTS ){}
Status init( const StringData& path ); Status init( const StringData& path );
skipping to change at line 218 skipping to change at line 226
Status init( const StringData& path, int type ); Status init( const StringData& path, int type );
virtual bool matchesSingleElement( const BSONElement& e ) const; virtual bool matchesSingleElement( const BSONElement& e ) const;
virtual bool matches( const MatchableDocument* doc, MatchDetails* d etails = 0 ) const; virtual bool matches( const MatchableDocument* doc, MatchDetails* d etails = 0 ) const;
virtual void debugString( StringBuilder& debug, int level ) const; virtual void debugString( StringBuilder& debug, int level ) const;
virtual bool equivalent( const MatchExpression* other ) const; virtual bool equivalent( const MatchExpression* other ) const;
int getType() const { return _type; }
private: private:
bool _matches( const StringData& path, bool _matches( const StringData& path,
const MatchableDocument* doc, const MatchableDocument* doc,
MatchDetails* details = 0 ) const; MatchDetails* details = 0 ) const;
StringData _path; StringData _path;
ElementPath _elementPath; ElementPath _elementPath;
int _type; int _type;
}; };
skipping to change at line 257 skipping to change at line 268
RegexMatchExpression* regex( int idx ) const { return _regexes[idx] ; } RegexMatchExpression* regex( int idx ) const { return _regexes[idx] ; }
bool hasNull() const { return _hasNull; } bool hasNull() const { return _hasNull; }
bool singleNull() const { return size() == 1 && _hasNull; } bool singleNull() const { return size() == 1 && _hasNull; }
bool hasEmptyArray() const { return _hasEmptyArray; } bool hasEmptyArray() const { return _hasEmptyArray; }
int size() const { return _equalities.size() + _regexes.size(); } int size() const { return _equalities.size() + _regexes.size(); }
bool equivalent( const ArrayFilterEntries& other ) const; bool equivalent( const ArrayFilterEntries& other ) const;
void copyTo( ArrayFilterEntries& toFillIn ) const; void copyTo( ArrayFilterEntries& toFillIn ) const;
private: private:
bool _hasNull; // if _equalities has a jstNULL element in it bool _hasNull; // if _equalities has a jstNULL element in it
bool _hasEmptyArray; bool _hasEmptyArray;
BSONElementSet _equalities; BSONElementSet _equalities;
std::vector<RegexMatchExpression*> _regexes; std::vector<RegexMatchExpression*> _regexes;
}; };
/** /**
* query operator: $in * query operator: $in
*/ */
skipping to change at line 284 skipping to change at line 296
ArrayFilterEntries* getArrayFilterEntries() { return &_arrayEntries ; } ArrayFilterEntries* getArrayFilterEntries() { return &_arrayEntries ; }
virtual bool matchesSingleElement( const BSONElement& e ) const; virtual bool matchesSingleElement( const BSONElement& e ) const;
virtual void debugString( StringBuilder& debug, int level ) const; virtual void debugString( StringBuilder& debug, int level ) const;
virtual bool equivalent( const MatchExpression* other ) const; virtual bool equivalent( const MatchExpression* other ) const;
void copyTo( InMatchExpression* toFillIn ) const; void copyTo( InMatchExpression* toFillIn ) const;
const ArrayFilterEntries& getData() const { return _arrayEntries; }
private: private:
bool _matchesRealElement( const BSONElement& e ) const; bool _matchesRealElement( const BSONElement& e ) const;
ArrayFilterEntries _arrayEntries; ArrayFilterEntries _arrayEntries;
}; };
} }
 End of changes. 6 change blocks. 
0 lines changed or deleted 14 lines changed or added


 expression_parser.h   expression_parser.h 
skipping to change at line 35 skipping to change at line 35
#include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression.h"
#include "mongo/db/matcher/expression_leaf.h" #include "mongo/db/matcher/expression_leaf.h"
#include "mongo/db/matcher/expression_tree.h" #include "mongo/db/matcher/expression_tree.h"
namespace mongo { namespace mongo {
typedef StatusWith<MatchExpression*> StatusWithMatchExpression; typedef StatusWith<MatchExpression*> StatusWithMatchExpression;
class MatchExpressionParser { class MatchExpressionParser {
public: public:
/**
* caller has to maintain ownership obj
* the tree has views (BSONElement) into obj
*/
static StatusWithMatchExpression parse( const BSONObj& obj ) { static StatusWithMatchExpression parse( const BSONObj& obj ) {
return _parse( obj, true ); return _parse( obj, true );
} }
private: private:
/** /**
* 5 = false * 5 = false
{ a : 5 } = false { a : 5 } = false
{ $lt : 5 } = true { $lt : 5 } = true
skipping to change at line 102 skipping to change at line 107
const BSONElement& e ); const BSONElement& e );
// tree // tree
static Status _parseTreeList( const BSONObj& arr, ListOfMatchExpres sion* out ); static Status _parseTreeList( const BSONObj& arr, ListOfMatchExpres sion* out );
static StatusWithMatchExpression _parseNot( const char* name, const BSONElement& e ); static StatusWithMatchExpression _parseNot( const char* name, const BSONElement& e );
}; };
typedef boost::function<StatusWithMatchExpression(const char* name, con st BSONObj& section)> MatchExpressionParserGeoCallback; typedef boost::function<StatusWithMatchExpression(const char* name, int type, const BSONObj& section)> MatchExpressionParserGeoCallback;
extern MatchExpressionParserGeoCallback expressionParserGeoCallback; extern MatchExpressionParserGeoCallback expressionParserGeoCallback;
typedef boost::function<StatusWithMatchExpression(const BSONElement& wh ere)> MatchExpressionParserWhereCallback; typedef boost::function<StatusWithMatchExpression(const BSONElement& wh ere)> MatchExpressionParserWhereCallback;
extern MatchExpressionParserWhereCallback expressionParserWhereCallback ; extern MatchExpressionParserWhereCallback expressionParserWhereCallback ;
} }
 End of changes. 2 change blocks. 
1 lines changed or deleted 6 lines changed or added


 fetch.h   fetch.h 
skipping to change at line 20 skipping to change at line 20
* 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 "mongo/db/diskloc.h" #include "mongo/db/diskloc.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/matcher.h"
#include "mongo/db/exec/plan_stage.h" #include "mongo/db/exec/plan_stage.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/matcher/expression.h"
namespace mongo { namespace mongo {
/** /**
* This stage turns a DiskLoc into a BSONObj. * This stage turns a DiskLoc into a BSONObj.
* *
* In WorkingSetMember terms, it transitions from LOC_AND_IDX to LOC_AN D_UNOWNED_OBJ by reading * In WorkingSetMember terms, it transitions from LOC_AND_IDX to LOC_AN D_UNOWNED_OBJ by reading
* the record at the provided loc. Returns verbatim any data that alre ady has an object. * the record at the provided loc. Returns verbatim any data that alre ady has an object.
* *
* Preconditions: Valid DiskLoc. * Preconditions: Valid DiskLoc.
*/ */
class FetchStage : public PlanStage { class FetchStage : public PlanStage {
public: public:
FetchStage(WorkingSet* ws, PlanStage* child, Matcher* matcher); FetchStage(WorkingSet* ws, PlanStage* child, const MatchExpression* filter);
virtual ~FetchStage(); virtual ~FetchStage();
virtual bool isEOF(); virtual bool isEOF();
virtual StageState work(WorkingSetID* out); virtual StageState work(WorkingSetID* out);
virtual void prepareToYield(); virtual void prepareToYield();
virtual void recoverFromYield(); virtual void recoverFromYield();
virtual void invalidate(const DiskLoc& dl); virtual void invalidate(const DiskLoc& dl);
PlanStageStats* getStats();
private: private:
/** /**
* If the member (with id memberID) passes our filter, set *out to memberID and return that * If the member (with id memberID) passes our filter, set *out to memberID and return that
* ADVANCED. Otherwise, free memberID and return NEED_TIME. * ADVANCED. Otherwise, free memberID and return NEED_TIME.
*/ */
StageState returnIfMatches(WorkingSetMember* member, WorkingSetID m emberID, StageState returnIfMatches(WorkingSetMember* member, WorkingSetID m emberID,
WorkingSetID* out); WorkingSetID* out);
/** /**
* work(...) delegates to this when we're called after requesting a fetch. * work(...) delegates to this when we're called after requesting a fetch.
*/ */
StageState fetchCompleted(WorkingSetID* out); StageState fetchCompleted(WorkingSetID* out);
// _ws is not owned by us. // _ws is not owned by us.
WorkingSet* _ws; WorkingSet* _ws;
scoped_ptr<PlanStage> _child; scoped_ptr<PlanStage> _child;
scoped_ptr<Matcher> _matcher;
// The filter is not owned by us.
const MatchExpression* _filter;
// If we're fetching a DiskLoc and it points at something that's no t in memory, we return a // If we're fetching a DiskLoc and it points at something that's no t in memory, we return a
// a "please page this in" result and hold on to the WSID until the next call to work(...). // a "please page this in" result and hold on to the WSID until the next call to work(...).
WorkingSetID _idBeingPagedIn; WorkingSetID _idBeingPagedIn;
// Stats
CommonStats _commonStats;
FetchStats _specificStats;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 6 change blocks. 
4 lines changed or deleted 12 lines changed or added


 field_parser.h   field_parser.h 
skipping to change at line 22 skipping to change at line 22
* *
* 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 <string> #include <string>
#include "mongo/bson/bson_field.h" #include "mongo/bson/bson_field.h"
#include "mongo/bson/util/misc.h" // for Date_t
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/util/time_support.h"
namespace mongo { namespace mongo {
class FieldParser { class FieldParser {
public: public:
/** /**
* Returns true and fills in 'out' with the contents of the field d escribed by 'field' * Returns true and fills in 'out' with the contents of the field d escribed by 'field'
* or with the value in 'def', depending on whether the field is pr esent and has the * or with the value in 'def', depending on whether the field is pr esent and has the
* correct type in 'doc' or not, respectively. Otherwise, if the fi eld exists but has * correct type in 'doc' or not, respectively. Otherwise, if the fi eld exists but has
* the wrong type, returns false. * the wrong type, returns false.
 End of changes. 2 change blocks. 
1 lines changed or deleted 1 lines changed or added


 finding_start_cursor.h   finding_start_cursor.h 
skipping to change at line 97 skipping to change at line 97
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; ClientCursorHolder _findingStartCursor;
shared_ptr<Cursor> _c; shared_ptr<Cursor> _c;
ClientCursor::YieldData _yieldData; ClientCursor::YieldData _yieldData;
static int _initialTimeout; static int _initialTimeout;
/** @return the first record of the extent containing @param rec. * / /** @return the first record of the extent containing @param rec. * /
DiskLoc extentFirstLoc( const DiskLoc &rec ); DiskLoc extentFirstLoc( 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 );
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 fts_util.h   fts_util.h 
skipping to change at line 25 skipping to change at line 25
* 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 <string> #include <string>
#include "mongo/db/hasher.h" #include "mongo/db/hasher.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/record.h" #include "mongo/db/storage/record.h"
#include "mongo/util/unordered_fast_key_table.h" #include "mongo/util/unordered_fast_key_table.h"
namespace mongo { namespace mongo {
namespace fts { namespace fts {
extern const std::string WILDCARD; extern const std::string WILDCARD;
extern const std::string INDEX_NAME; extern const std::string INDEX_NAME;
/** /**
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 geoquery.h   geoquery.h 
skipping to change at line 94 skipping to change at line 94
shared_ptr<S2RegionUnion> _region; shared_ptr<S2RegionUnion> _region;
}; };
class NearQuery { class NearQuery {
public: public:
NearQuery() : minDistance(0), maxDistance(std::numeric_limits<doubl e>::max()), NearQuery() : minDistance(0), maxDistance(std::numeric_limits<doubl e>::max()),
fromRadians(false) {} fromRadians(false) {}
NearQuery(const string& f) : field(f), minDistance(0), NearQuery(const string& f) : field(f), minDistance(0),
maxDistance(std::numeric_limits<double >::max()), maxDistance(std::numeric_limits<double >::max()),
fromRadians(false) {} fromRadians(false) {}
bool parseFrom(const BSONObj &obj, double radius);
/**
* If fromRadians is true after a parseFrom, minDistance and maxDis
tance are returned in
* radians, not meters. The distances must be multiplied by the un
derlying index's radius
* to convert them to meters.
*
* This is annoying but useful when we don't know what index we're
using at parse time.
*/
bool parseFrom(const BSONObj &obj);
bool parseFromGeoNear(const BSONObj &obj, double radius); bool parseFromGeoNear(const BSONObj &obj, double radius);
string field; string field;
PointWithCRS centroid; PointWithCRS centroid;
// Min and max distance IN METERS from centroid that we're willing to search. // Min and max distance IN METERS from centroid that we're willing to search.
double minDistance; double minDistance;
double maxDistance; double maxDistance;
// Did we convert to this distance from radians? (If so, we output distances in radians.) // Did we convert to this distance from radians? (If so, we output distances in radians.)
bool fromRadians; bool fromRadians;
}; };
// This represents either a $within or a $geoIntersects. // This represents either a $within or a $geoIntersects.
class GeoQuery { class GeoQuery {
public: public:
GeoQuery() : field(""), predicate(INVALID) {} GeoQuery() : field(""), predicate(INVALID) {}
GeoQuery(const string& f) : field(f), predicate(INVALID) {} GeoQuery(const string& f) : field(f), predicate(INVALID) {}
 End of changes. 4 change blocks. 
1 lines changed or deleted 15 lines changed or added


 grid.h   grid.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 <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp>
#include "../util/time_support.h" #include "mongo/util/time_support.h"
#include "../util/concurrency/mutex.h" #include "mongo/util/concurrency/mutex.h"
#include "config.h" // DBConfigPtr #include "config.h" // DBConfigPtr
namespace mongo { namespace mongo {
/** /**
* stores meta-information about the grid * stores meta-information about the grid
* TODO: used shard_ptr for DBConfig pointers * TODO: used shard_ptr for DBConfig pointers
*/ */
class Grid { class Grid {
 End of changes. 1 change blocks. 
2 lines changed or deleted 2 lines changed or added


 index_scan.h   index_scan.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 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 "mongo/db/exec/plan_stage.h"
#include "mongo/db/diskloc.h" #include "mongo/db/diskloc.h"
#include "mongo/db/index/btree_index_cursor.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/matcher.h" #include "mongo/db/matcher/expression.h"
#include "mongo/db/exec/plan_stage.h" #include "mongo/db/query/index_bounds.h"
#include "mongo/platform/unordered_set.h" #include "mongo/platform/unordered_set.h"
namespace mongo { namespace mongo {
class IndexAccessMethod; class IndexAccessMethod;
class IndexCursor; class IndexCursor;
class IndexDescriptor; class IndexDescriptor;
struct IndexScanParams;
class WorkingSet; class WorkingSet;
struct IndexScanParams {
IndexScanParams() : descriptor(NULL), direction(1), limit(0),
forceBtreeAccessMethod(false) { }
IndexDescriptor* descriptor;
IndexBounds bounds;
int direction;
// This only matters for 2d indices and will be ignored by every ot
her index.
int limit;
// Special indices internally open an IndexCursor over themselves b
ut as a straight Btree.
bool forceBtreeAccessMethod;
};
/** /**
* Stage scans over an index from startKey to endKey, returning results that pass the provided * Stage scans over an index from startKey to endKey, returning results that pass the provided
* filter. Internally dedups on DiskLoc. * filter. Internally dedups on DiskLoc.
* *
* Sub-stage preconditions: None. Is a leaf and consumes no stage data . * Sub-stage preconditions: None. Is a leaf and consumes no stage data .
*/ */
class IndexScan : public PlanStage { class IndexScan : public PlanStage {
public: public:
IndexScan(const IndexScanParams& params, WorkingSet* workingSet, Ma IndexScan(const IndexScanParams& params, WorkingSet* workingSet,
tcher* matcher); const MatchExpression* filter);
virtual ~IndexScan() { } virtual ~IndexScan() { }
virtual StageState work(WorkingSetID* out); virtual StageState work(WorkingSetID* out);
virtual bool isEOF(); virtual bool isEOF();
virtual void prepareToYield(); virtual void prepareToYield();
virtual void recoverFromYield(); virtual void recoverFromYield();
virtual void invalidate(const DiskLoc& dl); virtual void invalidate(const DiskLoc& dl);
virtual PlanStageStats* getStats();
private: private:
/** See if the cursor is pointing at or past _endKey, if _endKey is non-empty. */ /** See if the cursor is pointing at or past _endKey, if _endKey is non-empty. */
void checkEnd(); void checkEnd();
// The WorkingSet we annotate with results. Not owned by us. // The WorkingSet we annotate with results. Not owned by us.
WorkingSet* _workingSet; WorkingSet* _workingSet;
// Index access. // Index access.
scoped_ptr<IndexAccessMethod> _iam; scoped_ptr<IndexAccessMethod> _iam;
scoped_ptr<IndexCursor> _indexCursor; scoped_ptr<IndexCursor> _indexCursor;
scoped_ptr<IndexDescriptor> _descriptor; scoped_ptr<IndexDescriptor> _descriptor;
// Bounds for the cursor. TODO: take a set of bounds. // Have we hit the end of the index scan?
BSONObj _startKey;
BSONObj _endKey;
bool _endKeyInclusive;
int _direction;
bool _hitEnd; bool _hitEnd;
// Contains expressions only over fields in the index key. We assu me this is built // Contains expressions only over fields in the index key. We assu me this is built
// correctly by whomever creates this class. // correctly by whomever creates this class.
scoped_ptr<Matcher> _matcher; // The filter is not owned by us.
const MatchExpression* _filter;
// Could our index have duplicates? If so, we use _returned to ded up. // Could our index have duplicates? If so, we use _returned to ded up.
bool _shouldDedup; bool _shouldDedup;
unordered_set<DiskLoc, DiskLoc::Hasher> _returned; unordered_set<DiskLoc, DiskLoc::Hasher> _returned;
// For yielding. // For yielding.
BSONObj _savedKey; BSONObj _savedKey;
DiskLoc _savedLoc; DiskLoc _savedLoc;
// True if there was a yield and the yield changed the cursor posit ion. // True if there was a yield and the yield changed the cursor posit ion.
bool _yieldMovedCursor; bool _yieldMovedCursor;
// This is IndexScanParams::limit. See comment there. IndexScanParams _params;
int _numWanted;
};
struct IndexScanParams { // For our "fast" Btree-only navigation AKA the index bounds optimi
IndexScanParams() : descriptor(NULL), endKeyInclusive(true), direct zation.
ion(1), limit(0), scoped_ptr<IndexBoundsChecker> _checker;
forceBtreeAccessMethod(false) { } BtreeIndexCursor* _btreeCursor;
IndexDescriptor* descriptor; int _keyEltsToUse;
BSONObj startKey; bool _movePastKeyElts;
BSONObj endKey; vector<const BSONElement*> _keyElts;
bool endKeyInclusive; vector<bool> _keyEltsInc;
int direction;
// Stats
// This only matters for 2d indices and will be ignored by every ot CommonStats _commonStats;
her index. IndexScanStats _specificStats;
int limit;
// Special indices internally open an IndexCursor over themselves b
ut as a straight Btree.
bool forceBtreeAccessMethod;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 11 change blocks. 
31 lines changed or deleted 44 lines changed or added


 instance.h   instance.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
#include "mongo/client/dbclientinterface.h" #include "mongo/client/dbclientinterface.h"
#include "mongo/db/client.h" #include "mongo/db/client.h"
#include "mongo/db/cmdline.h" #include "mongo/db/cmdline.h"
#include "mongo/db/curop-inl.h" #include "mongo/db/curop-inl.h"
#include "mongo/db/dbmessage.h"
namespace mongo { namespace mongo {
extern string dbExecCommand; extern string dbExecCommand;
/** a high level recording of operations to the database - sometimes us ed for diagnostics /** a high level recording of operations to the database - sometimes us ed for diagnostics
and debugging. and debugging.
*/ */
class DiagLog { class DiagLog {
ofstream *f; // note this is never freed ofstream *f; // note this is never freed
skipping to change at line 57 skipping to change at line 58
* @return old * @return old
*/ */
int setLevel( int newLevel ); int setLevel( int newLevel );
void flush(); void flush();
void writeop(char *data,int len); void writeop(char *data,int len);
void readop(char *data, int len); void readop(char *data, int len);
}; };
extern DiagLog _diaglog; extern DiagLog _diaglog;
/* we defer response until we unlock. don't want a blocked socket to
keep things locked.
*/
struct DbResponse {
Message *response;
MSGID responseTo;
string exhaustNS; /* points to ns if exhaust mode. 0=normal mode*/
DbResponse(Message *r, MSGID rt) : response(r), responseTo(rt){ }
DbResponse() {
response = 0;
}
~DbResponse() { delete response; }
};
void assembleResponse( Message &m, DbResponse &dbresponse, const HostAn dPort &client ); void assembleResponse( Message &m, DbResponse &dbresponse, const HostAn dPort &client );
void getDatabaseNames( vector< string > &names , const string& usePath = dbpath ); void getDatabaseNames( vector< string > &names , const string& usePath = dbpath );
/* returns true if there is no data on this server. useful when starti ng replication. /* returns true if there is no data on this server. useful when starti ng replication.
local database does NOT count. local database does NOT count.
*/ */
bool replHasDatabases(); bool replHasDatabases();
/** "embedded" calls to the local server directly. /** "embedded" calls to the local server directly.
 End of changes. 2 change blocks. 
14 lines changed or deleted 1 lines changed or added


 interrupt_status.h   interrupt_status.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 License * You should have received a copy of the GNU Affero General Public License
* 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"
namespace mongo { namespace mongo {
/** /**
Abstraction for checking on interrupt status. Abstraction for checking on interrupt status.
The killCurrentOp object (currently declared in curop.h, and defined The killCurrentOp object (currently declared in curop.h, and defined
in instance.cpp) can only be referenced within mongod. This abstrac tion in instance.cpp) can only be referenced within mongod. This abstrac tion
serves to isolate that so that code that runs in both mongod and mon gos serves to isolate that so that code that runs in both mongod and mon gos
can be linked without unresolved symbols. There is a concrete can be linked without unresolved symbols. There is a concrete
implementation of this class for mongod which references killCurrent Op, implementation of this class for mongod which references killCurrent Op,
and another implementation for mongos which does not (currently, it and another implementation for mongos which does not (currently, it
does nothing, but that should be fixed). does nothing, but that should be fixed).
*/ */
class InterruptStatus { class InterruptStatus {
public: public:
/** /**
Check for interrupt. Check for interrupt.
@throws a uassert if the process has received an interrupt (SIGI NT) @throws a uassert if the process has received an interrupt (SIGI NT)
*/ */
virtual void checkForInterrupt() = 0; virtual void checkForInterrupt() const =0;
/** /**
Check for interrupt. Check for interrupt.
@returns a pointer to a string with additional information; will be @returns a pointer to a string with additional information; will be
"" if there hasn't been an interrupt. These strings are stati c "" if there hasn't been an interrupt. These strings are stati c
and don't need to be freed. and don't need to be freed.
*/ */
virtual const char *checkForInterruptNoAssert() = 0; virtual const char *checkForInterruptNoAssert() const =0;
protected: protected:
/** /**
This interface is meant to be used in the implementation of stat ic This interface is meant to be used in the implementation of stat ic
objects, so the destructor is made protected so that they can't be objects, so the destructor is made protected so that they can't be
accidentally deleted. It can't be private, or the compiler accidentally deleted. It can't be private, or the compiler
generates warnings about being unable to generate the derived generates warnings about being unable to generate the derived
classes' destructors. classes' destructors.
*/ */
virtual ~InterruptStatus() {}; virtual ~InterruptStatus() {};
 End of changes. 3 change blocks. 
4 lines changed or deleted 2 lines changed or added


 interrupt_status_mongod.h   interrupt_status_mongod.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 License * You should have received a copy of the GNU Affero General Public License
* 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/db/interrupt_status.h"
#include "db/interrupt_status.h"
namespace mongo { namespace mongo {
class InterruptStatusMongod : class InterruptStatusMongod :
public InterruptStatus, public InterruptStatus,
boost::noncopyable { boost::noncopyable {
public: public:
// virtuals from InterruptStatus // virtuals from InterruptStatus
virtual void checkForInterrupt(); virtual void checkForInterrupt() const;
virtual const char *checkForInterruptNoAssert(); virtual const char *checkForInterruptNoAssert() const;
/* /*
Static singleton instance. Static singleton instance.
*/ */
static InterruptStatusMongod status; static const InterruptStatusMongod status;
private: private:
InterruptStatusMongod(); InterruptStatusMongod();
}; };
}; };
 End of changes. 3 change blocks. 
5 lines changed or deleted 4 lines changed or added


 interrupt_status_mongos.h   interrupt_status_mongos.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 License * You should have received a copy of the GNU Affero General Public License
* 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/db/interrupt_status.h"
#include "db/interrupt_status.h"
namespace mongo { namespace mongo {
class InterruptStatusMongos : class InterruptStatusMongos :
public InterruptStatus, public InterruptStatus,
boost::noncopyable { boost::noncopyable {
public: public:
// virtuals from InterruptStatus // virtuals from InterruptStatus
virtual void checkForInterrupt(); virtual void checkForInterrupt() const;
virtual const char *checkForInterruptNoAssert(); virtual const char *checkForInterruptNoAssert() const;
/* /*
Static singleton instance. Static singleton instance.
*/ */
static InterruptStatusMongos status; static const InterruptStatusMongos status;
private: private:
InterruptStatusMongos(); InterruptStatusMongos();
}; };
}; };
 End of changes. 3 change blocks. 
5 lines changed or deleted 4 lines changed or added


 introspect.h   introspect.h 
skipping to change at line 23 skipping to change at line 23
* 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 "jsobj.h" #include "mongo/db/jsobj.h"
#include "pdfile.h" #include "mongo/db/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, int op, CurOp& currentOp);
/** /**
 End of changes. 1 change blocks. 
2 lines changed or deleted 2 lines changed or added


 jsobj.h   jsobj.h 
skipping to change at line 34 skipping to change at line 34
represented in JSON (plus a few extensions useful for databases & other languages). represented in JSON (plus a few extensions useful for databases & other languages).
http://www.bsonspec.org/ http://www.bsonspec.org/
*/ */
#pragma once #pragma once
#include "mongo/pch.h" #include "mongo/pch.h"
#include "mongo/bson/util/builder.h" #include "mongo/bson/util/builder.h"
#include "mongo/db/repl/optime.h" #include "mongo/bson/optime.h"
#include "mongo/bson/bsontypes.h" #include "mongo/bson/bsontypes.h"
#include "mongo/bson/oid.h" #include "mongo/bson/oid.h"
#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/bsonobjbuilder.h" #include "mongo/bson/bsonobjbuilder.h"
#include "mongo/bson/bsonobjiterator.h" #include "mongo/bson/bsonobjiterator.h"
#include "mongo/bson/bson-inl.h" #include "mongo/bson/bson-inl.h"
#include "mongo/bson/ordering.h" #include "mongo/bson/ordering.h"
#include "mongo/base/string_data.h" #include "mongo/base/string_data.h"
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 limit.h   limit.h 
skipping to change at line 44 skipping to change at line 44
LimitStage(int limit, WorkingSet* ws, PlanStage* child); LimitStage(int limit, WorkingSet* ws, PlanStage* child);
virtual ~LimitStage(); virtual ~LimitStage();
virtual bool isEOF(); virtual bool isEOF();
virtual StageState work(WorkingSetID* out); virtual StageState work(WorkingSetID* out);
virtual void prepareToYield(); virtual void prepareToYield();
virtual void recoverFromYield(); virtual void recoverFromYield();
virtual void invalidate(const DiskLoc& dl); virtual void invalidate(const DiskLoc& dl);
virtual PlanStageStats* getStats();
private: private:
WorkingSet* _ws; WorkingSet* _ws;
scoped_ptr<PlanStage> _child; scoped_ptr<PlanStage> _child;
// We only return this many results. // We only return this many results.
int _numToReturn; int _numToReturn;
// Stats
CommonStats _commonStats;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
0 lines changed or deleted 5 lines changed or added


 listen.h   listen.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 <set>
#include <string>
#include <vector>
#include "mongo/platform/atomic_word.h" #include "mongo/platform/atomic_word.h"
#include "mongo/util/concurrency/ticketholder.h" #include "mongo/util/concurrency/ticketholder.h"
#include "mongo/util/log.h"
#include "mongo/util/net/sock.h" #include "mongo/util/net/sock.h"
namespace mongo { namespace mongo {
const int DEFAULT_MAX_CONN = 20000; const int DEFAULT_MAX_CONN = 20000;
class MessagingPort; class MessagingPort;
class Listener : boost::noncopyable { class Listener : boost::noncopyable {
public: public:
Listener(const string& name, const string &ip, int port, bool logCo nnect=true ); Listener(const std::string& name, const std::string &ip, int port, bool logConnect=true );
virtual ~Listener(); virtual ~Listener();
void initAndListen(); // never returns unless error (start a thread ) void initAndListen(); // never returns unless error (start a thread )
/* spawn a thread, etc., then return */ /* spawn a thread, etc., then return */
virtual void accepted(boost::shared_ptr<Socket> psocket, long long connectionId ); virtual void accepted(boost::shared_ptr<Socket> psocket, long long connectionId );
virtual void acceptedMP(MessagingPort *mp); virtual void acceptedMP(MessagingPort *mp);
const int _port; const int _port;
skipping to change at line 67 skipping to change at line 72
static long long getElapsedTimeMillis() { static long long getElapsedTimeMillis() {
if ( _timeTracker ) if ( _timeTracker )
return _timeTracker->getMyElapsedTimeMillis(); return _timeTracker->getMyElapsedTimeMillis();
// should this assert or throw? seems like callers may not exp ect to get zero back, certainly not forever. // should this assert or throw? seems like callers may not exp ect to get zero back, certainly not forever.
return 0; return 0;
} }
private: private:
string _name; std::string _name;
string _ip; std::string _ip;
bool _logConnect; bool _logConnect;
long long _elapsedTime; long long _elapsedTime;
#ifdef MONGO_SSL #ifdef MONGO_SSL
SSLManagerInterface* _ssl; SSLManagerInterface* _ssl;
#endif #endif
/** /**
* @return true iff everything went ok * @return true iff everything went ok
*/ */
bool _setupSockets( const vector<SockAddr>& mine , vector<SOCKET>& socks ); bool _setupSockets( const std::vector<SockAddr>& mine , std::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: public:
/** the "next" connection number. every connection to this process has a unique number */ /** the "next" connection number. every connection to this process has a unique number */
static AtomicInt64 globalConnectionNumber; static AtomicInt64 globalConnectionNumber;
skipping to change at line 102 skipping to change at line 107
static TicketHolder globalTicketHolder; static TicketHolder globalTicketHolder;
/** makes sure user input is sane */ /** makes sure user input is sane */
static void checkTicketNumbers(); static void checkTicketNumbers();
}; };
class ListeningSockets { class ListeningSockets {
public: public:
ListeningSockets() ListeningSockets()
: _mutex("ListeningSockets") : _mutex("ListeningSockets")
, _sockets( new set<int>() ) , _sockets( new std::set<int>() )
, _socketPaths( new set<string>() ) , _socketPaths( new std::set<std::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( const std::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; std::set<int>* sockets;
set<string>* paths; std::set<std::string>* paths;
{ {
scoped_lock lk( _mutex ); scoped_lock lk( _mutex );
sockets = _sockets; sockets = _sockets;
_sockets = new set<int>(); _sockets = new std::set<int>();
paths = _socketPaths; paths = _socketPaths;
_socketPaths = new set<string>(); _socketPaths = new std::set<std::string>();
} }
for ( set<int>::iterator i=sockets->begin(); i!=sockets->end(); i++ ) { for ( std::set<int>::iterator i=sockets->begin(); i!=sockets->e nd(); i++ ) {
int sock = *i; int sock = *i;
log() << "closing listening socket: " << sock << endl; log() << "closing listening socket: " << sock << std::endl;
closesocket( sock ); closesocket( sock );
} }
for ( set<string>::iterator i=paths->begin(); i!=paths->end(); for ( std::set<std::string>::iterator i=paths->begin(); i!=path
i++ ) { s->end(); i++ ) {
string path = *i; std::string path = *i;
log() << "removing socket file: " << path << endl; log() << "removing socket file: " << path << std::endl;
::remove( path.c_str() ); ::remove( path.c_str() );
} }
} }
static ListeningSockets* get(); static ListeningSockets* get();
private: private:
mongo::mutex _mutex; mongo::mutex _mutex;
set<int>* _sockets; std::set<int>* _sockets;
set<string>* _socketPaths; // for unix domain sockets std::set<std::string>* _socketPaths; // for unix domain sockets
static ListeningSockets* _instance; static ListeningSockets* _instance;
}; };
} }
 End of changes. 13 change blocks. 
18 lines changed or deleted 23 lines changed or added


 lruishmap.h   lruishmap.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 "mongo/pch.h" #include "mongo/pch.h"
#include "../util/goodies.h" #include "mongo/util/goodies.h"
namespace mongo { namespace mongo {
/* Your K object must define: /* Your K object must define:
int hash() - must always return > 0. int hash() - must always return > 0.
operator== operator==
*/ */
template <class K, class V, int MaxChain> template <class K, class V, int MaxChain>
class LRUishMap { class LRUishMap {
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 master_slave.h   master_slave.h 
skipping to change at line 80 skipping to change at line 80
/* 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
avoid overflowing the master's transaction log by doing too much work before going avoid overflowing the master's transaction log by doing too much work before going
back to read more transactions. (Imagine a scenario of slave sta rtup where we try to back to read more transactions. (Imagine a scenario of slave sta rtup where we try to
clone 100 databases in one pass.) clone 100 databases in one pass.)
*/ */
set<string> addDbNextPass; set<string> addDbNextPass;
set<string> incompleteCloneDbs; set<string> incompleteCloneDbs;
BSONObj _me;
ReplSource(); ReplSource();
// returns the dummy ns used to do the drop // returns the dummy ns used to do the drop
string resyncDrop( const char *db, const char *requester ); string resyncDrop( const char *db, const char *requester );
// call without the db mutex // call without the db mutex
void syncToTailOfRemoteLog(); void syncToTailOfRemoteLog();
string ns() const { return string( "local.oplog.$" ) + sourceName() ; } string ns() const { return string( "local.oplog.$" ) + sourceName() ; }
unsigned _sleepAdviceTime; unsigned _sleepAdviceTime;
/** /**
* If 'db' is a new database and its name would conflict with that of * If 'db' is a new database and its name would conflict with that of
* an existing database, synchronize these database names with the * an existing database, synchronize these database names with the
* master. * master.
* @return true iff an op with the specified ns may be applied. * @return true iff an op with the specified ns may be applied.
*/ */
bool handleDuplicateDbName( const BSONObj &op, const char *ns, cons t char *db ); bool handleDuplicateDbName( const BSONObj &op, const char *ns, cons t char *db );
// populates _me so that it can be passed to oplogreader for handsh
akes
void ensureMe();
public: public:
OplogReader oplogReader; OplogReader oplogReader;
void applyOperation(const BSONObj& op); void applyOperation(const BSONObj& op);
string hostName; // ip addr or hostname plus optionally, ":<port >" string hostName; // ip addr or hostname plus optionally, ":<port >"
string _sourceName; // a logical source name. string _sourceName; // a logical source name.
string sourceName() const { return _sourceName.empty() ? "main" : _ sourceName; } string sourceName() const { return _sourceName.empty() ? "main" : _ sourceName; }
string only; // only a certain db. note that in the sources collect ion, this may not be changed once you start replicating. string only; // only a certain db. note that in the sources collect ion, this may not be changed once you start replicating.
/* the last time point we have already synced up to (in the remote/ master's oplog). */ /* the last time point we have already synced up to (in the remote/ master's oplog). */
 End of changes. 2 change blocks. 
0 lines changed or deleted 6 lines changed or added


 match_details.h   match_details.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 <boost/scoped_ptr.hpp>
#include <string> #include <string>
namespace mongo { namespace mongo {
/** Reports information about a match request. */ /** Reports information about a match request. */
class MatchDetails { class MatchDetails {
public: public:
MatchDetails(); MatchDetails();
void resetOutput(); void resetOutput();
// for debugging only
std::string toString() const; std::string toString() const;
/** Request that an elemMatchKey be recorded. */ // relating to whether or not we had to load the full record
void requestElemMatchKey() { _elemMatchKeyRequested = true; }
bool needRecord() const { return _elemMatchKeyRequested; } void setLoadedRecord( bool loadedRecord ) { _loadedRecord = loadedR ecord; }
bool hasLoadedRecord() const { return _loadedRecord; } bool hasLoadedRecord() const { return _loadedRecord; }
bool hasElemMatchKey() const { return _elemMatchKeyFound; }
std::string elemMatchKey() const {
verify( hasElemMatchKey() );
return _elemMatchKey;
}
void setLoadedRecord( bool loadedRecord ) { _loadedRecord = loadedR // this name is wrong
ecord; }
void setElemMatchKey( const std::string &elemMatchKey ) { bool needRecord() const { return _elemMatchKeyRequested; }
if ( _elemMatchKeyRequested ) {
_elemMatchKeyFound = true; // if we need to store the offset into an array where we found the
_elemMatchKey = elemMatchKey; match
}
} /** Request that an elemMatchKey be recorded. */
void requestElemMatchKey() { _elemMatchKeyRequested = true; }
bool hasElemMatchKey() const;
std::string elemMatchKey() const;
void setElemMatchKey( const std::string &elemMatchKey );
private: private:
bool _loadedRecord; bool _loadedRecord;
bool _elemMatchKeyRequested; bool _elemMatchKeyRequested;
bool _elemMatchKeyFound; boost::scoped_ptr<std::string> _elemMatchKey;
std::string _elemMatchKey;
}; };
} }
 End of changes. 8 change blocks. 
18 lines changed or deleted 22 lines changed or added


 message_event.h   message_event.h 
skipping to change at line 20 skipping to change at line 20
* 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/base/string_data.h" #include "mongo/base/string_data.h"
#include "mongo/logger/log_severity.h" #include "mongo/logger/log_severity.h"
#include "mongo/platform/cstdint.h"
#include "mongo/util/time_support.h"
namespace mongo { namespace mongo {
namespace logger { namespace logger {
/** /**
* Free form text log message object that does not own the storage behi nd its message and * Free form text log message object that does not own the storage behi nd its message and
* contextName. * contextName.
* *
* Used and owned by one thread. This is the message type used by Mess ageLogDomain. * Used and owned by one thread. This is the message type used by Mess ageLogDomain.
*/ */
class MessageEventEphemeral { class MessageEventEphemeral {
public: public:
MessageEventEphemeral(LogSeverity severity, StringData contextName, MessageEventEphemeral(
StringData message) : Date_t date,
_severity(severity), _contextName(contextName), _message(messag LogSeverity severity,
e) {} StringData contextName,
StringData message) :
_date(date),
_severity(severity),
_contextName(contextName),
_message(message) {}
uint64_t getDate() const { return _date; }
LogSeverity getSeverity() const { return _severity; } LogSeverity getSeverity() const { return _severity; }
StringData getContextName() const { return _contextName; } StringData getContextName() const { return _contextName; }
StringData getMessage() const { return _message; } StringData getMessage() const { return _message; }
private: private:
Date_t _date;
LogSeverity _severity; LogSeverity _severity;
StringData _contextName; StringData _contextName;
StringData _message; StringData _message;
}; };
} // namespace logger } // namespace logger
} // namespace mongo } // namespace mongo
 End of changes. 4 change blocks. 
4 lines changed or deleted 13 lines changed or added


 message_event_utf8_encoder.h   message_event_utf8_encoder.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 <string>
#include "mongo/logger/encoder.h" #include "mongo/logger/encoder.h"
#include "mongo/logger/message_event.h" #include "mongo/logger/message_event.h"
#include "mongo/util/time_support.h"
namespace mongo { namespace mongo {
namespace logger { namespace logger {
/** /**
* Encoder that writes log messages of the style that MongoDB writes to console and files. * Encoder that writes log messages of the style that MongoDB writes to console and files.
*/ */
class MessageEventDetailsEncoder : public Encoder<MessageEventEphemeral > { class MessageEventDetailsEncoder : public Encoder<MessageEventEphemeral > {
public: public:
typedef std::string (*DateFormatter)(Date_t);
/**
* Sets the date formatter function for all instances of MessageEve
ntDetailsEncoder.
*
* Only and always safe to call during single-threaded execution, a
s in during start-up
* intiailization.
*/
static void setDateFormatter(DateFormatter dateFormatter);
/**
* Gets the date formatter function in use by instances of MessageE
ventDetailsEncoder.
*
* Always safe to call.
*/
static DateFormatter getDateFormatter();
virtual ~MessageEventDetailsEncoder(); virtual ~MessageEventDetailsEncoder();
virtual std::ostream& encode(const MessageEventEphemeral& event, st d::ostream& os); virtual std::ostream& encode(const MessageEventEphemeral& event, st d::ostream& os);
}; };
/** /**
* Encoder that generates log messages suitable for syslog. * Encoder that generates log messages suitable for syslog.
*/ */
class MessageEventWithContextEncoder : public Encoder<MessageEventEphem eral> { class MessageEventWithContextEncoder : public Encoder<MessageEventEphem eral> {
public: public:
virtual ~MessageEventWithContextEncoder(); virtual ~MessageEventWithContextEncoder();
 End of changes. 3 change blocks. 
0 lines changed or deleted 23 lines changed or added


 message_port.h   message_port.h 
skipping to change at line 39 skipping to change at line 39
class AbstractMessagingPort : boost::noncopyable { class AbstractMessagingPort : boost::noncopyable {
public: public:
AbstractMessagingPort() : tag(0), _connectionId(0) {} AbstractMessagingPort() : tag(0), _connectionId(0) {}
virtual ~AbstractMessagingPort() { } virtual ~AbstractMessagingPort() { }
virtual void reply(Message& received, Message& response, MSGID resp onseTo) = 0; // like the reply below, but doesn't rely on received.data sti ll being available virtual void reply(Message& received, Message& response, MSGID resp onseTo) = 0; // like the reply below, but doesn't rely on received.data sti ll being available
virtual void reply(Message& received, Message& response) = 0; virtual void reply(Message& received, Message& response) = 0;
virtual HostAndPort remote() const = 0; virtual HostAndPort remote() const = 0;
virtual unsigned remotePort() const = 0; virtual unsigned remotePort() const = 0;
virtual SockAddr remoteAddr() const = 0;
virtual SockAddr localAddr() const = 0;
long long connectionId() const { return _connectionId; } long long connectionId() const { return _connectionId; }
void setConnectionId( long long connectionId ); void setConnectionId( long long connectionId );
void setX509SubjectName(const std::string& x509SubjectName){ void setX509SubjectName(const std::string& x509SubjectName){
_x509SubjectName = x509SubjectName; _x509SubjectName = x509SubjectName;
} }
std::string getX509SubjectName(){ std::string getX509SubjectName(){
return _x509SubjectName; return _x509SubjectName;
skipping to change at line 105 skipping to change at line 107
* 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 happen * 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;
virtual SockAddr remoteAddr() const;
virtual SockAddr localAddr() const;
boost::shared_ptr<Socket> psock; boost::shared_ptr<Socket> psock;
void send( const char * data , int len, const char *context ) { void send( const char * data , int len, const char *context ) {
psock->send( data, len, context ); psock->send( data, len, 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 ) {
psock->send( data, context ); psock->send( data, context );
} }
bool connect(SockAddr& farEnd) { bool connect(SockAddr& farEnd) {
 End of changes. 2 change blocks. 
0 lines changed or deleted 4 lines changed or added


 metadata_loader.h   metadata_loader.h 
skipping to change at line 32 skipping to change at line 32
#include "mongo/client/dbclientinterface.h" #include "mongo/client/dbclientinterface.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
namespace mongo { namespace mongo {
class CollectionMetadata; class CollectionMetadata;
class CollectionType; class CollectionType;
class DBClientCursor; class DBClientCursor;
/** /**
* The MetadataLoader is responsible for interfacing with the config se * The MetadataLoader is responsible for interfacing with the config se
rvers and obtaining rvers and previous
* the data that CollectionMetadatas are made of. Effectively, the load * metadata to build new instances of CollectionMetadata. MetadataLoad
er is the "builder" er is the "builder"
* class for that metadata. * class for metadata.
*
* CollectionMetadata has both persisted and volatile state (for now) -
the persisted
* config server chunk state and the volatile pending state which is on
ly tracked locally
* while a server is the primary. This requires a two-step loading pro
cess - the persisted
* chunk state *cannot* be loaded in a DBWrite lock while the pending c
hunk state *must* be.
*
* Example usage:
* beforeMetadata = <get latest local metadata>;
* remoteMetadata = makeCollectionMetadata( beforeMetadata, remoteMetad
ata );
* DBWrite lock( ns );
* afterMetadata = <get latest local metadata>;
* promotePendingChunks( afterMetadata, remoteMetadata );
* *
* The loader will go out of its way to try to fetch the smaller amount possible of data * The loader will go out of its way to try to fetch the smaller amount possible of data
* from the config server without sacrificing the freshness and accurac y of the metadata it * from the config server without sacrificing the freshness and accurac y of the metadata it
* builds. (See ConfigDiffTracker class.) * builds. (See ConfigDiffTracker class.)
* *
* The class is not thread safe. * The class is not thread safe.
*/ */
class MetadataLoader { class MetadataLoader {
public: public:
skipping to change at line 60 skipping to change at line 72
explicit MetadataLoader( const ConnectionString& configLoc ); explicit MetadataLoader( const ConnectionString& configLoc );
~MetadataLoader(); ~MetadataLoader();
/** /**
* Fills a new metadata instance representing the chunkset of the c ollection 'ns' * Fills a new metadata instance representing the chunkset of the c ollection 'ns'
* (or its entirety, if not sharded) that lives on 'shard' with dat a from the config server. * (or its entirety, if not sharded) that lives on 'shard' with dat a from the config server.
* Optionally, uses an 'oldMetadata' for the same 'ns'/'shard'; the contents of * Optionally, uses an 'oldMetadata' for the same 'ns'/'shard'; the contents of
* 'oldMetadata' can help reducing the amount of data read from the config servers. * 'oldMetadata' can help reducing the amount of data read from the config servers.
* *
* Locking note:
* + Must not be called in a DBLock, since this loads over the n
etwork
*
* OK on success. * OK on success.
* *
* Failure return values: * Failure return values:
* Abnormal: * Abnormal:
* @return FailedToParse if there was an error parsing the remote c onfig data * @return FailedToParse if there was an error parsing the remote c onfig data
* Normal: * Normal:
* @return NamespaceNotFound if the collection no longer exists * @return NamespaceNotFound if the collection no longer exists
* @return HostUnreachable if there was an error contacting the con fig servers * @return HostUnreachable if there was an error contacting the con fig servers
* @return RemoteChangeDetected if the data loaded was modified by another operation * @return RemoteChangeDetected if the data loaded was modified by another operation
*/ */
Status makeCollectionMetadata( const string& ns, Status makeCollectionMetadata( const string& ns,
const string& shard, const string& shard,
const CollectionMetadata* oldMetadat a, const CollectionMetadata* oldMetadat a,
CollectionMetadata* metadata ) const ; CollectionMetadata* metadata ) const ;
/**
* Replaces the pending chunks of the remote metadata with the more
up-to-date pending
* chunks of the 'after' metadata (metadata from after the remote l
oad), and removes pending
* chunks which are now regular chunks.
*
* Pending chunks should always correspond to one or zero chunks in
the remoteMetadata
* if the epochs are the same and the remote version is the same or
higher, otherwise they
* are not applicable.
*
* Locking note:
* + Must be called in a DBLock, to ensure validity of afterMeta
data
*
* Returns OK if pending chunks correctly follow the rule above or
are not applicable
* Returns RemoteChangeDetected if pending chunks do not follow the
rule above, indicating
* either the config server or us has
changed unexpectedly.
* This should only occur with manual
editing of the config
* server.
*
* TODO: This is a bit ugly but necessary for now. If/when pendin
g chunk info is stored on
* the config server, this should go away.
*/
Status promotePendingChunks( const CollectionMetadata* afterMetadat
a,
CollectionMetadata* remoteMetadata ) c
onst;
private: private:
ConnectionString _configLoc; ConnectionString _configLoc;
/** /**
* Returns OK and fills in the internal state of 'metadata' with ge neral collection * Returns OK and fills in the internal state of 'metadata' with ge neral collection
* information, not including chunks. * information, not including chunks.
* *
* If information about the collection can be accessed or is invali d, returns: * If information about the collection can be accessed or is invali d, returns:
* @return NamespaceNotFound if the collection no longer exists * @return NamespaceNotFound if the collection no longer exists
* @return FailedToParse if there was an error parsing the remote c onfig data * @return FailedToParse if there was an error parsing the remote c onfig data
skipping to change at line 101 skipping to change at line 140
CollectionMetadata* metadata ) const; CollectionMetadata* metadata ) const;
/** /**
* Returns OK and fills in the chunk state of 'metadata' to portray the chunks of the * Returns OK and fills in the chunk state of 'metadata' to portray the chunks of the
* collection 'ns' that sit in 'shard'. If provided, uses the conte nts of 'oldMetadata' * collection 'ns' that sit in 'shard'. If provided, uses the conte nts of 'oldMetadata'
* as a base (see description in initCollection above). * as a base (see description in initCollection above).
* *
* If information about the chunks can be accessed or is invalid, r eturns: * If information about the chunks can be accessed or is invalid, r eturns:
* @return HostUnreachable if there was an error contacting the con fig servers * @return HostUnreachable if there was an error contacting the con fig servers
* @return RemoteChangeDetected if the chunks loaded are unexpected ly different * @return RemoteChangeDetected if the chunks loaded are unexpected ly different
*
* For backwards compatibility,
* @return NamespaceNotFound if there are no chunks loaded and an e
poch change is detected
* TODO: @return FailedToParse * TODO: @return FailedToParse
*/ */
Status initChunks( const string& ns, Status initChunks( const string& ns,
const string& shard, const string& shard,
const CollectionMetadata* oldMetadata, const CollectionMetadata* oldMetadata,
CollectionMetadata* metadata ) const; CollectionMetadata* metadata ) const;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 4 change blocks. 
5 lines changed or deleted 66 lines changed or added


 misc.h   misc.h 
skipping to change at line 28 skipping to change at line 28
*/ */
#pragma once #pragma once
#include <ctime> #include <ctime>
#include <limits> #include <limits>
#include <string> #include <string>
#include "mongo/platform/cstdint.h" #include "mongo/platform/cstdint.h"
#include "mongo/util/assert_util.h" #include "mongo/util/assert_util.h"
#include "mongo/util/time_support.h"
namespace mongo { namespace mongo {
inline void time_t_to_String(time_t t, char *buf) {
#if defined(_WIN32)
ctime_s(buf, 32, &t);
#else
ctime_r(&t, buf);
#endif
buf[24] = 0; // don't want the \n
}
inline std::string time_t_to_String(time_t t = time(0) ) {
char buf[64];
#if defined(_WIN32)
ctime_s(buf, sizeof(buf), &t);
#else
ctime_r(&t, buf);
#endif
buf[24] = 0; // don't want the \n
return buf;
}
inline std::string time_t_to_String_no_year(time_t t) {
char buf[64];
#if defined(_WIN32)
ctime_s(buf, sizeof(buf), &t);
#else
ctime_r(&t, buf);
#endif
buf[19] = 0;
return buf;
}
inline std::string time_t_to_String_short(time_t t) {
char buf[64];
#if defined(_WIN32)
ctime_s(buf, sizeof(buf), &t);
#else
ctime_r(&t, buf);
#endif
buf[19] = 0;
if( buf[0] && buf[1] && buf[2] && buf[3] )
return buf + 4; // skip day of week
return buf;
}
struct Date_t {
// TODO: make signed (and look for related TODO's)
unsigned long long millis;
Date_t(): millis(0) {}
Date_t(unsigned long long m): millis(m) {}
operator unsigned long long&() { return millis; }
operator const unsigned long long&() const { return millis; }
void toTm (tm *buf) {
time_t dtime = toTimeT();
#if defined(_WIN32)
gmtime_s(buf, &dtime);
#else
gmtime_r(&dtime, buf);
#endif
}
std::string toString() const {
char buf[64];
time_t_to_String(toTimeT(), buf);
return buf;
}
time_t toTimeT() const {
// cant use uassert from bson/util
verify((long long)millis >= 0); // TODO when millis is signed,
delete
verify(((long long)millis/1000) < (std::numeric_limits<time_t>:
:max)());
return millis / 1000;
}
int64_t asInt64() {
return static_cast<int64_t>(millis);
}
};
// Like strlen, but only scans up to n bytes. // Like strlen, but only scans up to n bytes.
// Returns -1 if no '0' found. // Returns -1 if no '0' found.
inline int strnlen( const char *s, int n ) { inline int strnlen( const char *s, int n ) {
for( int i = 0; i < n; ++i ) for( int i = 0; i < n; ++i )
if ( !s[ i ] ) if ( !s[ i ] )
return i; return i;
return -1; return -1;
} }
} }
 End of changes. 2 change blocks. 
77 lines changed or deleted 1 lines changed or added


 mmap.h   mmap.h 
skipping to change at line 100 skipping to change at line 100
static set<MongoFile*>& getAllFiles(); 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 isDurableMappedFile() { return false; }
string filename() const { return _filename; } string filename() const { return _filename; }
void setFilename(const std::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;
skipping to change at line 132 skipping to change at line 132
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;
}; };
/** 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"); DurableMappedFile *a = finder.find("file_name_a");
MongoMMF *b = finder.find("file_name_b"); DurableMappedFile *b = finder.find("file_name_b");
*/ */
class MongoFileFinder : boost::noncopyable { class MongoFileFinder : boost::noncopyable {
public: public:
/** @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(const std::string& path) const; MongoFile* findByPath(const std::string& path) const;
private: private:
LockMongoFilesShared _lk; LockMongoFilesShared _lk;
skipping to change at line 226 skipping to change at line 226
#else #else
void clearWritableBits(void *privateView) { } void clearWritableBits(void *privateView) { }
#endif #endif
protected: protected:
/** 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;
/** 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;
const set<MongoFile*>& mmfiles = MongoFile::getAllFiles(); const set<MongoFile*>& mmfiles = MongoFile::getAllFiles();
for ( set<MongoFile*>::const_iterator i = mmfiles.begin(); i != mmf iles.end(); i++ ) for ( set<MongoFile*>::const_iterator i = mmfiles.begin(); i != mmf iles.end(); i++ )
p(*i); p(*i);
} }
#if defined(_WIN32) #if defined(_WIN32)
 End of changes. 3 change blocks. 
5 lines changed or deleted 3 lines changed or added


 mock_stage.h   mock_stage.h 
skipping to change at line 52 skipping to change at line 52
virtual StageState work(WorkingSetID* out); virtual StageState work(WorkingSetID* out);
virtual bool isEOF(); virtual bool isEOF();
// These don't really mean anything here. // These don't really mean anything here.
// Some day we could count the # of calls to the yield functions to check that other stages // Some day we could count the # of calls to the yield functions to check that other stages
// have correct yielding behavior. // have correct yielding behavior.
virtual void prepareToYield() { } virtual void prepareToYield() { }
virtual void recoverFromYield() { } virtual void recoverFromYield() { }
virtual void invalidate(const DiskLoc& dl) { } virtual void invalidate(const DiskLoc& dl) { }
virtual PlanStageStats* getStats() { return NULL; }
/** /**
* Add a result to the back of the queue. work() goes through the queue. * Add a result to the back of the queue. work() goes through the queue.
* Either no data is returned (just a state), or... * Either no data is returned (just a state), or...
*/ */
void pushBack(const PlanStage::StageState state); void pushBack(const PlanStage::StageState state);
/** /**
* ...data is returned (and we ADVANCED) * ...data is returned (and we ADVANCED)
*/ */
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 lines changed or added


 modifier_add_to_set.h   modifier_add_to_set.h 
skipping to change at line 28 skipping to change at line 28
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/bson/mutable/document.h" #include "mongo/bson/mutable/document.h"
#include "mongo/db/field_ref.h" #include "mongo/db/field_ref.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
namespace mongo { namespace mongo {
class LogBuilder;
class ModifierAddToSet : public ModifierInterface { class ModifierAddToSet : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierAddToSet); MONGO_DISALLOW_COPYING(ModifierAddToSet);
public: public:
ModifierAddToSet(); ModifierAddToSet();
virtual ~ModifierAddToSet(); virtual ~ModifierAddToSet();
/** Goes over the array item(s) that are going to be set- unioned a nd converts them /** Goes over the array item(s) that are going to be set- unioned a nd converts them
* internally to a mutable bson. Both single and $each forms are s upported. Returns OK * internally to a mutable bson. Both single and $each forms are s upported. Returns OK
* if the item(s) are valid otherwise returns a status describing the error. * if the item(s) are valid otherwise returns a status describing the error.
*/ */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
/** Decides which portion of the array items that are going to be s et-unioned to root's /** Decides which portion of the array items that are going to be s et-unioned to root's
* document and fills in 'execInfo' accordingly. Returns OK if the document has a * document and fills in 'execInfo' accordingly. Returns OK if the document has a
* valid array to set-union to, othwise returns a status describin g the error. * valid array to set-union to, othwise returns a status describin g the error.
*/ */
virtual Status prepare(mutablebson::Element root, virtual Status prepare(mutablebson::Element root,
const StringData& matchedField, const StringData& matchedField,
ExecInfo* execInfo); ExecInfo* execInfo);
/** Updates the Element used in prepare with the effects of the $ad dToSet operation. */ /** Updates the Element used in prepare with the effects of the $ad dToSet operation. */
virtual Status apply() const; virtual Status apply() const;
/** Converts the effects of this $addToSet into one or more equival ent $set operations. */ /** Converts the effects of this $addToSet into one or more equival ent $set operations. */
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
// Access to each component of fieldName that's the target of this mod. // Access to each component of fieldName that's the target of this mod.
FieldRef _fieldRef; FieldRef _fieldRef;
// 0 or index for $-positional in _fieldRef. // 0 or index for $-positional in _fieldRef.
size_t _posDollar; size_t _posDollar;
// Array of values to be set-union'ed onto target. // Array of values to be set-union'ed onto target.
mutablebson::Document _valDoc; mutablebson::Document _valDoc;
 End of changes. 3 change blocks. 
2 lines changed or deleted 4 lines changed or added


 modifier_bit.h   modifier_bit.h 
skipping to change at line 21 skipping to change at line 21
* 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 <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <string> #include <string>
#include <vector>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/bson/mutable/element.h" #include "mongo/bson/mutable/element.h"
#include "mongo/db/field_ref.h" #include "mongo/db/field_ref.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
#include "mongo/util/safe_num.h" #include "mongo/util/safe_num.h"
namespace mongo { namespace mongo {
class LogBuilder;
class ModifierBit : public ModifierInterface { class ModifierBit : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierBit); MONGO_DISALLOW_COPYING(ModifierBit);
public: public:
ModifierBit(); ModifierBit();
virtual ~ModifierBit(); virtual ~ModifierBit();
/** /**
* A 'modExpr' is a BSONElement {<fieldname>: <value>} coming from a $bit mod such as * A 'modExpr' is a BSONElement {<fieldname>: <value>} coming from a $bit mod such as
* {$bit: {<field: { [and|or] : <value>}}. init() extracts the fiel d name, the * {$bit: {<field: { [and|or] : <value>}}. init() extracts the fiel d name, the
* operation subtype, and the value to be assigned to it from 'modE xpr'. It returns OK * operation subtype, and the value to be assigned to it from 'modE xpr'. It returns OK
* if successful or a status describing the error. * if successful or a status describing the error.
*/ */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
/** Validates the potential application of the init'ed mod to the g iven Element and /** Validates the potential application of the init'ed mod to the g iven Element and
* configures the internal state of the mod as necessary. * configures the internal state of the mod as necessary.
*/ */
virtual Status prepare(mutablebson::Element root, virtual Status prepare(mutablebson::Element root,
const StringData& matchedField, const StringData& matchedField,
ExecInfo* execInfo); ExecInfo* execInfo);
/** Updates the Element used in prepare with the effects of the $bi t operation */ /** Updates the Element used in prepare with the effects of the $bi t operation */
virtual Status apply() const; virtual Status apply() const;
/** Converts the effects of this $bit into an equivalent $set */ /** Converts the effects of this $bit into an equivalent $set */
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
SafeNum apply(SafeNum value) const;
// Access to each component of fieldName that's the target of this mod. // Access to each component of fieldName that's the target of this mod.
FieldRef _fieldRef; FieldRef _fieldRef;
// 0 or index for $-positional in _fieldRef. // 0 or index for $-positional in _fieldRef.
size_t _posDollar; size_t _posDollar;
// Value to be $bit'ed onto target
SafeNum _val;
// The operator on SafeNum that we will invoke. // The operator on SafeNum that we will invoke.
SafeNum (SafeNum::* _op)(const SafeNum&) const; typedef SafeNum (SafeNum::* SafeNumOp)(const SafeNum&) const;
struct OpEntry {
SafeNum val;
SafeNumOp op;
};
typedef std::vector<OpEntry> OpEntries;
OpEntries _ops;
struct PreparedState; struct PreparedState;
scoped_ptr<PreparedState> _preparedState; scoped_ptr<PreparedState> _preparedState;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 7 change blocks. 
6 lines changed or deleted 17 lines changed or added


 modifier_inc.h   modifier_inc.h 
skipping to change at line 29 skipping to change at line 29
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <string> #include <string>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/bson/mutable/element.h" #include "mongo/bson/mutable/element.h"
#include "mongo/db/field_ref.h" #include "mongo/db/field_ref.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
namespace mongo { namespace mongo {
class LogBuilder;
class ModifierInc : public ModifierInterface { class ModifierInc : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierInc); MONGO_DISALLOW_COPYING(ModifierInc);
public: public:
ModifierInc(); // TODO: This is a shortcut to implementing $mul by hijacking $inc.
In the near future,
// we should consider either pulling $mul into its own operator, or
creating a general
// purpose "numeric binary op" operator. Potentially, that operator
could also subsume
// $bit (thought there are some subtleties, like that $bit can have
multiple
// operations, and doing so with arbirary math operations introduce
s potential
// associativity difficulties). At the very least, if this mechanis
m is retained, then
// this class should be renamed at some point away from ModifierInc
.
enum ModifierIncMode {
MODE_INC,
MODE_MUL
};
ModifierInc(ModifierIncMode mode = MODE_INC);
virtual ~ModifierInc(); virtual ~ModifierInc();
/** /**
* A 'modExpr' is a BSONElement {<fieldname>: <value>} coming from a $inc mod such as * A 'modExpr' is a BSONElement {<fieldname>: <value>} coming from a $inc mod such as
* {$inc: {<fieldname: <value>}}. init() extracts the field name an d the value to be * {$inc: {<fieldname: <value>}}. init() extracts the field name an d the value to be
* assigned to it from 'modExpr'. It returns OK if successful or a status describing * assigned to it from 'modExpr'. It returns OK if successful or a status describing
* the error. * the error.
*/ */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
/** Evaluates the validity of applying $inc to the identified node, and computes /** Evaluates the validity of applying $inc to the identified node, and computes
* effects, handling upcasting and overflow as necessary. * effects, handling upcasting and overflow as necessary.
*/ */
virtual Status prepare(mutablebson::Element root, virtual Status prepare(mutablebson::Element root,
const StringData& matchedField, const StringData& matchedField,
ExecInfo* execInfo); ExecInfo* execInfo);
/** Updates the node passed in prepare with the results of the $inc */ /** Updates the node passed in prepare with the results of the $inc */
virtual Status apply() const; virtual Status apply() const;
/** Converts the result of the $inc into an equivalent $set under l ogRoot */ /** Converts the result of the $inc into an equivalent $set under l ogRoot */
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
const ModifierIncMode _mode;
// Access to each component of fieldName that's the target of this mod. // Access to each component of fieldName that's the target of this mod.
FieldRef _fieldRef; FieldRef _fieldRef;
// 0 or index for $-positional in _fieldRef. // 0 or index for $-positional in _fieldRef.
size_t _posDollar; size_t _posDollar;
// Element of the $set expression. // Element of the $set expression.
SafeNum _val; SafeNum _val;
 End of changes. 5 change blocks. 
3 lines changed or deleted 25 lines changed or added


 modifier_interface.h   modifier_interface.h 
skipping to change at line 27 skipping to change at line 27
#pragma once #pragma once
#include "mongo/base/status.h" #include "mongo/base/status.h"
#include "mongo/base/string_data.h" #include "mongo/base/string_data.h"
#include "mongo/bson/mutable/element.h" #include "mongo/bson/mutable/element.h"
#include "mongo/db/field_ref.h" #include "mongo/db/field_ref.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
namespace mongo { namespace mongo {
class LogBuilder;
/** /**
* Abstract base class for update "modifiers" (a.k.a "$ operators"). To create a new * Abstract base class for update "modifiers" (a.k.a "$ operators"). To create a new
* operator, implement a new derived class. * operator, implement a new derived class.
* *
* A typical call sequence for the class is: * A typical call sequence for the class is:
* *
* + init() with the mod arguments * + init() with the mod arguments
* *
* + For each document that is being touched on that update, the foll owing methods are * + For each document that is being touched on that update, the foll owing methods are
* going to be called once for that document and in the order the c alls appear here. * going to be called once for that document and in the order the c alls appear here.
skipping to change at line 55 skipping to change at line 57
* that particular order and therefore can keep and reuse state between these calls, when * that particular order and therefore can keep and reuse state between these calls, when
* appropriate. * appropriate.
* *
* TODO: * TODO:
* For a reference implementation, see modifier_identity.{h,cpp} used i n tests. * For a reference implementation, see modifier_identity.{h,cpp} used i n tests.
*/ */
class ModifierInterface { class ModifierInterface {
public: public:
virtual ~ModifierInterface() { } virtual ~ModifierInterface() { }
struct Options;
/** /**
* Returns OK and extracts the parameters for this given mod from ' modExpr'. For * Returns OK and extracts the parameters for this given mod from ' modExpr'. For
* instance, for a $inc, extracts the increment value. The init() m ethod would be * instance, for a $inc, extracts the increment value. The init() m ethod would be
* called only once per operand, that is, if a { $inc: { a: 1, b: 1 } } is issued, * called only once per operand, that is, if a { $inc: { a: 1, b: 1 } } is issued,
* there would be one instance of the operator working on 'a' and o ne on 'b'. In each * there would be one instance of the operator working on 'a' and o ne on 'b'. In each
* case, init() would be called once with the respective bson eleme nt. * case, init() would be called once with the respective bson eleme nt.
* *
* If 'modExpr' is invalid, returns an error status with a reason d escription. * If 'modExpr' is invalid, returns an error status with a reason d escription.
* *
* Note: * Note:
* *
* + An operator may assume the modExpr passed here will be uncha nged throughout all * + An operator may assume the modExpr passed here will be uncha nged throughout all
* the mod object lifetime and also that the modExrp's lifetime exceeds the life * the mod object lifetime and also that the modExrp's lifetime exceeds the life
* time of this mod. Therefore, taking references to elements i nside modExpr is * time of this mod. Therefore, taking references to elements i nside modExpr is
* valid. * valid.
*/ */
virtual Status init(const BSONElement& modExpr) = 0; virtual Status init(const BSONElement& modExpr, const Options& opts ) = 0;
/** /**
* Returns OK if it would be correct to apply this mod over the doc ument 'root' (e.g, if * Returns OK if it would be correct to apply this mod over the doc ument 'root' (e.g, if
* we're $inc-ing a field, is that field numeric in the current doc ?). * we're $inc-ing a field, is that field numeric in the current doc ?).
* *
* If the field this mod is targeted to contains a $-positional par ameter, that value * If the field this mod is targeted to contains a $-positional par ameter, that value
* can be bound with 'matchedField', passed by the caller. * can be bound with 'matchedField', passed by the caller.
* *
* In addition, the call also identifies which fields(s) of 'root' the mod is interested * In addition, the call also identifies which fields(s) of 'root' the mod is interested
* in changing (note that the modifier may want to add a field that 's not present in * in changing (note that the modifier may want to add a field that 's not present in
skipping to change at line 107 skipping to change at line 110
* per operator. * per operator.
* *
* For this call to be issued, the call to 'prepareElem' must have necessarily turned * For this call to be issued, the call to 'prepareElem' must have necessarily turned
* off 'ExecInfo.noOp', ie this mod over this document is not a no- op. * off 'ExecInfo.noOp', ie this mod over this document is not a no- op.
* *
* If the mod could not be applied, returns an error status with a reason description. * If the mod could not be applied, returns an error status with a reason description.
*/ */
virtual Status apply() const = 0 ; virtual Status apply() const = 0 ;
/** /**
* Returns OK and registers the result of this mod in 'logRoot', th * Returns OK and records the result of this mod in the provided Lo
e document that gBuilder. The mod
* would eventually become a log entry. The mod must have kept enou * must have kept enough state to be able to produce the log record
gh state to (see idempotency
* be able to produce the log record (see idempotency note below). * note below). This call may be issued even if apply() was not.
This call may be
* issued even if apply() was not.
* *
* If the mod could not be logged, returns an error status with a r eason description. * If the mod could not be logged, returns an error status with a r eason description.
* *
* Idempotency Note: * Idempotency Note:
* *
* + The modifier must log a mod that is idempotent, ie, applying it more than once * + The modifier must log a mod that is idempotent, ie, applying it more than once
* to a base collection would produce the same result as applyi ng it only once. For * to a base collection would produce the same result as applyi ng it only once. For
* example, a $inc can be switched to a $set for the resulting incremented value, * example, a $inc can be switched to a $set for the resulting incremented value,
* for logging purposes. An array based operator may check the contents of the * for logging purposes. An array based operator may check the contents of the
* array before operating on it. * array before operating on it.
*/ */
virtual Status log(mutablebson::Element logRoot) const = 0; virtual Status log(LogBuilder* logBuilder) const = 0;
};
/**
* Options used to control Modifier behavior
*/
struct ModifierInterface::Options {
Options() : fromReplication(false), enforceOkForStorage(true) {}
Options(bool repl, bool ofs) : fromReplication(repl), enforceOkForS
torage(ofs) {}
static Options normal() { return Options(false, true); }
static Options fromRepl() { return Options(true, false); }
static Options unchecked() { return Options(false, false); }
bool fromReplication;
bool enforceOkForStorage;
}; };
struct ModifierInterface::ExecInfo { struct ModifierInterface::ExecInfo {
static const int MAX_NUM_FIELDS = 2; static const int MAX_NUM_FIELDS = 2;
/** /**
* An update mod may specify that it wishes to the applied only if the context * An update mod may specify that it wishes to the applied only if the context
* of the update turns out a certain way. * of the update turns out a certain way.
*/ */
enum UpdateContext { enum UpdateContext {
// This mod wants to be applied only if the update turns out to be an insert. // This mod wants to be applied only if the update turns out to be an insert.
INSERT_CONTEXT, INSERT_CONTEXT,
// This mod wants to be applied only if the update is not an in sert. // This mod wants to be applied only if the update is not an in sert.
UPDATE_CONTEXT, UPDATE_CONTEXT,
// This mod doesn't care if the update will be an update or an upsert. // This mod doesn't care if the update will be an update or an upsert.
ANY_CONTEXT ANY_CONTEXT
}; };
ExecInfo() : inPlace(false), noOp(false), context(ANY_CONTEXT) { ExecInfo() : noOp(false), context(ANY_CONTEXT) {
for (int i = 0; i < MAX_NUM_FIELDS; i++) { for (int i = 0; i < MAX_NUM_FIELDS; i++) {
fieldRef[i] = NULL; fieldRef[i] = NULL;
} }
} }
// The fields of concern to the driver: no other op may modify the fields listed here. // The fields of concern to the driver: no other op may modify the fields listed here.
FieldRef* fieldRef[MAX_NUM_FIELDS]; // not owned here FieldRef* fieldRef[MAX_NUM_FIELDS]; // not owned here
bool inPlace;
bool noOp; bool noOp;
UpdateContext context; UpdateContext context;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 8 change blocks. 
11 lines changed or deleted 26 lines changed or added


 modifier_object_replace.h   modifier_object_replace.h 
skipping to change at line 27 skipping to change at line 27
#pragma once #pragma once
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h" #include "mongo/base/status.h"
#include "mongo/bson/mutable/element.h" #include "mongo/bson/mutable/element.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
namespace mongo { namespace mongo {
class LogBuilder;
class ModifierObjectReplace : public ModifierInterface { class ModifierObjectReplace : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierObjectReplace); MONGO_DISALLOW_COPYING(ModifierObjectReplace);
public: public:
ModifierObjectReplace(); ModifierObjectReplace();
// //
// Modifier interface implementation // Modifier interface implementation
// //
virtual ~ModifierObjectReplace(); virtual ~ModifierObjectReplace();
/** /**
* Returns true and takes the embedded object contained in 'modExpr ' to be the object * Returns true and takes the embedded object contained in 'modExpr ' to be the object
* we're replacing for. The field name of 'modExpr' is ignored. If 'modExpr' is in an * we're replacing for. The field name of 'modExpr' is ignored. If 'modExpr' is in an
* unexpected format or if it can't be parsed for some reason, retu rns an error status * unexpected format or if it can't be parsed for some reason, retu rns an error status
* describing the error. * describing the error.
*/ */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
/** /**
* Registers the that 'root' is in the document that we want to ful ly replace. * Registers the that 'root' is in the document that we want to ful ly replace.
* prepare() returns OK and always fills 'execInfo' with false for inPlace and true for * prepare() returns OK and always fills 'execInfo' with true for
* noOp. * noOp.
*/ */
virtual Status prepare(mutablebson::Element root, virtual Status prepare(mutablebson::Element root,
const StringData& matchedField, const StringData& matchedField,
ExecInfo* execInfo); ExecInfo* execInfo);
/** /**
* Replaces the document passed in prepare() for the object passed in init(). Returns * Replaces the document passed in prepare() for the object passed in init(). Returns
* OK if successful or a status describing the error. * OK if successful or a status describing the error.
*/ */
virtual Status apply() const; virtual Status apply() const;
/** /**
* Adds a log entry to logRoot corresponding to full object replace ment. Returns OK if * Adds a log entry to logRoot corresponding to full object replace ment. Returns OK if
* successful or a status describing the error. * successful or a status describing the error.
*/ */
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
// Object to replace with. // Object to replace with.
BSONObj _val; BSONObj _val;
// The document whose value needs to be replaced. This state is val id after a prepare() // The document whose value needs to be replaced. This state is val id after a prepare()
// was issued and until a log() is issued. The document this mod is being prepared // was issued and until a log() is issued. The document this mod is being prepared
// against must e live throughout all the calls. // against must e live throughout all the calls.
struct PreparedState; struct PreparedState;
 End of changes. 4 change blocks. 
3 lines changed or deleted 5 lines changed or added


 modifier_pop.h   modifier_pop.h 
skipping to change at line 30 skipping to change at line 30
#include <string> #include <string>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/bson/mutable/element.h" #include "mongo/bson/mutable/element.h"
#include "mongo/db/field_ref.h" #include "mongo/db/field_ref.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
namespace mongo { namespace mongo {
class LogBuilder;
class ModifierPop : public ModifierInterface { class ModifierPop : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierPop); MONGO_DISALLOW_COPYING(ModifierPop);
public: public:
ModifierPop(); ModifierPop();
virtual ~ModifierPop(); virtual ~ModifierPop();
/** /**
* The format of this modifier ($pop) is {<fieldname>: <value>}. * The format of this modifier ($pop) is {<fieldname>: <value>}.
* If the value is number and greater than -1 then an element is re moved from the bottom, * If the value is number and greater than -1 then an element is re moved from the bottom,
* otherwise the top. Currently the value can be any anything but w e document * otherwise the top. Currently the value can be any anything but w e document
* the use of the numbers "1, -1" only. * the use of the numbers "1, -1" only.
* *
* Ex. $pop: {'a':1} will remove the last item from this array: [1, 2,3] -> [1,2] * Ex. $pop: {'a':1} will remove the last item from this array: [1, 2,3] -> [1,2]
*/ */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
virtual Status prepare(mutablebson::Element root, virtual Status prepare(mutablebson::Element root,
const StringData& matchedField, const StringData& matchedField,
ExecInfo* execInfo); ExecInfo* execInfo);
virtual Status apply() const; virtual Status apply() const;
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
// Access to each component of fieldName that's the target of this mod. // Access to each component of fieldName that's the target of this mod.
FieldRef _fieldRef; FieldRef _fieldRef;
// 0 or index for $-positional in _fieldRef. // 0 or index for $-positional in _fieldRef.
size_t _positionalPathIndex; size_t _positionalPathIndex;
// element position to remove from // element position to remove from
 End of changes. 3 change blocks. 
2 lines changed or deleted 4 lines changed or added


 modifier_pull.h   modifier_pull.h 
skipping to change at line 38 skipping to change at line 38
class MatchExpression; class MatchExpression;
class ModifierPull : public ModifierInterface { class ModifierPull : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierPull); MONGO_DISALLOW_COPYING(ModifierPull);
public: public:
ModifierPull(); ModifierPull();
virtual ~ModifierPull(); virtual ~ModifierPull();
/** Evaluates the array items to be removed and the match expressio n. */ /** Evaluates the array items to be removed and the match expressio n. */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
/** Decides which portion of the array items will be removed from t he provided element */ /** Decides which portion of the array items will be removed from t he provided element */
virtual Status prepare(mutablebson::Element root, virtual Status prepare(mutablebson::Element root,
const StringData& matchedField, const StringData& matchedField,
ExecInfo* execInfo); ExecInfo* execInfo);
/** Updates the Element used in prepare with the effects of the $pu ll operation. */ /** Updates the Element used in prepare with the effects of the $pu ll operation. */
virtual Status apply() const; virtual Status apply() const;
/** Converts the effects of this $pull into one or more equivalent $unset operations. */ /** Converts the effects of this $pull into one or more equivalent $unset operations. */
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
bool isMatch(mutablebson::ConstElement element);
// Access to each component of fieldName that's the target of this mod. // Access to each component of fieldName that's the target of this mod.
FieldRef _fieldRef; FieldRef _fieldRef;
// 0 or index for $-positional in _fieldRef. // 0 or index for $-positional in _fieldRef.
size_t _posDollar; size_t _posDollar;
// A matcher built from the modExpr that we use to identify element // If we aren't using a matcher, we just keep modExpr as _exprElt a
s to remove. nd use that to match
// with woCompare.
BSONElement _exprElt;
// If we are using a matcher, we need to keep around a BSONObj for
it.
BSONObj _exprObj; BSONObj _exprObj;
scoped_ptr<MatchExpression> _matchExpression;
// If we are using the matcher, this is the match expression we bui
lt around _exprObj.
scoped_ptr<MatchExpression> _matchExpr;
bool _matcherOnPrimitive;
struct PreparedState; struct PreparedState;
scoped_ptr<PreparedState> _preparedState; scoped_ptr<PreparedState> _preparedState;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 5 change blocks. 
5 lines changed or deleted 16 lines changed or added


 modifier_pull_all.h   modifier_pull_all.h 
skipping to change at line 30 skipping to change at line 30
#include <string> #include <string>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/bson/mutable/element.h" #include "mongo/bson/mutable/element.h"
#include "mongo/db/field_ref.h" #include "mongo/db/field_ref.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
namespace mongo { namespace mongo {
class LogBuilder;
class ModifierPullAll : public ModifierInterface { class ModifierPullAll : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierPullAll); MONGO_DISALLOW_COPYING(ModifierPullAll);
public: public:
ModifierPullAll(); ModifierPullAll();
virtual ~ModifierPullAll(); virtual ~ModifierPullAll();
/** /**
* The modifier $pullAll takes an array of values to match literall y, and remove * The modifier $pullAll takes an array of values to match literall y, and remove
* *
* Ex. {$pullAll : {<field> : [<values>]}} * Ex. {$pullAll : {<field> : [<values>]}}
* {$pullAll :{ array : [1,2] } } will transform {array: [1,2,3]} - > {array: [3]} * {$pullAll :{ array : [1,2] } } will transform {array: [1,2,3]} - > {array: [3]}
*/ */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
virtual Status prepare(mutablebson::Element root, virtual Status prepare(mutablebson::Element root,
const StringData& matchedField, const StringData& matchedField,
ExecInfo* execInfo); ExecInfo* execInfo);
virtual Status apply() const; virtual Status apply() const;
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
// Access to each component of fieldName that's the target of this mod. // Access to each component of fieldName that's the target of this mod.
FieldRef _fieldRef; FieldRef _fieldRef;
// 0 or index for $-positional in _fieldRef. // 0 or index for $-positional in _fieldRef.
size_t _positionalPathIndex; size_t _positionalPathIndex;
// The instance of the field in the provided doc. // The instance of the field in the provided doc.
 End of changes. 3 change blocks. 
2 lines changed or deleted 4 lines changed or added


 modifier_push.h   modifier_push.h 
skipping to change at line 31 skipping to change at line 31
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/bson/mutable/element.h" #include "mongo/bson/mutable/element.h"
#include "mongo/db/field_ref.h" #include "mongo/db/field_ref.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
#include "mongo/db/ops/modifier_push_sorter.h" #include "mongo/db/ops/modifier_push_sorter.h"
namespace mongo { namespace mongo {
class LogBuilder;
class ModifierPush : public ModifierInterface { class ModifierPush : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierPush); MONGO_DISALLOW_COPYING(ModifierPush);
public: public:
enum ModifierPushMode { PUSH_NORMAL, PUSH_ALL }; enum ModifierPushMode { PUSH_NORMAL, PUSH_ALL };
explicit ModifierPush(ModifierPushMode mode= PUSH_NORMAL); explicit ModifierPush(ModifierPushMode mode= PUSH_NORMAL);
// //
// Modifier interface implementation // Modifier interface implementation
skipping to change at line 60 skipping to change at line 62
* *
* There are currently a few restrictions concerning the clauses (b ut all can be * There are currently a few restrictions concerning the clauses (b ut all can be
* lifted): * lifted):
* + $slice can be negative only (ie, slicing from the recent end ) * + $slice can be negative only (ie, slicing from the recent end )
* + $sort requires $slice to be present * + $sort requires $slice to be present
* + $sort can only sort objects (as opposed to basic types), so it only takes * + $sort can only sort objects (as opposed to basic types), so it only takes
* object as patterns * object as patterns
* + Because of the previous, $sort requires that the array being pushed to be made * + Because of the previous, $sort requires that the array being pushed to be made
* of objects * of objects
*/ */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
/** /**
* Locates the array to be pushed into in the 'root', if it exists, and fills in * Locates the array to be pushed into in the 'root', if it exists, and fills in
* execInfo accordingly. Returns true if $push would succeed in 'ro ot', otherwise * execInfo accordingly. Returns true if $push would succeed in 'ro ot', otherwise
* return a status describing the error. * return a status describing the error.
* *
* Note that a $push is never in-place. The cost of checking if it is a no-op makes it * Note that a $push is never in-place. The cost of checking if it is a no-op makes it
* so that we don't do such check either. As such, execInfo is alwa ys filled with * so that we don't do such check either. As such, execInfo is alwa ys filled with
* 'false' for those two options. * 'false' for those two options.
*/ */
skipping to change at line 86 skipping to change at line 88
* Pushes the array into the prepared position and "sort/slice"s th e resulting array * Pushes the array into the prepared position and "sort/slice"s th e resulting array
* according to that call's instructions. * according to that call's instructions.
*/ */
virtual Status apply() const; virtual Status apply() const;
/** /**
* $push currently logs the entire resulting array as a $set. * $push currently logs the entire resulting array as a $set.
* *
* TODO Log a positional $set in the array, whenever possible. * TODO Log a positional $set in the array, whenever possible.
*/ */
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
// Access to each component of fieldName that's the target of this mod. // Access to each component of fieldName that's the target of this mod.
FieldRef _fieldRef; FieldRef _fieldRef;
// 0 or index for $-positional in _fieldRef. // 0 or index for $-positional in _fieldRef.
size_t _posDollar; size_t _posDollar;
// Clauses for the $push that are filled when the $each variation o f the command is used. // Clauses for the $push that are filled when the $each variation o f the command is used.
 End of changes. 3 change blocks. 
2 lines changed or deleted 4 lines changed or added


 modifier_rename.h   modifier_rename.h 
skipping to change at line 30 skipping to change at line 30
#include <string> #include <string>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/bson/mutable/element.h" #include "mongo/bson/mutable/element.h"
#include "mongo/db/field_ref.h" #include "mongo/db/field_ref.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
namespace mongo { namespace mongo {
class LogBuilder;
/** /**
* The $rename modifier moves the field from source to the destination t o perform * The $rename modifier moves the field from source to the destination t o perform
* the rename. * the rename.
* *
* Example: {$rename: {<source>:<dest>}} where both <source/dest> are fi eld names * Example: {$rename: {<source>:<dest>}} where both <source/dest> are fi eld names
* Start with {a:1} and applying a {$rename: {"a":"b"} } produces {b:1} * Start with {a:1} and applying a {$rename: {"a":"b"} } produces {b:1}
**/ **/
class ModifierRename : public ModifierInterface { class ModifierRename : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierRename); MONGO_DISALLOW_COPYING(ModifierRename);
public: public:
ModifierRename(); ModifierRename();
virtual ~ModifierRename(); virtual ~ModifierRename();
/** /**
* We will check that the to/from are valid paths; in prepare more validation is done * We will check that the to/from are valid paths; in prepare more validation is done
*/ */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
/** /**
* In prepare we will ensure that all restrictions are met: * In prepare we will ensure that all restrictions are met:
* -- The 'from' field exists, and is valid, else it is a no-op * -- The 'from' field exists, and is valid, else it is a no-op
* -- The 'to' field is valid as a destination * -- The 'to' field is valid as a destination
* -- The 'to' field is not on the path (or the same path) as the 'from' field * -- The 'to' field is not on the path (or the same path) as the 'from' field
* -- Neither 'to' nor 'from' have an array ancestor * -- Neither 'to' nor 'from' have an array ancestor
*/ */
virtual Status prepare(mutablebson::Element root, virtual Status prepare(mutablebson::Element root,
const StringData& matchedField, const StringData& matchedField,
skipping to change at line 71 skipping to change at line 73
/** /**
* We will transform the document by first making sure that the 'to ' element * We will transform the document by first making sure that the 'to ' element
* is empty before moving the 'from' element there. * is empty before moving the 'from' element there.
*/ */
virtual Status apply() const; virtual Status apply() const;
/** /**
* For the oplog entry we will generate an $unset on the 'from' fie ld, and $set for * For the oplog entry we will generate an $unset on the 'from' fie ld, and $set for
* the 'to' field. If no 'from' element is found then function will return immediately. * the 'to' field. If no 'from' element is found then function will return immediately.
*/ */
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
// The source and destination fields // The source and destination fields
FieldRef _fromFieldRef; FieldRef _fromFieldRef;
FieldRef _toFieldRef; FieldRef _toFieldRef;
// The state carried over from prepare for apply/log // The state carried over from prepare for apply/log
struct PreparedState; struct PreparedState;
scoped_ptr<PreparedState> _preparedState; scoped_ptr<PreparedState> _preparedState;
 End of changes. 3 change blocks. 
2 lines changed or deleted 4 lines changed or added


 modifier_set.h   modifier_set.h 
skipping to change at line 30 skipping to change at line 30
#include <string> #include <string>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/bson/mutable/element.h" #include "mongo/bson/mutable/element.h"
#include "mongo/db/field_ref.h" #include "mongo/db/field_ref.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
namespace mongo { namespace mongo {
class LogBuilder;
class ModifierSet : public ModifierInterface { class ModifierSet : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierSet); MONGO_DISALLOW_COPYING(ModifierSet);
public: public:
enum ModifierSetMode { SET_NORMAL, SET_ON_INSERT }; enum ModifierSetMode { SET_NORMAL, SET_ON_INSERT };
explicit ModifierSet(ModifierSetMode mode = SET_NORMAL); explicit ModifierSet(ModifierSetMode mode = SET_NORMAL);
// //
// Modifier interface implementation // Modifier interface implementation
// //
virtual ~ModifierSet(); virtual ~ModifierSet();
/** /**
* A 'modExpr' is a BSONElement {<fieldname>: <value>} coming from a $set mod such as * A 'modExpr' is a BSONElement {<fieldname>: <value>} coming from a $set mod such as
* {$set: {<fieldname: <value>}}. init() extracts the field name an d the value to be * {$set: {<fieldname: <value>}}. init() extracts the field name an d the value to be
* assigned to it from 'modExpr'. It returns OK if successful or a status describing * assigned to it from 'modExpr'. It returns OK if successful or a status describing
* the error. * the error.
*/ */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
/** /**
* Looks up the field name in the sub-tree rooted at 'root', and bi nds, if necessary, * Looks up the field name in the sub-tree rooted at 'root', and bi nds, if necessary,
* the '$' field part using the 'matchedfield' number. prepare() re turns OK and * the '$' field part using the 'matchedfield' number. prepare() re turns OK and
* fills in 'execInfo' with information of whether this mod is a no -op on 'root' and * fills in 'execInfo' with information of whether this mod is a no -op on 'root' and
* whether it is an in-place candidate. Otherwise, returns a status describing the * whether it is an in-place candidate. Otherwise, returns a status describing the
* error. * error.
*/ */
virtual Status prepare(mutablebson::Element root, virtual Status prepare(mutablebson::Element root,
const StringData& matchedField, const StringData& matchedField,
skipping to change at line 73 skipping to change at line 75
/** /**
* Applies the prepared mod over the element 'root' specified in th e prepare() * Applies the prepared mod over the element 'root' specified in th e prepare()
* call. Returns OK if successful or a status describing the error. * call. Returns OK if successful or a status describing the error.
*/ */
virtual Status apply() const; virtual Status apply() const;
/** /**
* Adds a log entry to logRoot corresponding to the operation appli ed here. Returns OK * Adds a log entry to logRoot corresponding to the operation appli ed here. Returns OK
* if successful or a status describing the error. * if successful or a status describing the error.
*/ */
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
// Access to each component of fieldName that's the target of this mod. // Access to each component of fieldName that's the target of this mod.
FieldRef _fieldRef; FieldRef _fieldRef;
// 0 or index for $-positional in _fieldRef. // 0 or index for $-positional in _fieldRef.
size_t _posDollar; size_t _posDollar;
// If on 'on insert' mode, We'd like to apply this mod only if we'r e in a upsert. // If on 'on insert' mode, We'd like to apply this mod only if we'r e in a upsert.
const ModifierSetMode _setMode; const ModifierSetMode _setMode;
// Element of the $set expression. // Element of the $set expression.
BSONElement _val; BSONElement _val;
// See the class comments in modifier_interface.h
ModifierInterface::Options _modOptions;
// The instance of the field in the provided doc. This state is val id after a // The instance of the field in the provided doc. This state is val id after a
// prepare() was issued and until a log() is issued. The document t his mod is // prepare() was issued and until a log() is issued. The document t his mod is
// being prepared against must be live throughout all the calls. // being prepared against must be live throughout all the calls.
struct PreparedState; struct PreparedState;
scoped_ptr<PreparedState> _preparedState; scoped_ptr<PreparedState> _preparedState;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 4 change blocks. 
2 lines changed or deleted 7 lines changed or added


 modifier_table.h   modifier_table.h 
skipping to change at line 28 skipping to change at line 28
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
namespace mongo { namespace mongo {
namespace modifiertable { namespace modifiertable {
enum ModifierType { enum ModifierType {
MOD_ADD_TO_SET, MOD_ADD_TO_SET,
MOD_BIT, MOD_BIT,
MOD_INC, MOD_INC,
MOD_MUL,
MOD_POP, MOD_POP,
MOD_PULL, MOD_PULL,
MOD_PULL_ALL, MOD_PULL_ALL,
MOD_PUSH, MOD_PUSH,
MOD_PUSH_ALL, MOD_PUSH_ALL,
MOD_SET, MOD_SET,
MOD_SET_ON_INSERT, MOD_SET_ON_INSERT,
MOD_RENAME, MOD_RENAME,
MOD_UNSET, MOD_UNSET,
MOD_UNKNOWN MOD_UNKNOWN
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 lines changed or added


 modifier_unset.h   modifier_unset.h 
skipping to change at line 30 skipping to change at line 30
#include <string> #include <string>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/bson/mutable/element.h" #include "mongo/bson/mutable/element.h"
#include "mongo/db/field_ref.h" #include "mongo/db/field_ref.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
namespace mongo { namespace mongo {
class LogBuilder;
class ModifierUnset : public ModifierInterface { class ModifierUnset : public ModifierInterface {
MONGO_DISALLOW_COPYING(ModifierUnset); MONGO_DISALLOW_COPYING(ModifierUnset);
public: public:
ModifierUnset(); ModifierUnset();
// //
// Modifier interface implementation // Modifier interface implementation
// //
virtual ~ModifierUnset(); virtual ~ModifierUnset();
/** /**
* A 'modExpr' is a BSONElement {<fieldname>: <value>} coming from a $set mod such as * A 'modExpr' is a BSONElement {<fieldname>: <value>} coming from a $set mod such as
* {$unset: {<fieldname: <value>}}. init() extracts the field name and the value to be * {$unset: {<fieldname: <value>}}. init() extracts the field name and the value to be
* assigned to it from 'modExpr'. It returns OK if successful or a status describing * assigned to it from 'modExpr'. It returns OK if successful or a status describing
* the error. * the error.
*/ */
virtual Status init(const BSONElement& modExpr); virtual Status init(const BSONElement& modExpr, const Options& opts );
/** /**
* Locates the field to be removed under the 'root' element, if it exist, and fills in * Locates the field to be removed under the 'root' element, if it exist, and fills in
* 'execInfo' accordingly. Return OK if successful or a status desc ribing the error. * 'execInfo' accordingly. Return OK if successful or a status desc ribing the error.
*/ */
virtual Status prepare(mutablebson::Element root, virtual Status prepare(mutablebson::Element root,
const StringData& matchedField, const StringData& matchedField,
ExecInfo* execInfo); ExecInfo* execInfo);
/** /**
* Removes the found element from the document. If such element was inside an array, * Removes the found element from the document. If such element was inside an array,
* removal means setting that array position to 'null'. * removal means setting that array position to 'null'.
*/ */
virtual Status apply() const; virtual Status apply() const;
/** /**
* Adds the exact $unset mod to the log. * Adds the exact $unset mod to the log.
*/ */
virtual Status log(mutablebson::Element logRoot) const; virtual Status log(LogBuilder* logBuilder) const;
private: private:
// Access to each component of fieldName that's the target of this mod. // Access to each component of fieldName that's the target of this mod.
FieldRef _fieldRef; FieldRef _fieldRef;
// 0 or index for $-positional in _fieldRef. // 0 or index for $-positional in _fieldRef.
size_t _posDollar; size_t _posDollar;
// Element of the $set expression. // Element of the $set expression.
 End of changes. 3 change blocks. 
2 lines changed or deleted 4 lines changed or added


 mutable_bson_test_utils.h   mutable_bson_test_utils.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 implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* 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.
*/ */
#include <iosfwd> #include <iosfwd>
#include "mongo/bson/mutable/document.h"
namespace mongo { namespace mongo {
class BSONObj; class BSONObj;
namespace mutablebson { namespace mutablebson {
class ConstElement;
class Document;
// //
// Utilities for mutable BSON unit tests. // Utilities for mutable BSON unit tests.
// //
/** /**
* Catch all comparator between a mutable 'doc' and the expected BSON ' exp'. It compares * Catch all comparator between a mutable 'doc' and the expected BSON ' exp'. It compares
* (a) 'doc's generated object, (b) 'exp', the expected object, and (c) 'doc(exp)', a * (a) 'doc's generated object, (b) 'exp', the expected object, and (c) 'doc(exp)', a
* document created from 'exp'. Returns true if all three are equal, ot herwise false. * document created from 'exp'. Returns true if all three are equal, ot herwise false.
*/ */
bool checkDoc(const Document& lhs, const BSONObj& rhs); bool checkDoc(const Document& lhs, const BSONObj& rhs);
skipping to change at line 57 skipping to change at line 56
inline bool operator==(const Document& lhs, const BSONObj& rhs) { inline bool operator==(const Document& lhs, const BSONObj& rhs) {
return checkDoc(lhs, rhs); return checkDoc(lhs, rhs);
} }
/** Stream out a document; useful within ASSERT calls */ /** Stream out a document; useful within ASSERT calls */
std::ostream& operator<<(std::ostream& stream, const Document& doc); std::ostream& operator<<(std::ostream& stream, const Document& doc);
/** Stream out an element; useful within ASSERT calls */ /** Stream out an element; useful within ASSERT calls */
std::ostream& operator<<(std::ostream& stream, const ConstElement& elt) ; std::ostream& operator<<(std::ostream& stream, const ConstElement& elt) ;
/** Check that the two provided Documents are equivalent modulo field o
rdering in Object
* Elements. Leaf values are considered equal via woCompare.
*/
bool checkEqualNoOrdering(const Document& lhs, const Document& rhs);
struct UnorderedWrapper_Obj {
inline explicit UnorderedWrapper_Obj(const BSONObj& o)
: obj(o) {}
const BSONObj& obj;
};
struct UnorderedWrapper_Doc {
inline explicit UnorderedWrapper_Doc(const Document& d)
: doc(d) {}
const Document& doc;
};
inline UnorderedWrapper_Doc unordered(const Document& d) {
return UnorderedWrapper_Doc(d);
}
inline UnorderedWrapper_Obj unordered(const BSONObj& o) {
return UnorderedWrapper_Obj(o);
}
inline bool operator==(const UnorderedWrapper_Doc& lhs, const Unordered
Wrapper_Doc& rhs) {
return checkEqualNoOrdering(lhs.doc, rhs.doc);
}
inline bool operator!=(const UnorderedWrapper_Doc& lhs, const Unordered
Wrapper_Doc& rhs) {
return !(lhs == rhs);
}
inline bool operator==(const UnorderedWrapper_Obj& lhs, const Unordered
Wrapper_Obj& rhs) {
const Document dlhs(lhs.obj);
const Document drhs(rhs.obj);
return checkEqualNoOrdering(dlhs, drhs);
}
inline bool operator!=(const UnorderedWrapper_Obj& lhs, const Unordered
Wrapper_Obj& rhs) {
return !(lhs == rhs);
}
inline bool operator==(const UnorderedWrapper_Doc& lhs, const Unordered
Wrapper_Obj& rhs) {
const Document drhs(rhs.obj);
return checkEqualNoOrdering(lhs.doc, drhs);
}
inline bool operator!=(const UnorderedWrapper_Doc& lhs, const Unordered
Wrapper_Obj& rhs) {
return !(lhs == rhs);
}
inline bool operator==(const UnorderedWrapper_Obj& lhs, const Unordered
Wrapper_Doc& rhs) {
const Document dlhs(lhs.obj);
return checkEqualNoOrdering(dlhs, rhs.doc);
}
inline bool operator!=(const UnorderedWrapper_Obj& lhs, const Unordered
Wrapper_Doc& rhs) {
return !(lhs == rhs);
}
std::ostream& operator<<(std::ostream& stream, const UnorderedWrapper_D
oc& uw_d);
std::ostream& operator<<(std::ostream& stream, const UnorderedWrapper_O
bj& uw_o);
} // namespace mutablebson } // namespace mutablebson
} // namespace mongo } // namespace mongo
 End of changes. 3 change blocks. 
3 lines changed or deleted 77 lines changed or added


 namespace_details.h   namespace_details.h 
skipping to change at line 26 skipping to change at line 26
#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/index_names.h" #include "mongo/db/index_names.h"
#include "mongo/db/index_set.h" #include "mongo/db/index_set.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/mongommf.h" #include "mongo/db/storage/durable_mapped_file.h"
#include "mongo/db/namespace_string.h" #include "mongo/db/namespace_string.h"
#include "mongo/db/querypattern.h" #include "mongo/db/querypattern.h"
#include "mongo/db/storage/namespace.h" #include "mongo/db/storage/namespace.h"
#include "mongo/db/storage/namespace_index.h" #include "mongo/db/storage/namespace_index.h"
#include "mongo/platform/unordered_map.h" #include "mongo/platform/unordered_map.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."
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 namespace_index.h   namespace_index.h 
skipping to change at line 69 skipping to change at line 69
void getNamespaces( std::list<std::string>& tofill , bool onlyColle ctions = true ) const; void getNamespaces( std::list<std::string>& tofill , bool onlyColle ctions = true ) const;
boost::filesystem::path path() const; boost::filesystem::path path() const;
unsigned long long fileLength() const { return _f.length(); } unsigned long long fileLength() const { return _f.length(); }
private: private:
void _init(); void _init();
void maybeMkdir() const; void maybeMkdir() const;
MongoMMF _f; DurableMappedFile _f;
HashTable<Namespace,NamespaceDetails> *_ht; HashTable<Namespace,NamespaceDetails> *_ht;
std::string _dir; std::string _dir;
std::string _database; std::string _database;
}; };
} }
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 namespace_string.h   namespace_string.h 
skipping to change at line 53 skipping to change at line 53
StringData coll() const; StringData coll() const;
const string& ns() const { return _ns; } const string& ns() const { return _ns; }
operator string() const { return _ns; } operator string() const { return _ns; }
string toString() const { return _ns; } string toString() const { return _ns; }
size_t size() const { return _ns.size(); } size_t size() const { return _ns.size(); }
bool isSystem() const { return coll().startsWith( "system." ); } bool isSystem() const { return coll().startsWith( "system." ); }
bool isConfigDB() const { return db() == "config"; }
bool isCommand() const { return coll() == "$cmd"; } bool isCommand() const { return coll() == "$cmd"; }
bool isSpecialCommand() const { return coll().startsWith("$cmd.sys" ); }
/** /**
* @return true if the namespace is valid. Special namespaces for i nternal use are considered as valid. * @return true if the namespace is valid. Special namespaces for i nternal use are considered as valid.
*/ */
bool isValid() const { return validDBName( db() ) && !coll().empty( ); } bool isValid() const { return validDBName( db() ) && !coll().empty( ); }
bool operator==( const string& nsIn ) const { return nsIn == _ns; } bool operator==( const string& nsIn ) const { return nsIn == _ns; }
bool operator==( const NamespaceString& nsIn ) const { return nsIn. _ns == _ns; } bool operator==( const NamespaceString& nsIn ) const { return nsIn. _ns == _ns; }
bool operator!=( const string& nsIn ) const { return nsIn != _ns; } bool operator!=( const string& nsIn ) const { return nsIn != _ns; }
 End of changes. 2 change blocks. 
0 lines changed or deleted 2 lines changed or added


 oplogreader.h   oplogreader.h 
skipping to change at line 34 skipping to change at line 34
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.
*/ */
class OplogReader { class OplogReader {
shared_ptr<DBClientConnection> _conn; shared_ptr<DBClientConnection> _conn;
shared_ptr<DBClientCursor> cursor; shared_ptr<DBClientCursor> cursor;
bool _doHandshake;
int _tailingQueryOptions; int _tailingQueryOptions;
public: public:
OplogReader( bool doHandshake = true ); OplogReader();
~OplogReader() { } ~OplogReader() { }
void resetCursor() { cursor.reset(); } void resetCursor() { cursor.reset(); }
void resetConnection() { void resetConnection() {
cursor.reset(); cursor.reset();
_conn.reset(); _conn.reset();
} }
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));
} }
/* SO_TIMEOUT (send/recv time out) for our DBClientConnections */
static const int tcp_timeout = 30;
/* ok to call if already connected */ /* ok to call if already connected */
bool connect(const std::string& hostname); bool connect(const std::string& hostname);
bool connect(const BSONObj& rid, const int from, const string& to); bool connect(const std::string& hostname, const BSONObj& me);
bool connect(const mongo::OID& rid, const int from, const string& t
o);
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();
} }
} }
bool haveCursor() { return cursor.get() != 0; } bool haveCursor() { return cursor.get() != 0; }
skipping to change at line 139 skipping to change at line 143
if( cursor.get() ) if( cursor.get() )
cursor->peek(v,n); cursor->peek(v,n);
} }
BSONObj nextSafe() { return cursor->nextSafe(); } BSONObj nextSafe() { return cursor->nextSafe(); }
BSONObj next() { return cursor->next(); } BSONObj next() { return cursor->next(); }
void putBack(BSONObj op) { cursor->putBack(op); } void putBack(BSONObj op) { cursor->putBack(op); }
private: private:
/** @return true iff connection was successful */ /** @return true iff connection was successful */
bool commonConnect(const string& hostName); bool commonConnect(const string& hostName);
bool passthroughHandshake(const BSONObj& rid, const int f); bool passthroughHandshake(const mongo::OID& rid, const int f);
}; };
} }
 End of changes. 5 change blocks. 
4 lines changed or deleted 9 lines changed or added


 optime.h   optime.h 
skipping to change at line 22 skipping to change at line 22
* 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/thread/condition.hpp> #include <boost/thread/condition.hpp>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include "mongo/bson/util/misc.h" // time_t_to_String
#include "mongo/util/assert_util.h" #include "mongo/util/assert_util.h"
#include "mongo/util/concurrency/mutex.h" #include "mongo/util/concurrency/mutex.h"
#include "mongo/util/time_support.h"
namespace mongo { namespace mongo {
struct ClockSkewException : public DBException { struct ClockSkewException : public DBException {
ClockSkewException() : DBException( "clock skew exception" , 20001 ) {} ClockSkewException() : DBException( "clock skew exception" , 20001 ) {}
}; };
/* replsets used to use RSOpTime. /* replsets used to use RSOpTime.
M/S uses OpTime. M/S uses OpTime.
But this is useable from both. But this is useable from both.
skipping to change at line 114 skipping to change at line 114
unsigned long long asDate() const { unsigned long long asDate() const {
return reinterpret_cast<const unsigned long long*>(&i)[0]; return reinterpret_cast<const unsigned long long*>(&i)[0];
} }
long long asLL() const { long long asLL() const {
return reinterpret_cast<const long long*>(&i)[0]; return reinterpret_cast<const long long*>(&i)[0];
} }
bool isNull() const { return secs == 0; } bool isNull() const { return secs == 0; }
string toStringLong() const { string toStringLong() const {
char buf[64];
time_t_to_String(secs, buf);
std::stringstream ss; std::stringstream ss;
ss << time_t_to_String_short(secs) << ' '; ss << time_t_to_String_short(secs) << ' ';
ss << std::hex << secs << ':' << i; ss << std::hex << secs << ':' << i;
return ss.str(); return ss.str();
} }
string toStringPretty() const { string toStringPretty() const {
std::stringstream ss; std::stringstream ss;
ss << time_t_to_String_short(secs) << ':' << std::hex << i; ss << time_t_to_String_short(secs) << ':' << std::hex << i;
return ss.str(); return ss.str();
 End of changes. 3 change blocks. 
3 lines changed or deleted 1 lines changed or added


 or.h   or.h 
skipping to change at line 20 skipping to change at line 20
* 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 "mongo/db/diskloc.h" #include "mongo/db/diskloc.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/matcher.h"
#include "mongo/db/exec/plan_stage.h" #include "mongo/db/exec/plan_stage.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/matcher/expression.h"
#include "mongo/platform/unordered_set.h" #include "mongo/platform/unordered_set.h"
namespace mongo { namespace mongo {
/** /**
* This stage outputs the union of its children. It optionally dedupli cates on DiskLoc. * This stage outputs the union of its children. It optionally dedupli cates on DiskLoc.
* *
* Preconditions: Valid DiskLoc. * Preconditions: Valid DiskLoc.
* *
* If we're deduping, we may fail to dedup any invalidated DiskLoc prop erly. * If we're deduping, we may fail to dedup any invalidated DiskLoc prop erly.
*/ */
class OrStage : public PlanStage { class OrStage : public PlanStage {
public: public:
OrStage(WorkingSet* ws, bool dedup, Matcher* matcher); OrStage(WorkingSet* ws, bool dedup, const MatchExpression* filter);
virtual ~OrStage(); virtual ~OrStage();
void addChild(PlanStage* child); void addChild(PlanStage* child);
virtual bool isEOF(); virtual bool isEOF();
virtual StageState work(WorkingSetID* out); virtual StageState work(WorkingSetID* out);
virtual void prepareToYield(); virtual void prepareToYield();
virtual void recoverFromYield(); virtual void recoverFromYield();
virtual void invalidate(const DiskLoc& dl); virtual void invalidate(const DiskLoc& dl);
virtual PlanStageStats* getStats();
private: private:
// Not owned by us. // Not owned by us.
WorkingSet* _ws; WorkingSet* _ws;
scoped_ptr<Matcher> _matcher; // The filter is not owned by us.
const MatchExpression* _filter;
// Owned by us. // Owned by us.
vector<PlanStage*> _children; vector<PlanStage*> _children;
// Which of _children are we calling work(...) on now? // Which of _children are we calling work(...) on now?
size_t _currentChild; size_t _currentChild;
// True if we dedup on DiskLoc, false otherwise. // True if we dedup on DiskLoc, false otherwise.
bool _dedup; bool _dedup;
// Which DiskLocs have we returned? // Which DiskLocs have we returned?
unordered_set<DiskLoc, DiskLoc::Hasher> _seen; unordered_set<DiskLoc, DiskLoc::Hasher> _seen;
// Stats
CommonStats _commonStats;
OrStats _specificStats;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 6 change blocks. 
4 lines changed or deleted 11 lines changed or added


 owned_pointer_vector.h   owned_pointer_vector.h 
skipping to change at line 37 skipping to change at line 37
* NOTE that an OwnedPointerVector<T> wraps an std::vector<T*>. * NOTE that an OwnedPointerVector<T> wraps an std::vector<T*>.
*/ */
template<class T> template<class T>
class OwnedPointerVector { class OwnedPointerVector {
MONGO_DISALLOW_COPYING(OwnedPointerVector); MONGO_DISALLOW_COPYING(OwnedPointerVector);
public: public:
OwnedPointerVector(); OwnedPointerVector();
~OwnedPointerVector(); ~OwnedPointerVector();
typedef typename std::vector<T*>::const_iterator const_iterator;
typedef typename std::vector<T*>::const_reverse_iterator const_reve
rse_iterator;
/** Access the vector. */ /** Access the vector. */
const std::vector<T*>& vector() const { return _vector; } const std::vector<T*>& vector() const { return _vector; }
std::vector<T*>& mutableVector() { return _vector; } std::vector<T*>& mutableVector() { return _vector; }
std::size_t size() const { return _vector.size(); }
bool empty() const { return _vector.empty(); }
const_iterator begin() const { return _vector.begin(); }
const_reverse_iterator rbegin() const { return _vector.rbegin(); }
const_iterator end() const { return _vector.end(); }
const_reverse_iterator rend() const { return _vector.rend(); }
void clear(); void clear();
private: private:
std::vector<T*> _vector; std::vector<T*> _vector;
}; };
template<class T> template<class T>
OwnedPointerVector<T>::OwnedPointerVector() { OwnedPointerVector<T>::OwnedPointerVector() {
} }
 End of changes. 2 change blocks. 
0 lines changed or deleted 12 lines changed or added


 parsed_query.h   parsed_query.h 
// DEPRECATED
/* 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,
skipping to change at line 68 skipping to change at line 69
bool isExplain() const { return _explain; } bool isExplain() const { return _explain; }
bool isSnapshot() const { return _snapshot; } bool isSnapshot() const { return _snapshot; }
bool returnKey() const { return _returnKey; } bool returnKey() const { return _returnKey; }
bool showDiskLoc() const { return _showDiskLoc; } bool showDiskLoc() const { return _showDiskLoc; }
const BSONObj& getMin() const { return _min; } const BSONObj& getMin() const { return _min; }
const BSONObj& getMax() const { return _max; } const BSONObj& getMax() const { return _max; }
const BSONObj& getOrder() const { return _order; } const BSONObj& getOrder() const { return _order; }
const BSONObj& getHint() const { return _hint; } const BSONObj& getHint() const { return _hint; }
int getMaxScan() const { return _maxScan; } int getMaxScan() const { return _maxScan; }
int getMaxTimeMS() const { return _maxTimeMS; }
bool couldBeCommand() const;
bool hasIndexSpecifier() const; bool hasIndexSpecifier() const;
/* if ntoreturn is zero, we return up to 101 objects. on the subse quent getmore, there /* if ntoreturn is zero, we return up to 101 objects. on the subse quent getmore, there
is only a size limit. The idea is that on a find() where one does n't use much results, is only a size limit. The idea is that on a find() where one does n't use much results,
we don't return much, but once getmore kicks in, we start pushing significant quantities. we don't return much, but once getmore kicks in, we start pushing significant quantities.
The n limit (vs. size) is important when someone fetches only one small field from big The n limit (vs. size) is important when someone fetches only one small field from big
objects, which causes massive scanning server-side. objects, which causes massive scanning server-side.
*/ */
skipping to change at line 112 skipping to change at line 112
bool _wantMore; bool _wantMore;
bool _explain; bool _explain;
bool _snapshot; bool _snapshot;
bool _returnKey; bool _returnKey;
bool _showDiskLoc; bool _showDiskLoc;
bool _hasReadPref; bool _hasReadPref;
BSONObj _min; BSONObj _min;
BSONObj _max; BSONObj _max;
BSONObj _hint; BSONObj _hint;
int _maxScan; int _maxScan;
int _maxTimeMS;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 3 change blocks. 
2 lines changed or deleted 3 lines changed or added


 path_support.h   path_support.h 
skipping to change at line 67 skipping to change at line 67
* 'a.b.c' is a viable path in {a: {b: {c: 1}}} * 'a.b.c' is a viable path in {a: {b: {c: 1}}}
* 'a.b.c' is a viable path in {a: {b: {c: {d: 1}}}} * 'a.b.c' is a viable path in {a: {b: {c: {d: 1}}}}
* 'a.b.c' is NOT a viable path in {a: {b: 1}}, because b would h ave changed types * 'a.b.c' is NOT a viable path in {a: {b: 1}}, because b would h ave changed types
* 'a.0.b' is a viable path in {a: [{b: 1}, {c: 1}]} * 'a.0.b' is a viable path in {a: [{b: 1}, {c: 1}]}
* 'a.0.b' is a viable path in {a: {"0": {b: 1}}} * 'a.0.b' is a viable path in {a: {"0": {b: 1}}}
* 'a.0.b' is NOT a viable path in {a: 1}, because a would have c hanged types * 'a.0.b' is NOT a viable path in {a: 1}, because a would have c hanged types
* 'a.5.b' is a viable path in in {a: []} (padding would occur) * 'a.5.b' is a viable path in in {a: []} (padding would occur)
*/ */
Status findLongestPrefix(const FieldRef& prefix, Status findLongestPrefix(const FieldRef& prefix,
mutablebson::Element root, mutablebson::Element root,
int32_t* idxFound, size_t* idxFound,
mutablebson::Element* elemFound); mutablebson::Element* elemFound);
/** /**
* Creates the parts 'prefix[idxRoot]', 'prefix[idxRoot+1]', ..., * Creates the parts 'prefix[idxRoot]', 'prefix[idxRoot+1]', ...,
* 'prefix[<numParts>-1]' under 'elemFound' and adds 'newElem' as a child of that * 'prefix[<numParts>-1]' under 'elemFound' and adds 'newElem' as a child of that
* path. Returns OK, if successful, or an error code describing why not, otherwise. * path. Returns OK, if successful, or an error code describing why not, otherwise.
* *
* createPathAt is designed to work with 'findLongestPrefix' in tha t it can create the * createPathAt is designed to work with 'findLongestPrefix' in tha t it can create the
* field parts in 'prefix' that are missing from a given document. 'elemFound' points * field parts in 'prefix' that are missing from a given document. 'elemFound' points
* to the element in the doc that is the parent of prefix[idxRoot]. * to the element in the doc that is the parent of prefix[idxRoot].
*/ */
Status createPathAt(const FieldRef& prefix, Status createPathAt(const FieldRef& prefix,
int32_t idxRoot, size_t idxRoot,
mutablebson::Element elemFound, mutablebson::Element elemFound,
mutablebson::Element newElem); mutablebson::Element newElem);
} // namespace pathsupport } // namespace pathsupport
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 pdfile.h   pdfile.h 
skipping to change at line 29 skipping to change at line 29
Files: Files:
database.ns - namespace index database.ns - namespace index
database.1 - data files database.1 - data files
database.2 database.2
... ...
*/ */
#pragma once #pragma once
#include "mongo/db/client.h" #include "mongo/db/client.h"
#include "mongo/db/cursor.h"
#include "mongo/db/database.h"
#include "mongo/db/diskloc.h" #include "mongo/db/diskloc.h"
#include "mongo/db/jsobjmanipulator.h" #include "mongo/db/jsobjmanipulator.h"
#include "mongo/db/memconcept.h" #include "mongo/db/memconcept.h"
#include "mongo/db/mongommf.h" #include "mongo/db/storage/data_file.h"
#include "mongo/db/storage/durable_mapped_file.h"
#include "mongo/db/storage/extent.h"
#include "mongo/db/namespace_details-inl.h" #include "mongo/db/namespace_details-inl.h"
#include "mongo/db/namespace_string.h" #include "mongo/db/namespace_string.h"
#include "mongo/db/pdfile_version.h" #include "mongo/db/pdfile_version.h"
#include "mongo/platform/cstdint.h" #include "mongo/platform/cstdint.h"
#include "mongo/util/log.h" #include "mongo/util/log.h"
#include "mongo/util/mmap.h" #include "mongo/util/mmap.h"
namespace mongo { namespace mongo {
class Cursor; class Cursor;
skipping to change at line 64 skipping to change at line 68
/* 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());
bool isValidNS( const StringData& ns ); bool isValidNS( const StringData& ns );
/*--------------------------------------------------------------------- */ /*--------------------------------------------------------------------- */
class MongoDataFile {
friend class DataFileMgr;
friend class BasicCursor;
public:
MongoDataFile(int fn) : _mb(0), fileNo(fn) { }
/** @return true if found and opened. if uninitialized (prealloc on
ly) does not open. */
bool openExisting( const char *filename );
/** creates if DNE */
void open(const char *filename, int requestedDataSize = 0, bool pre
allocateOnly = false);
/* allocate a new extent from this datafile.
@param capped - true if capped collection
@param loops is our recursion check variable - you want to pass
in zero
*/
Extent* createExtent(const char *ns, int approxSize, bool capped =
false, int loops = 0);
DataFileHeader *getHeader() { return header(); }
HANDLE getFd() { return mmf.getFd(); }
unsigned long long length() const { return mmf.length(); }
/* return max size an extent may be */
static int maxSize();
/** fsync */
void flush( bool sync );
/** only use fore debugging */
Extent* debug_getExtent(DiskLoc loc) { return _getExtent( loc ); }
private:
void badOfs(int) const;
void badOfs2(int) const;
int defaultSize( const char *filename ) const;
Extent* getExtent(DiskLoc loc) const;
Extent* _getExtent(DiskLoc loc) const;
Record* recordAt(DiskLoc dl) const;
void grow(DiskLoc dl, int size);
char* p() const { return (char *) _mb; }
DataFileHeader* header() { return (DataFileHeader*) _mb; }
MongoMMF mmf;
void *_mb; // the memory mapped view
int fileNo;
};
class DataFileMgr { class DataFileMgr {
friend class BasicCursor; friend class BasicCursor;
public: public:
DataFileMgr(); DataFileMgr();
void init(const string& path ); void init(const string& path );
/* see if we can find an extent of the right size in the freelist. */ /* see if we can find an extent of the right size in the freelist. */
static Extent* allocFromFreeList(const char *ns, int approxSize, bo ol capped = false); static Extent* allocFromFreeList(const char *ns, int approxSize, bo ol capped = false);
/** @return DiskLoc where item ends up */ /** @return DiskLoc where item ends up */
skipping to change at line 195 skipping to change at line 151
* NB: 'precalced' is accessed from fastBuildIndex(), which is call ed from insert-related * NB: 'precalced' is accessed from fastBuildIndex(), which is call ed from insert-related
* methods like insertWithObjMod(). It is mutated from various cal lers of the insert * methods like insertWithObjMod(). It is mutated from various cal lers of the insert
* methods, which assume 'precalced' will not change while in the i nsert method. This * methods, which assume 'precalced' will not change while in the i nsert method. This
* should likely be refactored so theDataFileMgr takes full respons ibility. * should likely be refactored so theDataFileMgr takes full respons ibility.
*/ */
SortPhaseOne* getPrecalced() const; SortPhaseOne* getPrecalced() const;
void setPrecalced(SortPhaseOne* precalced); void setPrecalced(SortPhaseOne* precalced);
mongo::mutex _precalcedMutex; mongo::mutex _precalcedMutex;
private: private:
vector<MongoDataFile *> files; vector<DataFile *> files;
SortPhaseOne* _precalced; SortPhaseOne* _precalced;
}; };
extern DataFileMgr theDataFileMgr; extern DataFileMgr theDataFileMgr;
#pragma pack(1) #pragma pack(1)
class DeletedRecord { class DeletedRecord {
public: public:
skipping to change at line 276 skipping to change at line 232
/* use this when a record is deleted. basically a union with next/p rev fields */ /* use this when a record is deleted. basically a union with next/p rev fields */
DeletedRecord& asDeleted() { return *((DeletedRecord*) this); } DeletedRecord& asDeleted() { return *((DeletedRecord*) this); }
Extent* myExtent(const DiskLoc& myLoc) { return DataFileMgr::getExt ent(DiskLoc(myLoc.a(), extentOfs() ) ); } Extent* myExtent(const DiskLoc& myLoc) { return DataFileMgr::getExt ent(DiskLoc(myLoc.a(), extentOfs() ) ); }
/* get the next record in the namespace, traversing extents as nece ssary */ /* get the next record in the namespace, traversing extents as nece ssary */
DiskLoc getNext(const DiskLoc& myLoc); DiskLoc getNext(const DiskLoc& myLoc);
DiskLoc getPrev(const DiskLoc& myLoc); DiskLoc getPrev(const DiskLoc& myLoc);
DiskLoc nextInExtent(const DiskLoc& myLoc) {
_accessing();
if ( _nextOfs == DiskLoc::NullOfs )
return DiskLoc();
verify( _nextOfs );
return DiskLoc(myLoc.a(), _nextOfs);
}
struct NP { struct NP {
int nextOfs; int nextOfs;
int prevOfs; int prevOfs;
}; };
NP* np() { return (NP*) &_nextOfs; } NP* np() { return (NP*) &_nextOfs; }
// --------------------- // ---------------------
// memory cache // memory cache
// --------------------- // ---------------------
skipping to change at line 344 skipping to change at line 292
int _nextOfs; int _nextOfs;
int _prevOfs; int _prevOfs;
/** be careful when referencing this that your write intent was cor rect */ /** be careful when referencing this that your write intent was cor rect */
char _data[4]; char _data[4];
public: public:
static bool MemoryTrackingEnabled; static bool MemoryTrackingEnabled;
}; };
/* extents are datafile regions where all the records within the region
belong to the same namespace.
(11:12:35 AM) dm10gen: when the extent is allocated, all its empty spac
e is stuck into one big DeletedRecord
(11:12:55 AM) dm10gen: and that is placed on the free list
*/
class Extent {
public:
enum { extentSignature = 0x41424344 };
unsigned magic;
DiskLoc myLoc;
DiskLoc xnext, xprev; /* next/prev extent for this namespace */
/* which namespace this extent is for. this is just for troublesho
oting really
and won't even be correct if the collection were renamed!
*/
Namespace nsDiagnostic;
int length; /* size of the extent, including these fields */
DiskLoc firstRecord;
DiskLoc lastRecord;
char _extentData[4];
static int HeaderSize() { return sizeof(Extent)-4; }
bool validates(const DiskLoc diskLoc, BSONArrayBuilder* errors = NU
LL);
BSONObj dump() {
return BSON( "loc" << myLoc.toString() << "xnext" << xnext.toSt
ring() << "xprev" << xprev.toString()
<< "nsdiag" << nsDiagnostic.toString()
<< "size" << length << "firstRecord" << firstRecord.t
oString() << "lastRecord" << lastRecord.toString());
}
void dump(iostream& s) {
s << " loc:" << myLoc.toString() << " xnext:" << xnext.toStr
ing() << " xprev:" << xprev.toString() << '\n';
s << " nsdiag:" << nsDiagnostic.toString() << '\n';
s << " size:" << length << " firstRecord:" << firstRecord.to
String() << " lastRecord:" << lastRecord.toString() << '\n';
}
/* assumes already zeroed -- insufficient for block 'reuse' perhaps
Returns a DeletedRecord location which is the data in the extent re
ady for us.
Caller will need to add that to the freelist structure in namespace
detail.
*/
DiskLoc init(const char *nsname, int _length, int _fileNo, int _off
set, bool capped);
/* like init(), but for a reuse case */
DiskLoc reuse(const char *nsname, bool newUseIsAsCapped);
bool isOk() const { return magic == extentSignature; }
void assertOk() const { verify(isOk()); }
Record* newRecord(int len);
Record* getRecord(DiskLoc dl) {
verify( !dl.isNull() );
verify( dl.sameFile(myLoc) );
int x = dl.getOfs() - myLoc.getOfs();
verify( x > 0 );
return (Record *) (((char *) this) + x);
}
Extent* getNextExtent() { return xnext.isNull() ? 0 : DataFileMgr::
getExtent(xnext); }
Extent* getPrevExtent() { return xprev.isNull() ? 0 : DataFileMgr::
getExtent(xprev); }
static int maxSize();
static int minSize() { return 0x1000; }
/**
* @param len lengt of record we need
* @param lastRecord size of last extent which is a factor in next
extent size
*/
static int followupSize(int len, int lastExtentLen);
/** get a suggested size for the first extent in a namespace
* @param len length of record we need to insert
*/
static int initialSize(int len);
struct FL {
DiskLoc firstRecord;
DiskLoc lastRecord;
};
/** often we want to update just the firstRecord and lastRecord fie
lds.
this helper is for that -- for use with getDur().writing() meth
od
*/
FL* fl() { return (FL*) &firstRecord; }
/** caller must declare write intent first */
void markEmpty();
private:
DiskLoc _reuse(const char *nsname, bool newUseIsAsCapped); // recyc
le an extent and reuse it for a different ns
};
/* a datafile - i.e. the "dbname.<#>" files :
----------------------
DataFileHeader
----------------------
Extent (for a particular namespace)
Record
...
Record (some chained for unused space)
----------------------
more Extents...
----------------------
*/
class DataFileHeader {
public:
int version;
int versionMinor;
int fileLength;
DiskLoc unused; /* unused is the portion of the file that doesn't b
elong to any allocated extents. -1 = no more */
int unusedLength;
char reserved[8192 - 4*4 - 8];
char data[4]; // first extent starts here
enum { HeaderSize = 8192 };
bool isCurrentVersion() const {
return version == PDFILE_VERSION && ( versionMinor == PDFILE_VE
RSION_MINOR_22_AND_OLDER
|| versionMinor == PDFILE_VE
RSION_MINOR_24_AND_NEWER
);
}
bool uninitialized() const { return version == 0; }
void init(int fileno, int filelength, const char* filename) {
if ( uninitialized() ) {
DEV log() << "datafileheader::init initializing " << filena
me << " n:" << fileno << endl;
if( !(filelength > 32768 ) ) {
massert(13640, str::stream() << "DataFileHeader looks c
orrupt at file open filelength:" << filelength << " fileno:" << fileno, fal
se);
}
{
// "something" is too vague, but we checked for the rig
ht db to be locked higher up the call stack
if( !Lock::somethingWriteLocked() ) {
LockState::Dump();
log() << "*** TEMP NOT INITIALIZING FILE " << filen
ame << ", not in a write lock." << endl;
log() << "temp bypass until more elaborate change -
case that is manifesting is benign anyway" << endl;
return;
/**
log() << "ERROR can't create outside a write lock"
<< endl;
printStackTrace();
::abort();
**/
}
}
getDur().createdFile(filename, filelength);
verify( HeaderSize == 8192 );
DataFileHeader *h = getDur().writing(this);
h->fileLength = filelength;
h->version = PDFILE_VERSION;
h->versionMinor = PDFILE_VERSION_MINOR_22_AND_OLDER; // All
dbs start like this
h->unused.set( fileno, HeaderSize );
verify( (data-(char*)this) == HeaderSize );
h->unusedLength = fileLength - HeaderSize - 16;
}
}
bool isEmpty() const {
return uninitialized() || ( unusedLength == fileLength - Header
Size - 16 );
}
};
#pragma pack() #pragma pack()
inline Extent* MongoDataFile::_getExtent(DiskLoc loc) const { // XXX-ERH
loc.assertOk();
Extent *e = (Extent *) (p()+loc.getOfs());
return e;
}
inline Extent* MongoDataFile::getExtent(DiskLoc loc) const { inline Extent* Extent::getNextExtent() {
Extent *e = _getExtent(loc); return xnext.isNull() ? 0 : DataFileMgr::getExtent(xnext);
e->assertOk();
memconcept::is(e, memconcept::concept::extent);
return e;
} }
} // namespace mongo inline Extent* Extent::getPrevExtent() {
return xprev.isNull() ? 0 : DataFileMgr::getExtent(xprev);
#include "cursor.h"
namespace mongo {
inline Record* MongoDataFile::recordAt(DiskLoc dl) const {
int ofs = dl.getOfs();
if (ofs < DataFileHeader::HeaderSize) {
badOfs(ofs); // will uassert - external call to keep out of the
normal code path
}
return reinterpret_cast<Record*>(p() + ofs);
} }
inline DiskLoc Record::getNext(const DiskLoc& myLoc) { inline DiskLoc Record::getNext(const DiskLoc& myLoc) {
_accessing(); _accessing();
if ( _nextOfs != DiskLoc::NullOfs ) { if ( _nextOfs != DiskLoc::NullOfs ) {
/* defensive */ /* defensive */
if ( _nextOfs >= 0 && _nextOfs < 10 ) { if ( _nextOfs >= 0 && _nextOfs < 10 ) {
logContext("Assertion failure - Record::getNext() referenci ng a deleted record?"); logContext("Assertion failure - Record::getNext() referenci ng a deleted record?");
return DiskLoc(); return DiskLoc();
} }
skipping to change at line 613 skipping to change at line 378
template< class V > template< class V >
inline inline
const BtreeBucket<V> * DiskLoc::btree() const { const BtreeBucket<V> * DiskLoc::btree() const {
verify( _a != -1 ); verify( _a != -1 );
Record *r = rec(); Record *r = rec();
memconcept::is(r, memconcept::concept::btreebucket, "", 8192); memconcept::is(r, memconcept::concept::btreebucket, "", 8192);
return (const BtreeBucket<V> *) r->data(); return (const BtreeBucket<V> *) r->data();
} }
} // namespace mongo
#include "database.h"
#include "memconcept.h"
namespace mongo {
boost::intmax_t dbSize( const char *database ); boost::intmax_t dbSize( const char *database );
inline NamespaceIndex* nsindex(const StringData& ns) { inline NamespaceIndex* nsindex(const StringData& ns) {
Database *database = cc().database(); Database *database = cc().database();
verify( database ); verify( database );
memconcept::is(database, memconcept::concept::database, ns, sizeof( Database)); memconcept::is(database, memconcept::concept::database, ns, sizeof( Database));
DEV { DEV {
StringData dbname = nsToDatabaseSubstring( ns ); StringData dbname = nsToDatabaseSubstring( ns );
if ( database->name() != dbname ) { if ( database->name() != dbname ) {
out() << "ERROR: attempt to write to wrong database\n"; out() << "ERROR: attempt to write to wrong database\n";
skipping to change at line 649 skipping to change at line 407
// if this faults, did you set the current db first? (Client::Cont ext + dblock) // if this faults, did you set the current db first? (Client::Cont ext + dblock)
NamespaceDetails *d = nsindex(ns)->details(ns); NamespaceDetails *d = nsindex(ns)->details(ns);
if( d ) { if( d ) {
memconcept::is(d, memconcept::concept::nsdetails, ns, sizeof(Na mespaceDetails)); memconcept::is(d, memconcept::concept::nsdetails, ns, sizeof(Na mespaceDetails));
} }
return d; return d;
} }
inline Extent* DataFileMgr::getExtent(const DiskLoc& dl) { inline Extent* DataFileMgr::getExtent(const DiskLoc& dl) {
verify( dl.a() != -1 ); verify( dl.a() != -1 );
return cc().database()->getFile(dl.a())->getExtent(dl); return cc().database()->getExtentManager().getExtent(dl);
} }
inline Record* DataFileMgr::getRecord(const DiskLoc& dl) { inline Record* DataFileMgr::getRecord(const DiskLoc& dl) {
verify(dl.a() != -1); verify(dl.a() != -1);
return cc().database()->getFile(dl.a())->recordAt(dl); return cc().database()->getExtentManager().recordFor( dl );
} }
BOOST_STATIC_ASSERT( 16 == sizeof(DeletedRecord) ); BOOST_STATIC_ASSERT( 16 == sizeof(DeletedRecord) );
inline DeletedRecord* DataFileMgr::getDeletedRecord(const DiskLoc& dl) { inline DeletedRecord* DataFileMgr::getDeletedRecord(const DiskLoc& dl) {
return reinterpret_cast<DeletedRecord*>(getRecord(dl)); return reinterpret_cast<DeletedRecord*>(getRecord(dl));
} }
inline BSONObj BSONObj::make(const Record* r ) { inline BSONObj BSONObj::make(const Record* r ) {
return BSONObj( r->data() ); return BSONObj( r->data() );
 End of changes. 12 change blocks. 
288 lines changed or deleted 13 lines changed or added


 pipeline.h   pipeline.h 
skipping to change at line 23 skipping to change at line 23
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* 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 <deque> #include <deque>
#include "mongo/pch.h" #include "mongo/pch.h"
#include "util/intrusive_counter.h" #include "mongo/util/intrusive_counter.h"
#include "util/timer.h" #include "mongo/util/timer.h"
namespace mongo { namespace mongo {
class BSONObj; class BSONObj;
class BSONObjBuilder; class BSONObjBuilder;
class BSONArrayBuilder; class BSONArrayBuilder;
class DocumentSource; class DocumentSource;
class DocumentSourceProject; class DocumentSourceProject;
class Expression; class Expression;
class ExpressionContext; struct ExpressionContext;
class ExpressionNary; class ExpressionNary;
struct OpDesc; // local private struct struct OpDesc; // local private struct
class Privilege;
/** mongodb "commands" (sent via db.$cmd.findOne(...)) /** mongodb "commands" (sent via db.$cmd.findOne(...))
subclass to make a command. define a singleton object for it. subclass to make a command. define a singleton object for it.
*/ */
class Pipeline : class Pipeline :
public IntrusiveCounterUnsigned { public IntrusiveCounterUnsigned {
public: public:
virtual ~Pipeline();
/** /**
Create a pipeline from the command. Create a pipeline from the command.
@param errmsg where to write errors, if there are any @param errmsg where to write errors, if there are any
@param cmdObj the command object sent from the client @param cmdObj the command object sent from the client
@returns the pipeline, if created, otherwise a NULL reference @returns the pipeline, if created, otherwise a NULL reference
*/ */
static intrusive_ptr<Pipeline> parseCommand( static intrusive_ptr<Pipeline> parseCommand(
string &errmsg, BSONObj &cmdObj, string &errmsg, BSONObj &cmdObj,
const intrusive_ptr<ExpressionContext> &pCtx); const intrusive_ptr<ExpressionContext> &pCtx);
/// Helper to implement Command::addRequiredPrivileges
static void addRequiredPrivileges(const string& inputNs,
BSONObj cmdObj,
vector<Privilege>* out);
/** /**
Get the collection name from the command. Get the collection name from the command.
@returns the collection name @returns the collection name
*/ */
string getCollectionName() const; string getCollectionName() const;
intrusive_ptr<ExpressionContext> getContext() const { return pCtx;
}
/** /**
Split the current Pipeline into a Pipeline for each shard, and Split the current Pipeline into a Pipeline for each shard, and
a Pipeline that combines the results within mongos. a Pipeline that combines the results within mongos.
This permanently alters this pipeline for the merging operation. This permanently alters this pipeline for the merging operation.
@returns the Spec for the pipeline command that should be sent @returns the Spec for the pipeline command that should be sent
to the shards to the shards
*/ */
intrusive_ptr<Pipeline> splitForSharded(); intrusive_ptr<Pipeline> splitForSharded();
skipping to change at line 135 skipping to change at line 141
@returns true if this is an explain @returns true if this is an explain
*/ */
bool isExplain() const; bool isExplain() const;
/// The initial source is special since it varies between mongos an d mongod. /// The initial source is special since it varies between mongos an d mongod.
void addInitialSource(intrusive_ptr<DocumentSource> source); void addInitialSource(intrusive_ptr<DocumentSource> source);
/// The source that represents the output. Returns a non-owning poi nter. /// The source that represents the output. Returns a non-owning poi nter.
DocumentSource* output() { return sources.back().get(); } DocumentSource* output() { return sources.back().get(); }
/// Returns true if this pipeline only uses features that work in m
ongos.
bool canRunInMongos() const;
/** /**
The aggregation command name. The aggregation command name.
*/ */
static const char commandName[]; static const char commandName[];
/* /*
PipelineD is a "sister" class that has additional functionality PipelineD is a "sister" class that has additional functionality
for the Pipeline. It exists because of linkage requirements. for the Pipeline. It exists because of linkage requirements.
Pipeline needs to function in mongod and mongos. PipelineD Pipeline needs to function in mongod and mongos. PipelineD
contains extra functionality required in mongod, and which can't contains extra functionality required in mongod, and which can't
 End of changes. 7 change blocks. 
5 lines changed or deleted 16 lines changed or added


 pipeline_d.h   pipeline_d.h 
skipping to change at line 23 skipping to change at line 23
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* 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"
namespace mongo { namespace mongo {
class DocumentSourceCursor; class DocumentSourceCursor;
struct ExpressionContext;
class Pipeline; class Pipeline;
/* /*
PipelineD is an extension of the Pipeline class, but with additional PipelineD is an extension of the Pipeline class, but with additional
material that references symbols that are not available in mongos, material that references symbols that are not available in mongos,
where the remainder of the Pipeline class also functions. PipelineD where the remainder of the Pipeline class also functions. PipelineD
is a friend of Pipeline so that it can have equal access to Pipeline' s is a friend of Pipeline so that it can have equal access to Pipeline' s
members. members.
See the friend declaration in Pipeline. See the friend declaration in Pipeline.
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 lines changed or added


 plan_stage.h   plan_stage.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 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 "mongo/db/exec/plan_stats.h"
#include "mongo/db/exec/working_set.h" #include "mongo/db/exec/working_set.h"
namespace mongo { namespace mongo {
class DiskLoc; class DiskLoc;
/** /**
* A PlanStage ("stage") is the basic building block of a "Query Execut ion Plan." A stage is * A PlanStage ("stage") is the basic building block of a "Query Execut ion Plan." A stage is
* the smallest piece of machinery used in executing a compiled query. Stages either access * the smallest piece of machinery used in executing a compiled query. Stages either access
* data (from a collection or an index) to create a stream of results, or transform a stream of * data (from a collection or an index) to create a stream of results, or transform a stream of
skipping to change at line 174 skipping to change at line 175
virtual void recoverFromYield() = 0; virtual void recoverFromYield() = 0;
/** /**
* Notifies a stage that a DiskLoc is going to be deleted (or in-pl ace updated) so that the * Notifies a stage that a DiskLoc is going to be deleted (or in-pl ace updated) so that the
* stage can invalidate or modify any state required to continue pr ocessing without this * stage can invalidate or modify any state required to continue pr ocessing without this
* DiskLoc. * DiskLoc.
* *
* Can only be called after a prepareToYield but before a recoverFr omYield. * Can only be called after a prepareToYield but before a recoverFr omYield.
*/ */
virtual void invalidate(const DiskLoc& dl) = 0; virtual void invalidate(const DiskLoc& dl) = 0;
/**
* Returns a tree of stats. See plan_stats.h for the details of th
is structure. If the
* stage has any children it must propagate the request for stats t
o them.
*
* Caller owns returned pointer.
*/
virtual PlanStageStats* getStats() = 0;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
0 lines changed or deleted 11 lines changed or added


 privilege.h   privilege.h 
skipping to change at line 23 skipping to change at line 23
* limitations under the License. * limitations under the License.
*/ */
#pragma once #pragma once
#include <string> #include <string>
#include <vector> #include <vector>
#include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h" #include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/principal.h"
namespace mongo { namespace mongo {
/** /**
* A representation of the permission to perform a set of actions on a specific resource. * A representation of the permission to perform a set of actions on a specific resource.
*/ */
class Privilege { class Privilege {
public: public:
Privilege(const std::string& resource, const ActionType& action); Privilege(const std::string& resource, const ActionType& action);
 End of changes. 1 change blocks. 
1 lines changed or deleted 0 lines changed or added


 progress_meter.h   progress_meter.h 
skipping to change at line 33 skipping to change at line 33
namespace mongo { namespace mongo {
class ProgressMeter : boost::noncopyable { class ProgressMeter : boost::noncopyable {
public: public:
ProgressMeter(unsigned long long total, ProgressMeter(unsigned long long total,
int secondsBetween = 3, int secondsBetween = 3,
int checkInterval = 100, int checkInterval = 100,
std::string units = "", std::string units = "",
std::string name = "Progress") std::string name = "Progress")
: _units(units) : _showTotal(true),
, _name(name) { _units(units),
_name(name) {
reset( total , secondsBetween , checkInterval ); reset( total , secondsBetween , checkInterval );
} }
ProgressMeter() : _active(0), _units(""), _name("Progress") {} ProgressMeter() : _active(0), _showTotal(true), _units(""), _name(" Progress") {}
// typically you do ProgressMeterHolder // typically you do ProgressMeterHolder
void reset( unsigned long long total , int secondsBetween = 3 , int checkInterval = 100 ); void reset( unsigned long long total , int secondsBetween = 3 , int checkInterval = 100 );
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
skipping to change at line 68 skipping to change at line 69
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; }
unsigned long long total() const { return _total; } unsigned long long total() const { return _total; }
void showTotal(bool doShow) {
_showTotal = doShow;
}
std::string toString() const; std::string toString() const;
bool operator==( const ProgressMeter& other ) const { return this = = &other; } bool operator==( const ProgressMeter& other ) const { return this = = &other; }
private: private:
bool _active; bool _active;
unsigned long long _total; unsigned long long _total;
bool _showTotal;
int _secondsBetween; int _secondsBetween;
int _checkInterval; int _checkInterval;
unsigned long long _done; unsigned long long _done;
unsigned long long _hits; unsigned long long _hits;
int _lastTime; int _lastTime;
std::string _units; std::string _units;
std::string _name; std::string _name;
}; };
 End of changes. 4 change blocks. 
3 lines changed or deleted 9 lines changed or added


 query.h   query.h 
skipping to change at line 34 skipping to change at line 34
#include "mongo/db/dbmessage.h" #include "mongo/db/dbmessage.h"
#include "mongo/db/explain.h" #include "mongo/db/explain.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/s/collection_metadata.h" #include "mongo/s/collection_metadata.h"
#include "mongo/util/net/message.h" #include "mongo/util/net/message.h"
// struct QueryOptions, QueryResult, QueryResultFlags in: // struct QueryOptions, QueryResult, QueryResultFlags in:
namespace mongo { namespace mongo {
class CurOp;
class ParsedQuery; class ParsedQuery;
class QueryOptimizerCursor; class QueryOptimizerCursor;
struct QueryPlanSummary; struct QueryPlanSummary;
extern const int32_t MaxBytesToReturnToClientAtOnce; extern const int32_t MaxBytesToReturnToClientAtOnce;
/** /**
* Return a batch of results from a client OP_GET_MORE request. * Return a batch of results from a client OP_GET_MORE request.
* 'cursorid' - The id of the cursor producing results. * 'cursorid' - The id of the cursor producing results.
* 'isCursorAuthorized' - Set to true after a cursor with id 'cursorid' is authorized for use. * 'isCursorAuthorized' - Set to true after a cursor with id 'cursorid' is authorized for use.
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 lines changed or added


 query_optimizer_internal.h   query_optimizer_internal.h 
skipping to change at line 245 skipping to change at line 245
bool _complete; bool _complete;
bool _stopRequested; bool _stopRequested;
ExceptionInfo _exception; ExceptionInfo _exception;
const QueryPlan* _queryPlan; const QueryPlan* _queryPlan;
bool _error; bool _error;
CachedMatchCounter _matchCounter; CachedMatchCounter _matchCounter;
bool _countingMatches; bool _countingMatches;
bool _mustAdvance; bool _mustAdvance;
bool _capped; bool _capped;
shared_ptr<Cursor> _c; shared_ptr<Cursor> _c;
ClientCursor::Holder _cc; ClientCursorHolder _cc;
DiskLoc _posBeforeYield; DiskLoc _posBeforeYield;
ClientCursor::YieldData _yieldData; ClientCursor::YieldData _yieldData;
const QueryPlanSelectionPolicy& _selectionPolicy; const QueryPlanSelectionPolicy& _selectionPolicy;
const bool& _requireOrder; // TODO don't use a ref for this, but si gnal change explicitly const bool& _requireOrder; // TODO don't use a ref for this, but si gnal change explicitly
shared_ptr<ExplainPlanInfo> _explainPlanInfo; shared_ptr<ExplainPlanInfo> _explainPlanInfo;
bool _alwaysCountMatches; bool _alwaysCountMatches;
}; };
/** /**
* This class works if T::operator< is variant unlike a regular stl pri ority queue, but it's * This class works if T::operator< is variant unlike a regular stl pri ority queue, but it's
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 range_arithmetic.h   range_arithmetic.h 
skipping to change at line 53 skipping to change at line 53
* contains Id(DocB) * contains Id(DocB)
* *
* keyPattern : { field : "numberofletters" } * keyPattern : { field : "numberofletters" }
* minKey : { field : 4 } : numberofletters(DocA) * minKey : { field : 4 } : numberofletters(DocA)
* maxKey : { field : 5 } : numberofletters(DocC) * maxKey : { field : 5 } : numberofletters(DocC)
* *
* does not contain numberofletters(DocB) * does not contain numberofletters(DocB)
*/ */
struct KeyRange { struct KeyRange {
KeyRange( const std::string& ns_, KeyRange( const std::string& ns,
const BSONObj& minKey_, const BSONObj& minKey,
const BSONObj& maxKey_, const BSONObj& maxKey,
const BSONObj& keyPattern_ ) : const BSONObj& keyPattern ) :
ns( ns_ ), minKey( minKey_ ), maxKey( maxKey_ ), keyPattern ns( ns ), minKey( minKey ), maxKey( maxKey ), keyPattern( k
( keyPattern_ ) eyPattern )
{ {
} }
KeyRange() {}
std::string ns; std::string ns;
BSONObj minKey; BSONObj minKey;
BSONObj maxKey; BSONObj maxKey;
BSONObj keyPattern; BSONObj keyPattern;
}; };
/** /**
* Returns true if the point is within the range [inclusiveLower, exclu siveUpper). * Returns true if the point is within the range [inclusiveLower, exclu siveUpper).
*/ */
bool rangeContains( const BSONObj& inclusiveLower, bool rangeContains( const BSONObj& inclusiveLower,
skipping to change at line 132 skipping to change at line 134
const BSONObj& exclusiveUpper ); const BSONObj& exclusiveUpper );
/** /**
* Returns true if the provided range map exactly contains the provided range * Returns true if the provided range map exactly contains the provided range
* [inclusiveLower, exclusiveUpper). * [inclusiveLower, exclusiveUpper).
*/ */
bool rangeMapContains( const RangeMap& ranges, bool rangeMapContains( const RangeMap& ranges,
const BSONObj& inclusiveLower, const BSONObj& inclusiveLower,
const BSONObj& exclusiveUpper ); const BSONObj& exclusiveUpper );
/**
* String representation of [inclusiveLower, exclusiveUpper)
*/
std::string rangeToString( const BSONObj& inclusiveLower,
const BSONObj& exclusiveUpper );
/**
* String representation of overlapping ranges as a list "[range1),[ran
ge2),..."
*/
std::string overlapToString( RangeVector overlap );
} }
 End of changes. 3 change blocks. 
6 lines changed or deleted 20 lines changed or added


 redef_macros.h   redef_macros.h 
skipping to change at line 51 skipping to change at line 51
#define dassert MONGO_dassert #define dassert MONGO_dassert
#pragma push_macro("wassert") #pragma push_macro("wassert")
#undef wassert #undef wassert
#define wassert MONGO_wassert #define wassert MONGO_wassert
#pragma push_macro("massert") #pragma push_macro("massert")
#undef massert #undef massert
#define massert MONGO_massert #define massert MONGO_massert
#pragma push_macro("uassert") #pragma push_macro("uassert")
#undef uassert #undef uassert
#define uassert MONGO_uassert #define uassert MONGO_uassert
#pragma push_macro("uassertStatusOK")
#undef uassertStatusOK
#define uassertStatusOK MONGO_uassertStatusOK
#pragma push_macro("DESTRUCTOR_GUARD") #pragma push_macro("DESTRUCTOR_GUARD")
#undef DESTRUCTOR_GUARD #undef DESTRUCTOR_GUARD
#define DESTRUCTOR_GUARD MONGO_DESTRUCTOR_GUARD #define DESTRUCTOR_GUARD MONGO_DESTRUCTOR_GUARD
// util/goodies.h // util/goodies.h
#pragma push_macro("PRINT") #pragma push_macro("PRINT")
#undef PRINT #undef PRINT
#define PRINT MONGO_PRINT #define PRINT MONGO_PRINT
#pragma push_macro("PRINTFL") #pragma push_macro("PRINTFL")
#undef PRINTFL #undef PRINTFL
 End of changes. 1 change blocks. 
3 lines changed or deleted 0 lines changed or added


 request.h   request.h 
skipping to change at line 21 skipping to change at line 21
* 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 "mongo/pch.h" #include "mongo/pch.h"
#include "../util/net/message.h"
#include "../db/dbmessage.h" #include "mongo/db/dbmessage.h"
#include "config.h" #include "mongo/s/config.h"
#include "mongo/util/net/message.h"
namespace mongo { namespace mongo {
class OpCounters; class OpCounters;
class ClientInfo; class ClientInfo;
class Request : boost::noncopyable { class Request : boost::noncopyable {
public: public:
Request( Message& m, AbstractMessagingPort* p ); Request( Message& m, AbstractMessagingPort* p );
 End of changes. 1 change blocks. 
3 lines changed or deleted 4 lines changed or added


 restapi.h   restapi.h 
skipping to change at line 24 skipping to change at line 24
* 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 <string> #include <string>
#include "mongo/db/auth/user_name.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/util/admin_access.h" #include "mongo/util/admin_access.h"
namespace mongo { namespace mongo {
class RestAdminAccess : public AdminAccess { class RestAdminAccess : public AdminAccess {
public: public:
virtual ~RestAdminAccess() { } virtual ~RestAdminAccess() { }
virtual bool haveAdminUsers() const; virtual bool haveAdminUsers() const;
virtual BSONObj getAdminUser( const std::string& username ) const; virtual BSONObj getAdminUser(const UserName& username) const;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
1 lines changed or deleted 2 lines changed or added


 rs.h   rs.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
#include "mongo/db/commands.h" #include "mongo/db/commands.h"
#include "mongo/db/index.h" #include "mongo/db/index.h"
#include "mongo/db/repl/oplogreader.h" #include "mongo/db/repl/oplogreader.h"
#include "mongo/db/repl/optime.h" #include "mongo/bson/optime.h"
#include "mongo/db/repl/rs_config.h" #include "mongo/db/repl/rs_config.h"
#include "mongo/db/repl/rs_exception.h" #include "mongo/db/repl/rs_exception.h"
#include "mongo/db/repl/rs_member.h" #include "mongo/db/repl/rs_member.h"
#include "mongo/db/repl/rs_sync.h" #include "mongo/db/repl/rs_sync.h"
#include "mongo/db/repl/sync_source_feedback.h"
#include "mongo/util/concurrency/list.h" #include "mongo/util/concurrency/list.h"
#include "mongo/util/concurrency/msg.h" #include "mongo/util/concurrency/msg.h"
#include "mongo/util/concurrency/thread_pool.h" #include "mongo/util/concurrency/thread_pool.h"
#include "mongo/util/concurrency/value.h" #include "mongo/util/concurrency/value.h"
#include "mongo/util/net/hostandport.h" #include "mongo/util/net/hostandport.h"
/** /**
* Order of Events * Order of Events
* *
* On startup, if the --replSet option is present, startReplSets is called. * On startup, if the --replSet option is present, startReplSets is called.
skipping to change at line 151 skipping to change at line 152
* *
* We can't just directly sync to the primary because it could be * We can't just directly sync to the primary because it could be
* unreachable, e.g., S1--->S2--->S3--->P. S2 should ghost sync fr om S3 * unreachable, e.g., S1--->S2--->S3--->P. S2 should ghost sync fr om S3
* and S3 can ghost sync from the primary. * and S3 can ghost sync from the primary.
* *
* Say we have an S1--->S2--->P situation and this node is S2. rid * Say we have an S1--->S2--->P situation and this node is S2. rid
* would refer to S1. S2 would create a ghost slave of S1 and conn ect * would refer to S1. S2 would create a ghost slave of S1 and conn ect
* it to P (_currentSyncTarget). Then it would use this connection to * it to P (_currentSyncTarget). Then it would use this connection to
* pretend to be S1, replicating off of P. * pretend to be S1, replicating off of P.
*/ */
void percolate(const BSONObj& rid, const OpTime& last); void percolate(const mongo::OID& rid, const OpTime& last);
void associateSlave(const BSONObj& rid, const int memberId); void associateSlave(const BSONObj& rid, const int memberId);
void updateSlave(const mongo::OID& id, const OpTime& last); void updateSlave(const mongo::OID& id, const OpTime& last);
void clearCache(); void clearCache();
}; };
class Consensus { class Consensus {
ReplSetImpl &rs; ReplSetImpl &rs;
struct LastYea { struct LastYea {
LastYea() : when(0), who(0xffffffff) { } LastYea() : when(0), who(0xffffffff) { }
time_t when; time_t when;
skipping to change at line 344 skipping to change at line 345
/* todo thread */ /* todo thread */
void msgUpdateHBInfo(HeartbeatInfo); void msgUpdateHBInfo(HeartbeatInfo);
/** /**
* Updates the lastHeartbeatRecv of Member with the given id. * Updates the lastHeartbeatRecv of Member with the given id.
*/ */
void msgUpdateHBRecv(unsigned id, time_t newTime); void msgUpdateHBRecv(unsigned id, time_t newTime);
StateBox box; StateBox box;
SyncSourceFeedback syncSourceFeedback;
OpTime lastOpTimeWritten; OpTime lastOpTimeWritten;
long long lastH; // hash we use to make sure we are reading the rig ht flow of ops and aren't on an out-of-date "fork" long long lastH; // hash we use to make sure we are reading the rig ht flow of ops and aren't on an out-of-date "fork"
bool forceSyncFrom(const string& host, string& errmsg, BSONObjBuild er& result); bool forceSyncFrom(const string& host, string& errmsg, BSONObjBuild er& result);
// Check if the current sync target is suboptimal. This must be cal led while holding a mutex // Check if the current sync target is suboptimal. This must be cal led while holding a mutex
// that prevents the sync source from changing. // that prevents the sync source from changing.
bool shouldChangeSyncTarget(const OpTime& target) const; bool shouldChangeSyncTarget(const OpTime& target) const;
/** /**
* Find the closest member (using ping time) with a higher latest o ptime. * Find the closest member (using ping time) with a higher latest o ptime.
*/ */
skipping to change at line 508 skipping to change at line 511
* have called it again, passing in false. * have called it again, passing in false.
*/ */
bool setMaintenanceMode(const bool inc); bool setMaintenanceMode(const bool inc);
// Records a new slave's id in the GhostSlave map, at handshake tim e. // Records a new slave's id in the GhostSlave map, at handshake tim e.
void registerSlave(const BSONObj& rid, const int memberId); void registerSlave(const BSONObj& rid, const int memberId);
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* getMutableMember(unsigned id);
Member* findByName(const std::string& hostname) 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;
skipping to change at line 565 skipping to change at line 569
threadpool::ThreadPool& getPrefetchPool() { return _prefetcherPool; } threadpool::ThreadPool& getPrefetchPool() { return _prefetcherPool; }
threadpool::ThreadPool& getWriterPool() { return _writerPool; } threadpool::ThreadPool& getWriterPool() { return _writerPool; }
static const int maxSyncSourceLagSecs; static const int maxSyncSourceLagSecs;
const ReplSetConfig::MemberCfg& myConfig() const { return _config; } const ReplSetConfig::MemberCfg& myConfig() const { return _config; }
bool tryToGoLiveAsASecondary(OpTime&); // readlocks bool tryToGoLiveAsASecondary(OpTime&); // readlocks
void syncRollback(OplogReader& r); void syncRollback(OplogReader& r);
void syncThread(); void syncThread();
const OpTime lastOtherOpTime() const; const OpTime lastOtherOpTime() const;
/**
* The most up to date electable replica
*/
const OpTime lastOtherElectableOpTime() const;
/** /**
* When a member reaches its minValid optime it is in a consistent state. Thus, minValid is * When a member reaches its minValid optime it is in a consistent state. Thus, minValid is
* set as the last step in initial sync. At the beginning of initi al sync, _initialSyncFlag * set as the last step in initial sync. At the beginning of initi al sync, _initialSyncFlag
* is appended onto minValid to indicate that initial sync was star ted but has not yet * is appended onto minValid to indicate that initial sync was star ted but has not yet
* completed. * completed.
* minValid is also used during "normal" sync: the last op in each batch is used to set * minValid is also used during "normal" sync: the last op in each batch is used to set
* minValid, to indicate that we are in a consistent state when the batch has been fully * minValid, to indicate that we are in a consistent state when the batch has been fully
* applied. * applied.
*/ */
 End of changes. 6 change blocks. 
2 lines changed or deleted 10 lines changed or added


 safe_num-inl.h   safe_num-inl.h 
skipping to change at line 63 skipping to change at line 63
} }
inline SafeNum SafeNum::operator+(const SafeNum& rhs) const { inline SafeNum SafeNum::operator+(const SafeNum& rhs) const {
return addInternal(*this, rhs); return addInternal(*this, rhs);
} }
inline SafeNum& SafeNum::operator+=(const SafeNum& rhs) { inline SafeNum& SafeNum::operator+=(const SafeNum& rhs) {
return *this = addInternal(*this, rhs); return *this = addInternal(*this, rhs);
} }
inline SafeNum SafeNum::operator*(const SafeNum& rhs) const {
return mulInternal(*this, rhs);
}
inline SafeNum& SafeNum::operator*=(const SafeNum& rhs) {
return *this = mulInternal(*this, rhs);
}
inline SafeNum SafeNum::bitAnd(const SafeNum& rhs) const { inline SafeNum SafeNum::bitAnd(const SafeNum& rhs) const {
return andInternal(*this, rhs); return andInternal(*this, rhs);
} }
inline SafeNum SafeNum::operator&(const SafeNum& rhs) const { inline SafeNum SafeNum::operator&(const SafeNum& rhs) const {
return bitAnd(rhs); return bitAnd(rhs);
} }
inline SafeNum& SafeNum::operator&=(const SafeNum& rhs) { inline SafeNum& SafeNum::operator&=(const SafeNum& rhs) {
return *this = bitAnd(rhs); return *this = bitAnd(rhs);
skipping to change at line 87 skipping to change at line 95
} }
inline SafeNum SafeNum::operator|(const SafeNum& rhs) const { inline SafeNum SafeNum::operator|(const SafeNum& rhs) const {
return bitOr(rhs); return bitOr(rhs);
} }
inline SafeNum& SafeNum::operator|=(const SafeNum& rhs) { inline SafeNum& SafeNum::operator|=(const SafeNum& rhs) {
return *this = bitOr(rhs); return *this = bitOr(rhs);
} }
inline SafeNum SafeNum::bitXor(const SafeNum& rhs) const {
return xorInternal(*this, rhs);
}
inline SafeNum SafeNum::operator^(const SafeNum& rhs) const {
return bitXor(rhs);
}
inline SafeNum& SafeNum::operator^=(const SafeNum& rhs) {
return *this = bitXor(rhs);
}
inline bool SafeNum::isValid() const { inline bool SafeNum::isValid() const {
return _type != EOO; return _type != EOO;
} }
inline BSONType SafeNum::type() const { inline BSONType SafeNum::type() const {
return _type; return _type;
} }
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
0 lines changed or deleted 20 lines changed or added


 safe_num.h   safe_num.h 
skipping to change at line 102 skipping to change at line 102
* anything else, even another EOO-typed instance. Otherwise, retur ns false. * anything else, even another EOO-typed instance. Otherwise, retur ns false.
*/ */
bool isIdentical(const SafeNum& rhs) const; bool isIdentical(const SafeNum& rhs) const;
// //
// arithmetic support // arithmetic support
// //
/** /**
* Sums the 'rhs' -- right-hand side -- safe num with this, taking care of * Sums the 'rhs' -- right-hand side -- safe num with this, taking care of
* upconvertions and overflow (see class header). * upconversions and overflow (see class header).
*/ */
SafeNum operator+(const SafeNum& rhs) const; SafeNum operator+(const SafeNum& rhs) const;
SafeNum& operator+=(const SafeNum& rhs); SafeNum& operator+=(const SafeNum& rhs);
// TODO other operations than sum
/**
* Multiplies the 'rhs' -- right-hand side -- safe num with this, t
aking care of
* upconversions and overflow (see class header).
*/
SafeNum operator*(const SafeNum& rhs) const;
SafeNum& operator*=(const SafeNum& rhs);
// //
// logical operation support. Note that these operations are only s upported for // logical operation support. Note that these operations are only s upported for
// integral types. Attempts to apply with either side holding a dou ble value // integral types. Attempts to apply with either side holding a dou ble value
// will result in an EOO typed safenum. // will result in an EOO typed safenum.
// //
// Bitwise 'and' support // Bitwise 'and' support
SafeNum bitAnd(const SafeNum& rhs) const; SafeNum bitAnd(const SafeNum& rhs) const;
SafeNum operator&(const SafeNum& rhs) const; SafeNum operator&(const SafeNum& rhs) const;
SafeNum& operator&=(const SafeNum& rhs); SafeNum& operator&=(const SafeNum& rhs);
// Bitwise 'or' support // Bitwise 'or' support
SafeNum bitOr(const SafeNum& rhs) const; SafeNum bitOr(const SafeNum& rhs) const;
SafeNum operator|(const SafeNum& rhs) const; SafeNum operator|(const SafeNum& rhs) const;
SafeNum& operator|=(const SafeNum& rhs); SafeNum& operator|=(const SafeNum& rhs);
// Bitwise 'xor' support
SafeNum bitXor(const SafeNum& rhs) const;
SafeNum operator^(const SafeNum& rhs) const;
SafeNum& operator^=(const SafeNum& rhs);
// //
// output support // output support
// //
friend class mutablebson::Element; friend class mutablebson::Element;
friend class mutablebson::Document; friend class mutablebson::Document;
// TODO: output to builder // TODO: output to builder
// //
skipping to change at line 167 skipping to change at line 178
double doubleVal; double doubleVal;
} _value; } _value;
/** /**
* Returns the sum of 'lhs' and 'rhs', taking into consideration th eir types. The * Returns the sum of 'lhs' and 'rhs', taking into consideration th eir types. The
* type of the result would upcast, if necessary and permitted. Oth erwise, returns * type of the result would upcast, if necessary and permitted. Oth erwise, returns
* an EOO-type instance. * an EOO-type instance.
*/ */
static SafeNum addInternal(const SafeNum& lhs, const SafeNum& rhs); static SafeNum addInternal(const SafeNum& lhs, const SafeNum& rhs);
/**
* Returns the product of 'lhs' and 'rhs', taking into consideratio
n their types. The
* type of the result would upcast, if necessary and permitted. Oth
erwise, returns an
* EOO-type instance.
*/
static SafeNum mulInternal(const SafeNum& lhs, const SafeNum& rhs);
/** Returns the bitwise 'and' of lhs and rhs, taking into considera tion their types. If /** Returns the bitwise 'and' of lhs and rhs, taking into considera tion their types. If
* the operation is invalid for the underlying types, returns an E OO instance. * the operation is invalid for the underlying types, returns an E OO instance.
*/ */
static SafeNum andInternal(const SafeNum& lhs, const SafeNum& rhs); static SafeNum andInternal(const SafeNum& lhs, const SafeNum& rhs);
/** Returns the bitwise 'or' of lhs and rhs, taking into considerat ion their types. If /** Returns the bitwise 'or' of lhs and rhs, taking into considerat ion their types. If
* the operation is invalid for the underlying types, returns an E OO instance. * the operation is invalid for the underlying types, returns an E OO instance.
*/ */
static SafeNum orInternal(const SafeNum& lhs, const SafeNum& rhs); static SafeNum orInternal(const SafeNum& lhs, const SafeNum& rhs);
/** Returns the bitwise 'xor' of lhs and rhs, taking into considera
tion their types. If
* the operation is invalid for the underlying types, returns an E
OO instance.
*/
static SafeNum xorInternal(const SafeNum& lhs, const SafeNum& rhs);
/** /**
* Extracts the value of 'snum' in a long format. It assumes 'snum' is an NumberInt * Extracts the value of 'snum' in a long format. It assumes 'snum' is an NumberInt
* or a NumberDouble. * or a NumberDouble.
*/ */
static long long getLongLong(const SafeNum& snum); static long long getLongLong(const SafeNum& snum);
/** /**
* Extracts the value of 'snum' in a double format. It assumes 'snu m' is a valid * Extracts the value of 'snum' in a double format. It assumes 'snu m' is a valid
* SafeNum, i.e., that _type is not EOO. * SafeNum, i.e., that _type is not EOO.
*/ */
 End of changes. 5 change blocks. 
2 lines changed or deleted 30 lines changed or added


 shard.h   shard.h 
skipping to change at line 310 skipping to change at line 310
* Note: This is *dangerous* if we have GLE state. * Note: This is *dangerous* if we have GLE state.
*/ */
static void releaseMyConnections(); static void releaseMyConnections();
/** /**
* Clears all connections in the sharded pool, including connection s in the * Clears all connections in the sharded pool, including connection s in the
* thread local storage pool of the current thread. * thread local storage pool of the current thread.
*/ */
static void clearPool(); static void clearPool();
/**
* Forgets a namespace to prevent future versioning.
*/
static void forgetNS( const string& ns );
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;
 End of changes. 1 change blocks. 
0 lines changed or deleted 5 lines changed or added


 skip.h   skip.h 
skipping to change at line 43 skipping to change at line 43
SkipStage(int toSkip, WorkingSet* ws, PlanStage* child); SkipStage(int toSkip, WorkingSet* ws, PlanStage* child);
virtual ~SkipStage(); virtual ~SkipStage();
virtual bool isEOF(); virtual bool isEOF();
virtual StageState work(WorkingSetID* out); virtual StageState work(WorkingSetID* out);
virtual void prepareToYield(); virtual void prepareToYield();
virtual void recoverFromYield(); virtual void recoverFromYield();
virtual void invalidate(const DiskLoc& dl); virtual void invalidate(const DiskLoc& dl);
virtual PlanStageStats* getStats();
private: private:
WorkingSet* _ws; WorkingSet* _ws;
scoped_ptr<PlanStage> _child; scoped_ptr<PlanStage> _child;
// We drop the first _toSkip results that we would have returned. // We drop the first _toSkip results that we would have returned.
int _toSkip; int _toSkip;
// Stats
CommonStats _commonStats;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 2 change blocks. 
0 lines changed or deleted 5 lines changed or added


 sock.h   sock.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/pch.h"
#include <stdio.h> #include <stdio.h>
#ifndef _WIN32 #ifndef _WIN32
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <errno.h> #include <errno.h>
#ifdef __openbsd__ #ifdef __openbsd__
# include <sys/uio.h> # include <sys/uio.h>
#endif #endif
#endif // not _WIN32 #endif // not _WIN32
#ifdef MONGO_SSL #ifdef MONGO_SSL
#include <openssl/ssl.h> #include <openssl/ssl.h>
#endif #endif
#include <string>
#include <utility>
#include <vector>
#include "mongo/base/disallow_copying.h"
#include "mongo/logger/log_severity.h" #include "mongo/logger/log_severity.h"
#include "mongo/platform/compiler.h" #include "mongo/platform/compiler.h"
#include "mongo/platform/cstdint.h"
#include "mongo/util/assert_util.h"
namespace mongo { namespace mongo {
class SSLManagerInterface; class SSLManagerInterface;
const int SOCK_FAMILY_UNKNOWN_ERROR=13078; const int SOCK_FAMILY_UNKNOWN_ERROR=13078;
void disableNagle(int sock); void disableNagle(int sock);
#if defined(_WIN32) #if defined(_WIN32)
skipping to change at line 72 skipping to change at line 77
}; };
#else // _WIN32 #else // _WIN32
inline void closesocket(int s) { close(s); } inline void closesocket(int s) { close(s); }
const int INVALID_SOCKET = -1; const int INVALID_SOCKET = -1;
typedef int SOCKET; typedef int SOCKET;
#endif // _WIN32 #endif // _WIN32
string makeUnixSockPath(int port); std::string makeUnixSockPath(int port);
// If an ip address is passed in, just return that. If a hostname is p assed // If an ip address is passed in, just return that. If a hostname is p assed
// in, look up its ip and return that. Returns "" on failure. // in, look up its ip and return that. Returns "" on failure.
string hostbyname(const char *hostname); std::string hostbyname(const char *hostname);
void enableIPv6(bool state=true); void enableIPv6(bool state=true);
bool IPv6Enabled(); bool IPv6Enabled();
void setSockTimeouts(int sock, double secs); void setSockTimeouts(int sock, double secs);
/** /**
* wrapped around os representation of network address * wrapped around os representation of network address
*/ */
struct SockAddr { struct SockAddr {
SockAddr() { SockAddr() {
addressSize = sizeof(sa); addressSize = sizeof(sa);
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
sa.ss_family = AF_UNSPEC; sa.ss_family = AF_UNSPEC;
} }
explicit SockAddr(int sourcePort); /* listener side */ explicit SockAddr(int sourcePort); /* listener side */
SockAddr(const char *ip, int port); /* EndPoint (remote) side, or i f you want to specify which interface locally */ SockAddr(const char *ip, int port); /* EndPoint (remote) side, or i f you want to specify which interface locally */
template <typename T> T& as() { return *(T*)(&sa); } template <typename T> T& as() { return *(T*)(&sa); }
template <typename T> const T& as() const { return *(const T*)(&sa) ; } template <typename T> const T& as() const { return *(const T*)(&sa) ; }
string toString(bool includePort=true) const; std::string toString(bool includePort=true) const;
/** /**
* @return one of AF_INET, AF_INET6, or AF_UNIX * @return one of AF_INET, AF_INET6, or AF_UNIX
*/ */
sa_family_t getType() const; sa_family_t getType() const;
unsigned getPort() const; unsigned getPort() const;
string getAddr() const; std::string getAddr() const;
bool isLocalHost() const; bool isLocalHost() const;
bool operator==(const SockAddr& r) const; bool operator==(const SockAddr& r) const;
bool operator!=(const SockAddr& r) const; bool operator!=(const SockAddr& r) const;
bool operator<(const SockAddr& r) const; bool operator<(const SockAddr& r) const;
const sockaddr* raw() const {return (sockaddr*)&sa;} const sockaddr* raw() const {return (sockaddr*)&sa;}
sockaddr* raw() {return (sockaddr*)&sa;} sockaddr* raw() {return (sockaddr*)&sa;}
socklen_t addressSize; socklen_t addressSize;
private: private:
struct sockaddr_storage sa; struct sockaddr_storage sa;
}; };
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(); std::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(); std::string getHostNameCached();
string prettyHostName(); std::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 , const std::string& server , int code = 90 01 , const std::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( std::string("socket exception [") + _getStringT ype( 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 std::string toString() const;
virtual const std::string* server() const { return &_server; } 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 std::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";
case FAILED_STATE: return "FAILED_STATE"; case FAILED_STATE: return "FAILED_STATE";
case CONNECT_ERROR: return "CONNECT_ERROR"; case CONNECT_ERROR: return "CONNECT_ERROR";
default: return "UNKNOWN"; // should never happe n default: return "UNKNOWN"; // should never happe n
} }
} }
string _server; std::string _server;
string _extra; std::string _extra;
}; };
/** /**
* thin wrapped around file descriptor and system calls * thin wrapped around file descriptor and system calls
* todo: ssl * todo: ssl
*/ */
class Socket : boost::noncopyable { class Socket {
MONGO_DISALLOW_COPYING(Socket);
public: public:
static const int errorPollIntervalSecs; static const int errorPollIntervalSecs;
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, logger::LogSeverity logLevel = logger ::LogSeverity::Log() ); Socket(double so_timeout = 0, logger::LogSeverity logLevel = logger ::LogSeverity::Log() );
~Socket(); ~Socket();
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 std::vector< std::pair< char *, int > > &data, con st char *context );
// 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 );
logger::LogSeverity getLogLevel() const { return _logLevel; } logger::LogSeverity getLogLevel() const { return _logLevel; }
void setLogLevel( logger::LogSeverity ll ) { _logLevel = ll; } void setLogLevel( logger::LogSeverity ll ) { _logLevel = ll; }
SockAddr remoteAddr() const { return _remote; } SockAddr remoteAddr() const { return _remote; }
string remoteString() const { return _remote.toString(); } std::string remoteString() const { return _remote.toString(); }
unsigned remotePort() const { return _remote.getPort(); } unsigned remotePort() const { return _remote.getPort(); }
SockAddr localAddr() const { return _local; }
void clearCounters() { _bytesIn = 0; _bytesOut = 0; } void clearCounters() { _bytesIn = 0; _bytesOut = 0; }
long long getBytesIn() const { return _bytesIn; } long long getBytesIn() const { return _bytesIn; }
long long getBytesOut() const { return _bytesOut; } long long getBytesOut() const { return _bytesOut; }
void setTimeout( double secs ); void setTimeout( double secs );
bool isStillConnected(); bool isStillConnected();
#ifdef MONGO_SSL #ifdef MONGO_SSL
/** secures inline */ /** secures inline */
void secure( SSLManagerInterface* ssl ); void secure( SSLManagerInterface* ssl );
skipping to change at line 246 skipping to change at line 254
* @return the time when the socket was opened. * @return the time when the socket was opened.
*/ */
uint64_t getSockCreationMicroSec() const { uint64_t getSockCreationMicroSec() const {
return _fdCreationMicroSec; return _fdCreationMicroSec;
} }
private: private:
void _init(); void _init();
/** sends dumbly, just each buffer at a time */ /** sends dumbly, just each buffer at a time */
void _send( const vector< pair< char *, int > > &data, const char * context ); void _send( const std::vector< std::pair< char *, int > > &data, co nst char *context );
/** raw send, same semantics as ::send */ /** raw send, same semantics as ::send */
int _send( const char * data , int len ); int _send( const char * data , int len );
/** raw recv, same semantics as ::recv */ /** raw recv, same semantics as ::recv */
int _recv( char * buf , int max ); int _recv( char * buf , int max );
void _handleRecvError(int ret, int len, int* retries); void _handleRecvError(int ret, int len, int* retries);
MONGO_COMPILER_NORETURN void _handleSendError(int ret, const char* context); MONGO_COMPILER_NORETURN void _handleSendError(int ret, const char* context);
int _fd; int _fd;
uint64_t _fdCreationMicroSec; uint64_t _fdCreationMicroSec;
SockAddr _local;
SockAddr _remote; SockAddr _remote;
double _timeout; double _timeout;
long long _bytesIn; long long _bytesIn;
long long _bytesOut; long long _bytesOut;
time_t _lastValidityCheckAtSecs; time_t _lastValidityCheckAtSecs;
#ifdef MONGO_SSL #ifdef MONGO_SSL
SSL* _ssl; SSL* _ssl;
SSLManagerInterface* _sslManager; SSLManagerInterface* _sslManager;
 End of changes. 20 change blocks. 
18 lines changed or deleted 27 lines changed or added


 strategy.h   strategy.h 
skipping to change at line 36 skipping to change at line 36
class Strategy { class Strategy {
public: public:
Strategy() {} Strategy() {}
virtual ~Strategy() {} virtual ~Strategy() {}
virtual void queryOp( Request& r ) = 0; virtual void queryOp( Request& r ) = 0;
virtual void getMore( Request& r ) = 0; virtual void getMore( Request& r ) = 0;
virtual void writeOp( int op , Request& r ) = 0; virtual void writeOp( int op , Request& r ) = 0;
void insert( const Shard& shard , const char * ns , const BSONObj& obj , int flags=0 , bool safe=false ); void insert( const Shard& shard , const char * ns , const BSONObj& obj , int flags=0 , bool safe=false );
virtual void commandOp( const string& db, const BSONObj& command, i struct CommandResult {
nt options, Shard shardTarget;
const string& versionedNS, const BSONObj& f ConnectionString target;
ilter, BSONObj result;
map<Shard,BSONObj>& results ) };
virtual void commandOp( const string& db,
const BSONObj& command,
int options,
const string& versionedNS,
const BSONObj& targetingQuery,
vector<CommandResult>* results )
{ {
// Only call this from sharded, for now. // Only call this from sharded, for now.
// TODO: Refactor all this. // TODO: Refactor all this.
verify( false ); verify( false );
} }
// These interfaces will merge soon, so make it easy to share logic // These interfaces will merge soon, so make it easy to share logic
friend class ShardStrategy; friend class ShardStrategy;
friend class SingleStrategy; friend class SingleStrategy;
 End of changes. 1 change blocks. 
5 lines changed or deleted 12 lines changed or added


 string_data.h   string_data.h 
skipping to change at line 138 skipping to change at line 138
/** /**
* Functor compatible with std::hash for std::unordered_{map,set} * Functor compatible with std::hash for std::unordered_{map,set}
* Warning: The hash function is subject to change. Do not use in c ases where hashes need * Warning: The hash function is subject to change. Do not use in c ases where hashes need
* to be consistent across versions. * to be consistent across versions.
*/ */
struct Hasher { struct Hasher {
size_t operator() (const StringData& str) const; size_t operator() (const StringData& str) const;
}; };
//
// iterators
//
typedef const char* const_iterator;
const_iterator begin() const { return rawData(); }
const_iterator end() const { return rawData() + size(); }
private: private:
const char* _data; // is not guaranted to be null terminated (see "notes" above) const char* _data; // is not guaranted to be null terminated (see "notes" above)
mutable size_t _size; // 'size' does not include the null termi nator mutable size_t _size; // 'size' does not include the null termi nator
void fillSize() const { void fillSize() const {
if (_size == string::npos) { if (_size == string::npos) {
_size = strlen(_data); _size = strlen(_data);
} }
} }
}; };
skipping to change at line 177 skipping to change at line 186
} }
inline bool operator>=(const StringData& lhs, const StringData& rhs) { inline bool operator>=(const StringData& lhs, const StringData& rhs) {
return lhs.compare(rhs) >= 0; return lhs.compare(rhs) >= 0;
} }
std::ostream& operator<<(std::ostream& stream, const StringData& value) ; std::ostream& operator<<(std::ostream& stream, const StringData& value) ;
} // namespace mongo } // namespace mongo
#include "string_data-inl.h" #include "mongo/base/string_data-inl.h"
 End of changes. 2 change blocks. 
0 lines changed or deleted 9 lines changed or added


 synchronization.h   synchronization.h 
skipping to change at line 41 skipping to change at line 41
class Notification : boost::noncopyable { class Notification : boost::noncopyable {
public: public:
Notification(); Notification();
/* /*
* Blocks until the method 'notifyOne()' is called. * Blocks until the method 'notifyOne()' is called.
*/ */
void waitToBeNotified(); void waitToBeNotified();
/* /*
* Blocks until the method 'notifyOne()' is called or the time inte
rval elapses.
* Returns true if notified, false if timeout.
*/
bool timedWaitToBeNotified( int millis );
/*
* Notifies the waiter of '*this' that it can proceed. Can only be called once. * Notifies the waiter of '*this' that it can proceed. Can only be called once.
*/ */
void notifyOne(); void notifyOne();
private: private:
mongo::mutex _mutex; // protects state below mongo::mutex _mutex; // protects state below
unsigned long long lookFor; unsigned long long lookFor;
unsigned long long cur; unsigned long long cur;
boost::condition _condition; // cond over _notified being true boost::condition _condition; // cond over _notified being true
}; };
 End of changes. 1 change blocks. 
7 lines changed or deleted 0 lines changed or added


 time_support.h   time_support.h 
skipping to change at line 23 skipping to change at line 23
* 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 <ctime> #include <ctime>
#include <string> #include <string>
#include <boost/thread/xtime.hpp> #include <boost/thread/xtime.hpp>
#include <boost/version.hpp>
#include "mongo/bson/util/misc.h" // Date_t
namespace mongo { namespace mongo {
void time_t_to_Struct(time_t t, struct tm * buf , bool local = false ); void time_t_to_Struct(time_t t, struct tm * buf , bool local = false );
std::string time_t_to_String(time_t t);
std::string time_t_to_String_short(time_t t);
/** struct Date_t {
* Gets the current time string (in fixed width) in UTC. Sample format: // TODO: make signed (and look for related TODO's)
* unsigned long long millis;
* Wed Oct 31 13:34:47.996 Date_t(): millis(0) {}
* Date_t(unsigned long long m): millis(m) {}
* @param timeStr pointer to the buffer to set the string - empirically operator unsigned long long&() { return millis; }
, 64 bytes is enough for operator const unsigned long long&() const { return millis; }
* the buffer, 26 is not. void toTm (tm *buf);
*/ std::string toString() const;
void curTimeString(char* timeStr); time_t toTimeT() const;
int64_t asInt64() const {
return static_cast<int64_t>(millis);
}
};
// uses ISO 8601 dates without trailing Z // uses ISO 8601 dates without trailing Z
// colonsOk should be false when creating filenames // colonsOk should be false when creating filenames
std::string terseCurrentTime(bool colonsOk=true); std::string terseCurrentTime(bool colonsOk=true);
/**
* Formats "time" according to the ISO 8601 extended form standard, inc
luding date,
* and time, in the UTC timezone.
*
* Sample format: "2013-07-23T18:42:14Z"
*/
std::string timeToISOString(time_t time); std::string timeToISOString(time_t time);
/**
* Formats "date" according to the ISO 8601 extended form standard, inc
luding date,
* and time with milliseconds decimal component, in the UTC timezone.
*
* Sample format: "2013-07-23T18:42:14.072Z"
*/
std::string dateToISOStringUTC(Date_t date);
/**
* Formats "date" according to the ISO 8601 extended form standard, inc
luding date,
* and time with milliseconds decimal component, in the local timezone.
*
* Sample format: "2013-07-23T18:42:14.072-05:00"
*/
std::string dateToISOStringLocal(Date_t date);
/**
* Formats "date" in fixed width in the local time zone.
*
* Sample format: "Wed Oct 31 13:34:47.996"
*/
std::string dateToCtimeString(Date_t date);
boost::gregorian::date currentDate(); boost::gregorian::date currentDate();
// parses time of day in "hh:mm" format assuming 'hh' is 00-23 // parses time of day in "hh:mm" format assuming 'hh' is 00-23
bool toPointInTime( const std::string& str , boost::posix_time::ptime* timeOfDay ); bool toPointInTime( const std::string& str , boost::posix_time::ptime* timeOfDay );
void sleepsecs(int s); void sleepsecs(int s);
void sleepmillis(long long ms); void sleepmillis(long long ms);
void sleepmicros(long long micros); void sleepmicros(long long micros);
class Backoff { class Backoff {
 End of changes. 5 change blocks. 
12 lines changed or deleted 49 lines changed or added


 tool.h   tool.h 
skipping to change at line 21 skipping to change at line 21
* 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/>.
*/ */
// Tool.h // Tool.h
#pragma once #pragma once
#include <string>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <string>
#if defined(_WIN32) #if defined(_WIN32)
#include <io.h> #include <io.h>
#endif #endif
#include "db/instance.h" #include "mongo/db/instance.h"
#include "db/matcher.h" #include "mongo/db/matcher.h"
using std::string; using std::string;
namespace mongo { namespace mongo {
class Tool { class Tool {
public: public:
enum DBAccess { enum DBAccess {
NONE = 0 , NONE = 0 ,
REMOTE_SERVER = 1 << 1 , REMOTE_SERVER = 1 << 1 ,
LOCAL_SERVER = 1 << 2 , LOCAL_SERVER = 1 << 2 ,
SPECIFY_DBCOL = 1 << 3 , SPECIFY_DBCOL = 1 << 3 ,
ALL = REMOTE_SERVER | LOCAL_SERVER | SPECIFY_DBCOL ALL = REMOTE_SERVER | LOCAL_SERVER | SPECIFY_DBCOL
}; };
Tool( string name , DBAccess access=ALL, string defaultDB="test" , Tool( string name , DBAccess access=ALL, string defaultDB="test" ,
string defaultCollection="", bool usesstdout=true, bool quiet =false); string defaultCollection="", bool usesstdout=true, bool quiet =false);
virtual ~Tool(); virtual ~Tool();
int main( int argc , char ** argv ); static auto_ptr<Tool> (*createInstance)();
int main( int argc , char ** argv, char ** envp );
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();
} }
boost::program_options::options_description_easy_init add_hidden_op tions() { boost::program_options::options_description_easy_init add_hidden_op tions() {
return _hidden_options->add_options(); return _hidden_options->add_options();
} }
void addPositionArg( const char * name , int pos ) { void addPositionArg( const char * name , int pos ) {
_positonalOptions.add( name , pos ); _positonalOptions.add( name , pos );
} }
skipping to change at line 165 skipping to change at line 166
virtual int doRun() = 0; virtual int doRun() = 0;
virtual void gotObject( const BSONObj& obj ) = 0; virtual void gotObject( const BSONObj& obj ) = 0;
virtual int run(); virtual int run();
long long processFile( const boost::filesystem::path& file ); long long processFile( const boost::filesystem::path& file );
}; };
} }
#define REGISTER_MONGO_TOOL(TYPENAME) \
auto_ptr<Tool> createInstanceOfThisTool() {return auto_ptr<Tool>(new TY
PENAME());} \
auto_ptr<Tool> (*Tool::createInstance)() = createInstanceOfThisTool;
 End of changes. 5 change blocks. 
5 lines changed or deleted 6 lines changed or added


 trace.h   trace.h 
skipping to change at line 22 skipping to change at line 22
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* 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 <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include "util/concurrency/rwlock.h" #include "mongo/util/concurrency/rwlock.h"
namespace mongo { namespace mongo {
class Trace : class Trace :
public boost::noncopyable { public boost::noncopyable {
public: public:
#ifdef LATER #ifdef LATER
/** /**
Set the traces with the given names. Set the traces with the given names.
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 type_config_version.h   type_config_version.h 
skipping to change at line 122 skipping to change at line 122
void setMinCompatibleVersion(const int minCompatibleVersion) { void setMinCompatibleVersion(const int minCompatibleVersion) {
_minCompatibleVersion = minCompatibleVersion; _minCompatibleVersion = minCompatibleVersion;
_isMinCompatibleVersionSet = true; _isMinCompatibleVersionSet = true;
} }
void unsetMinCompatibleVersion() { _isMinCompatibleVersionSet = fal se; } void unsetMinCompatibleVersion() { _isMinCompatibleVersionSet = fal se; }
bool isMinCompatibleVersionSet() const { return _isMinCompatibleVer sionSet; } bool isMinCompatibleVersionSet() const { return _isMinCompatibleVer sionSet; }
// Calling get*() methods when the member is not set results in und efined behavior // Calling get*() methods when the member is not set results in und efined behavior
const int getMinCompatibleVersion() const { int getMinCompatibleVersion() const {
dassert(_isMinCompatibleVersionSet); dassert(_isMinCompatibleVersionSet);
return _minCompatibleVersion; return _minCompatibleVersion;
} }
void setCurrentVersion(const int currentVersion) { void setCurrentVersion(const int currentVersion) {
_currentVersion = currentVersion; _currentVersion = currentVersion;
_isCurrentVersionSet = true; _isCurrentVersionSet = true;
} }
void unsetCurrentVersion() { _isCurrentVersionSet = false; } void unsetCurrentVersion() { _isCurrentVersionSet = false; }
bool isCurrentVersionSet() const { return _isCurrentVersionSet; } bool isCurrentVersionSet() const { return _isCurrentVersionSet; }
// Calling get*() methods when the member is not set results in und efined behavior // Calling get*() methods when the member is not set results in und efined behavior
const int getCurrentVersion() const { int getCurrentVersion() const {
dassert(_isCurrentVersionSet); dassert(_isCurrentVersionSet);
return _currentVersion; return _currentVersion;
} }
void setExcludingMongoVersions(const BSONArray& excludingMongoVersi ons) { void setExcludingMongoVersions(const BSONArray& excludingMongoVersi ons) {
_excludingMongoVersions = excludingMongoVersions; _excludingMongoVersions = excludingMongoVersions;
_isExcludingMongoVersionsSet = true; _isExcludingMongoVersionsSet = true;
} }
void unsetExcludingMongoVersions() { _isExcludingMongoVersionsSet = false; } void unsetExcludingMongoVersions() { _isExcludingMongoVersionsSet = false; }
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 type_locks.h   type_locks.h 
skipping to change at line 136 skipping to change at line 136
void setState(const int state) { void setState(const int state) {
_state = state; _state = state;
_isStateSet = true; _isStateSet = true;
} }
void unsetState() { _isStateSet = false; } void unsetState() { _isStateSet = false; }
bool isStateSet() const { return _isStateSet; } bool isStateSet() const { return _isStateSet; }
// Calling get*() methods when the member is not set results in und efined behavior // Calling get*() methods when the member is not set results in und efined behavior
const int getState() const { int getState() const {
dassert(_isStateSet); dassert(_isStateSet);
return _state; return _state;
} }
// Optional Fields // Optional Fields
void setProcess(StringData& process) { void setProcess(StringData& process) {
_process = process.toString(); _process = process.toString();
_isProcessSet = true; _isProcessSet = true;
} }
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 type_mongos.h   type_mongos.h 
skipping to change at line 151 skipping to change at line 151
void setUp(const int up) { void setUp(const int up) {
_up = up; _up = up;
_isUpSet = true; _isUpSet = true;
} }
void unsetUp() { _isUpSet = false; } void unsetUp() { _isUpSet = false; }
bool isUpSet() const { return _isUpSet; } bool isUpSet() const { return _isUpSet; }
// Calling get*() methods when the member is not set results in und efined behavior // Calling get*() methods when the member is not set results in und efined behavior
const int getUp() const { int getUp() const {
dassert(_isUpSet); dassert(_isUpSet);
return _up; return _up;
} }
void setWaiting(const bool waiting) { void setWaiting(const bool waiting) {
_waiting = waiting; _waiting = waiting;
_isWaitingSet = true; _isWaitingSet = true;
} }
void unsetWaiting() { _isWaitingSet = false; } void unsetWaiting() { _isWaitingSet = false; }
bool isWaitingSet() const { return _isWaitingSet; } bool isWaitingSet() const { return _isWaitingSet; }
// Calling get*() methods when the member is not set results in und efined behavior // Calling get*() methods when the member is not set results in und efined behavior
const bool getWaiting() const { bool getWaiting() const {
dassert(_isWaitingSet); dassert(_isWaitingSet);
return _waiting; return _waiting;
} }
// Optional Fields // Optional Fields
void setMongoVersion(const StringData& mongoVersion) { void setMongoVersion(const StringData& mongoVersion) {
_mongoVersion = mongoVersion.toString(); _mongoVersion = mongoVersion.toString();
_isMongoVersionSet = true; _isMongoVersionSet = true;
} }
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 undef_macros.h   undef_macros.h 
skipping to change at line 41 skipping to change at line 41
// util/assert_util.h // util/assert_util.h
#undef dassert #undef dassert
#pragma pop_macro("dassert") #pragma pop_macro("dassert")
#undef wassert #undef wassert
#pragma pop_macro("wassert") #pragma pop_macro("wassert")
#undef massert #undef massert
#pragma pop_macro("massert") #pragma pop_macro("massert")
#undef uassert #undef uassert
#pragma pop_macro("uassert") #pragma pop_macro("uassert")
#undef uassertStatusOK
#pragma pop_macro("uassertStatusOK")
#undef verify #undef verify
#pragma pop_macro("verify") #pragma pop_macro("verify")
#undef DESTRUCTOR_GUARD #undef DESTRUCTOR_GUARD
#pragma pop_macro("DESTRUCTOR_GUARD") #pragma pop_macro("DESTRUCTOR_GUARD")
// util/goodies.h // util/goodies.h
#undef PRINT #undef PRINT
#pragma pop_macro("PRINT") #pragma pop_macro("PRINT")
#undef PRINTFL #undef PRINTFL
#pragma pop_macro("PRINTFL") #pragma pop_macro("PRINTFL")
 End of changes. 1 change blocks. 
2 lines changed or deleted 0 lines changed or added


 update.h   update.h 
skipping to change at line 19 skipping to change at line 19
* *
* 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.
* *
* 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/>.
*/ */
#include "mongo/pch.h" #pragma once
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/curop.h" #include "mongo/db/curop.h"
#include "mongo/db/ops/update_request.h"
#include "mongo/db/ops/update_result.h"
#include "mongo/db/query_plan_selection_policy.h" #include "mongo/db/query_plan_selection_policy.h"
namespace mongo { namespace mongo {
// ---------- public ------------- class UpdateDriver;
struct UpdateResult { UpdateResult update(const UpdateRequest& request, OpDebug* opDebug);
const bool existing; // if existing objects were modified
const bool mod; // was this a $ mod UpdateResult update(const UpdateRequest& request, OpDebug* opDebug, Upd
const long long num; // how many objects touched ateDriver* driver);
OID upserted; // if something was upserted, the new _id of the obj
ect
UpdateResult( bool e, bool m, unsigned long long n , const BSONObj&
upsertedObject )
: existing(e) , mod(m), num(n) {
upserted.clear();
BSONElement id = upsertedObject["_id"];
if ( ! e && n == 1 && id.type() == jstOID ) {
upserted = id.OID();
}
}
};
class RemoveSaver;
/** Returns true if updates are supposed to be handle by the new update
framework */
bool isNewUpdateFrameworkEnabled();
/* returns true if an existing object was updated, false if no existing
object was found.
multi - update multiple objects - mostly useful with things like $se
t
su - allow access to system namespaces (super user)
*/
UpdateResult updateObjects(const char* ns,
const BSONObj& updateobj,
const BSONObj& pattern,
bool upsert,
bool multi,
bool logop,
OpDebug& debug,
bool fromMigrate = false,
const QueryPlanSelectionPolicy& planPolicy =
QueryPlanSelectionPolicy::any());
/*
* Similar to updateObjects but not strict about applying mods that can
fail during initial
* replication.
*
* Reference ticket: SERVER-4781
*/
UpdateResult updateObjectsForReplication(const char* ns,
const BSONObj& updateobj,
const BSONObj& pattern,
bool upsert,
bool multi,
bool logop,
OpDebug& debug,
bool fromMigrate = false,
const QueryPlanSelectionPolicy
& planPolicy =
QueryPlanSelectionPolicy::
any());
UpdateResult _updateObjects(bool su,
const char* ns,
const BSONObj& updateobj,
const BSONObj& pattern,
bool upsert,
bool multi,
bool logop,
OpDebug& debug,
RemoveSaver* rs = 0,
bool fromMigrate = false,
const QueryPlanSelectionPolicy& planPolicy
= QueryPlanSelectionPolicy::any(),
bool forReplication = false);
UpdateResult _updateObjectsNEW(bool su,
const char* ns,
const BSONObj& updateobj,
const BSONObj& pattern,
bool upsert,
bool multi,
bool logop,
OpDebug& debug,
RemoveSaver* rs = 0,
bool fromMigrate = false,
const QueryPlanSelectionPolicy& planPoli
cy
= QueryPlanSelectionPolicy::any(),
bool forReplication = false);
/** /**
* takes the from document and returns a new document * takes the from document and returns a new document
* after apply all the operators * after apply all the operators
* e.g. * e.g.
* applyUpdateOperators( BSON( "x" << 1 ) , BSON( "$inc" << BSON( "x" << 1 ) ) ); * applyUpdateOperators( BSON( "x" << 1 ) , BSON( "$inc" << BSON( "x" << 1 ) ) );
* returns: { x : 2 } * returns: { x : 2 }
*/ */
BSONObj applyUpdateOperators( const BSONObj& from, const BSONObj& opera tors ); BSONObj applyUpdateOperators( const BSONObj& from, const BSONObj& opera tors );
} // namespace mongo } // namespace mongo
 End of changes. 5 change blocks. 
92 lines changed or deleted 8 lines changed or added


 update_driver.h   update_driver.h 
skipping to change at line 23 skipping to change at line 23
* 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 <string> #include <string>
#include <vector> #include <vector>
#include "mongo/base/status.h" #include "mongo/base/status.h"
#include "mongo/bson/mutable/document.h"
#include "mongo/db/index_set.h" #include "mongo/db/index_set.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/ops/modifier_interface.h" #include "mongo/db/ops/modifier_interface.h"
namespace mongo { namespace mongo {
class UpdateDriver { class UpdateDriver {
public: public:
struct Options; struct Options;
UpdateDriver(const Options& opts); UpdateDriver(const Options& opts);
~UpdateDriver(); ~UpdateDriver();
/** /**
* Returns OK and fills in '_mods' if 'updateExpr' is correct. In t * Returns OK and fills in '_mods' if 'updateExpr' is correct. Othe
hat case, take note rwise returns an
* that the collection that 'updateExpr' is built against have indi * error status with a corresponding description.
ces that encompass
* all fields present in 'indexedFields'. Otherwise returns an erro
r status with a
* corresponding description.
*/ */
Status parse(const IndexPathSet& indexedFields, const BSONObj& upda teExpr); Status parse(const BSONObj& updateExpr);
/** /**
* Returns true and derives a BSONObj, 'newObj', from 'query'. * Fills in document with any fields in the query which are valid.
* *
* TODO: Elaborate on the logic used here. * Valid fields include equality matches like "a":1, or "a.b":false
*
* Each valid field will be expanded (from dot notation) and confli
cts will be
* checked for all fields added to the underlying document.
*
* Returns Status::OK() if the document can be used. If there are a
ny error or
* conflicts along the way then those errors will be returned.
*/
static Status createFromQuery(const BSONObj& query, mutablebson::Do
cument& doc);
/**
* return a BSONObj with the _id field of the doc passed in, or the
doc itself.
* If no _id and multi, error.
*/ */
bool createFromQuery(const BSONObj query, BSONObj* newObj) const; BSONObj makeOplogEntryQuery(const BSONObj doc, bool multi) const;
/** /**
* Returns OK and executes '_mods' over 'doc', generating 'newObj'. If any mod is * Returns OK and executes '_mods' over 'doc', generating 'newObj'. If any mod is
* positional, use 'matchedField' (index of the array item matched) . If doc allows * positional, use 'matchedField' (index of the array item matched) . If doc allows
* mods to be applied in place and no index updating is involved, t hen the mods may * mods to be applied in place and no index updating is involved, t hen the mods may
* be applied "in place" over 'doc'. * be applied "in place" over 'doc'.
* *
* If the driver's '_logOp' mode is turned on, and if 'logOpRec' is not NULL, fills in * If the driver's '_logOp' mode is turned on, and if 'logOpRec' is not NULL, fills in
* the latter with the oplog entry corresponding to the update. If '_mods' can't be * the latter with the oplog entry corresponding to the update. If '_mods' can't be
* applied, returns an error status with a corresponding descriptio n. * applied, returns an error status with a corresponding descriptio n.
skipping to change at line 72 skipping to change at line 83
Status update(const StringData& matchedField, Status update(const StringData& matchedField,
mutablebson::Document* doc, mutablebson::Document* doc,
BSONObj* logOpRec); BSONObj* logOpRec);
// //
// Accessors // Accessors
// //
size_t numMods() const; size_t numMods() const;
bool dollarModMode() const; bool isDocReplacement() const;
bool modsAffectIndices() const; bool modsAffectIndices() const;
void refreshIndexKeys(const IndexPathSet& indexedFields);
bool multi() const; bool multi() const;
void setMulti(bool multi); void setMulti(bool multi);
bool upsert() const; bool upsert() const;
void setUpsert(bool upsert); void setUpsert(bool upsert);
bool logOp() const; bool logOp() const;
void setLogOp(bool logOp); void setLogOp(bool logOp);
ModifierInterface::Options modOptions() const;
void setModOptions(ModifierInterface::Options modOpts);
ModifierInterface::ExecInfo::UpdateContext context() const; ModifierInterface::ExecInfo::UpdateContext context() const;
void setContext(ModifierInterface::ExecInfo::UpdateContext context) ; void setContext(ModifierInterface::ExecInfo::UpdateContext context) ;
private: private:
/** Resets the state of the class associated with mods (not the err or state) */ /** Resets the state of the class associated with mods (not the err or state) */
void clear(); void clear();
// //
// immutable properties after parsing // immutable properties after parsing
// //
// Is there a list of $mod's on '_mods' or is it just full object r // Is there a list of $mod's on '_mods' or is it just full object r
eplacment? eplacement?
bool _dollarModMode; bool _replacementMode;
// Collection of update mod instances. Owned here. // Collection of update mod instances. Owned here.
vector<ModifierInterface*> _mods; vector<ModifierInterface*> _mods;
// What are the list of fields in the collection over which the upd ate is going to be // What are the list of fields in the collection over which the upd ate is going to be
// applied that participate in indices? // applied that participate in indices?
//
// TODO: Do we actually need to keep a copy of this?
IndexPathSet _indexedFields; IndexPathSet _indexedFields;
// //
// mutable properties after parsing // mutable properties after parsing
// //
// May this driver apply updates to several documents? // May this driver apply updates to several documents?
bool _multi; bool _multi;
// May this driver construct a new object if an update for a non-ex isting one is sent? // May this driver construct a new object if an update for a non-ex isting one is sent?
bool _upsert; bool _upsert;
// Should this driver generate an oplog record when it applies the update? // Should this driver generate an oplog record when it applies the update?
bool _logOp; bool _logOp;
// The options to initiate the mods with
ModifierInterface::Options _modOptions;
// Are any of the fields mentioned in the mods participating in any index? Is set anew // Are any of the fields mentioned in the mods participating in any index? Is set anew
// at each call to update. // at each call to update.
bool _affectIndices; bool _affectIndices;
// Is this update going to be an upsert? // Is this update going to be an upsert?
ModifierInterface::ExecInfo::UpdateContext _context; ModifierInterface::ExecInfo::UpdateContext _context;
mutablebson::Document _logDoc;
}; };
struct UpdateDriver::Options { struct UpdateDriver::Options {
bool multi; bool multi;
bool upsert; bool upsert;
bool logOp; bool logOp;
ModifierInterface::Options modOptions;
Options() : multi(false), upsert(false), logOp(false) {} Options() : multi(false), upsert(false), logOp(false), modOptions() {}
}; };
} // namespace mongo } // namespace mongo
 End of changes. 15 change blocks. 
16 lines changed or deleted 41 lines changed or added


 user.h   user.h 
skipping to change at line 66 skipping to change at line 66
* Returns the user name for this user. * Returns the user name for this user.
*/ */
const UserName& getName() const; const UserName& getName() const;
/** /**
* Returns an iterator that can be used to get the list of roles th is user belongs to. * Returns an iterator that can be used to get the list of roles th is user belongs to.
*/ */
const RoleNameIterator getRoles() const; const RoleNameIterator getRoles() const;
/** /**
* Returns the CredentialData for this user.
*/
const CredentialData& getCredentials() const;
/**
* Gets the set of actions this user is allowed to perform on the g iven resource. * Gets the set of actions this user is allowed to perform on the g iven resource.
*/ */
const ActionSet getActionsForResource(const std::string& resource) const; const ActionSet getActionsForResource(const std::string& resource) const;
/** /**
* Returns true if this copy of information about this user is stil l valid. If this returns * Returns true if this copy of information about this user is stil l valid. If this returns
* false, this object should no longer be used and should be return ed to the * false, this object should no longer be used and should be return ed to the
* AuthorizationManager and a new User object for this user should be requested. * AuthorizationManager and a new User object for this user should be requested.
*/ */
bool isValid() const; bool isValid() const;
 End of changes. 1 change blocks. 
0 lines changed or deleted 5 lines changed or added


 value.h   value.h 
skipping to change at line 20 skipping to change at line 20
* 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 License * You should have received a copy of the GNU Affero General Public License
* 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/pipeline/value_internal.h" #include "mongo/db/pipeline/value_internal.h"
#include "mongo/platform/unordered_set.h"
namespace mongo { namespace mongo {
class BSONElement; class BSONElement;
class Builder;
/** A variant type that can hold any type of data representable in BSON /** A variant type that can hold any type of data representable in BSON
* *
* Small values are stored inline, but some values, such as large stri ngs, * Small values are stored inline, but some values, such as large stri ngs,
* are heap allocated. It has smart pointer capabilities built-in so i t is * are heap allocated. It has smart pointer capabilities built-in so i t is
* safe and recommended to pass these around and return them by value. * safe and recommended to pass these around and return them by value.
* *
* Values are immutable, but can be assigned. This means that once you have * Values are immutable, but can be assigned. This means that once you have
* a Value, you can be assured that none of the data in that Value wil l * a Value, you can be assured that none of the data in that Value wil l
* change. However if you have a non-const Value you replace it with * change. However if you have a non-const Value you replace it with
skipping to change at line 83 skipping to change at line 83
explicit Value(const BSONSymbol& sym) : _storage(Symbol, sym.sy mbol) {} explicit Value(const BSONSymbol& sym) : _storage(Symbol, sym.sy mbol) {}
explicit Value(const BSONCode& code) : _storage(Code, code.cod e) {} explicit Value(const BSONCode& code) : _storage(Code, code.cod e) {}
explicit Value(const NullLabeler&) : _storage(jstNULL) {} // BSONNull explicit Value(const NullLabeler&) : _storage(jstNULL) {} // BSONNull
explicit Value(const UndefinedLabeler&) : _storage(Undefined) {} // BSONUndefined explicit Value(const UndefinedLabeler&) : _storage(Undefined) {} // BSONUndefined
explicit Value(const MinKeyLabeler&) : _storage(MinKey) {} // MINKEY explicit Value(const MinKeyLabeler&) : _storage(MinKey) {} // MINKEY
explicit Value(const MaxKeyLabeler&) : _storage(MaxKey) {} // MAXKEY explicit Value(const MaxKeyLabeler&) : _storage(MaxKey) {} // MAXKEY
explicit Value(const Date_t& date) explicit Value(const Date_t& date)
: _storage(Date, static_cast<long long>(date.millis)) // millis really signed : _storage(Date, static_cast<long long>(date.millis)) // millis really signed
{} {}
/** Creates an empty or zero value of specified type.
* This is currently the only way to create Undefined or Null Valu
es.
*/
explicit Value(BSONType type);
// TODO: add an unsafe version that can share storage with the BSON Element // TODO: add an unsafe version that can share storage with the BSON Element
/// Deep-convert from BSONElement to Value /// Deep-convert from BSONElement to Value
explicit Value(const BSONElement& elem); explicit Value(const BSONElement& elem);
/** Construct a long or integer-valued Value. /** Construct a long or integer-valued Value.
* *
* Used when preforming arithmetic operations with int where the * Used when preforming arithmetic operations with int where the
* result may be too large and need to be stored as long. The Valu e * result may be too large and need to be stored as long. The Valu e
* will be an int if value fits, otherwise it will be a long. * will be an int if value fits, otherwise it will be a long.
*/ */
skipping to change at line 203 skipping to change at line 198
friend friend
bool operator==(const Value& v1, const Value& v2) { bool operator==(const Value& v1, const Value& v2) {
if (v1._storage.identical(v2._storage)) { if (v1._storage.identical(v2._storage)) {
// Simple case // Simple case
return true; return true;
} }
return (Value::compare(v1, v2) == 0); return (Value::compare(v1, v2) == 0);
} }
friend bool operator!=(const Value& v1, const Value& v2) {
return !(v1 == v2);
}
friend bool operator<(const Value& lhs, const Value& rhs) {
return (Value::compare(lhs, rhs) < 0);
}
/// This is for debugging, logging, etc. See getString() for how to extract a string. /// This is for debugging, logging, etc. See getString() for how to extract a string.
string toString() const; string toString() const;
friend ostream& operator << (ostream& out, const Value& v); friend ostream& operator << (ostream& out, const Value& v);
void swap(Value& rhs) { void swap(Value& rhs) {
_storage.swap(rhs._storage); _storage.swap(rhs._storage);
} }
/** Figure out what the widest of two numeric types is. /** Figure out what the widest of two numeric types is.
* *
skipping to change at line 261 skipping to change at line 264
explicit Value(const ValueStorage& storage) :_storage(storage) {} explicit Value(const ValueStorage& storage) :_storage(storage) {}
// does no type checking // does no type checking
StringData getStringData() const; // May contain embedded NUL bytes StringData getStringData() const; // May contain embedded NUL bytes
ValueStorage _storage; ValueStorage _storage;
friend class MutableValue; // gets and sets _storage.genericRCPtr friend class MutableValue; // gets and sets _storage.genericRCPtr
}; };
BOOST_STATIC_ASSERT(sizeof(Value) == 16); BOOST_STATIC_ASSERT(sizeof(Value) == 16);
typedef unordered_set<Value, Value::Hash> ValueSet;
} }
namespace std { namespace std {
// This is used by std::sort and others // This is used by std::sort and others
template <> template <>
inline void swap(mongo::Value& lhs, mongo::Value& rhs) { lhs.swap(rhs); } inline void swap(mongo::Value& lhs, mongo::Value& rhs) { lhs.swap(rhs); }
} }
/* ======================= INLINED IMPLEMENTATIONS ======================== == */ /* ======================= INLINED IMPLEMENTATIONS ======================== == */
 End of changes. 5 change blocks. 
7 lines changed or deleted 11 lines changed or added


 value_internal.h   value_internal.h 
skipping to change at line 25 skipping to change at line 25
*/ */
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include "bson/bsonobj.h" #include "bson/bsonobj.h"
#include "bson/bsontypes.h" #include "bson/bsontypes.h"
#include "bson/bsonmisc.h" #include "bson/bsonmisc.h"
#include "bson/oid.h" #include "bson/oid.h"
#include "util/intrusive_counter.h" #include "util/intrusive_counter.h"
#include "mongo/db/repl/optime.h" #include "mongo/bson/optime.h"
namespace mongo { namespace mongo {
class Document; class Document;
class DocumentStorage; class DocumentStorage;
class Value; class Value;
//TODO: a MutableVector, similar to MutableDocument //TODO: a MutableVector, similar to MutableDocument
/// A heap-allocated reference-counted std::vector /// A heap-allocated reference-counted std::vector
class RCVector : public RefCountable { class RCVector : public RefCountable {
public: public:
skipping to change at line 91 skipping to change at line 91
memcpy(&oid, &o, sizeof(OID)); memcpy(&oid, &o, sizeof(OID));
BOOST_STATIC_ASSERT(sizeof(OID) == sizeof(oid)); BOOST_STATIC_ASSERT(sizeof(OID) == sizeof(oid));
} }
ValueStorage(const ValueStorage& rhs) { ValueStorage(const ValueStorage& rhs) {
memcpy(this, &rhs, sizeof(*this)); memcpy(this, &rhs, sizeof(*this));
memcpyed(); memcpyed();
} }
~ValueStorage() { ~ValueStorage() {
DEV verifyRefCountingIfShould();
if (refCounter) if (refCounter)
intrusive_ptr_release(genericRCPtr); intrusive_ptr_release(genericRCPtr);
DEV memset(this, 0xee, sizeof(*this)); DEV memset(this, 0xee, sizeof(*this));
} }
ValueStorage& operator= (ValueStorage rhsCopy) { ValueStorage& operator= (ValueStorage rhsCopy) {
this->swap(rhsCopy); this->swap(rhsCopy);
return *this; return *this;
} }
void swap(ValueStorage& rhs) { void swap(ValueStorage& rhs) {
// Don't need to update ref-counts because they will be the sam e in the end // Don't need to update ref-counts because they will be the sam e in the end
char temp[sizeof(ValueStorage)]; char temp[sizeof(ValueStorage)];
memcpy(temp, this, sizeof(*this)); memcpy(temp, this, sizeof(*this));
memcpy(this, &rhs, sizeof(*this)); memcpy(this, &rhs, sizeof(*this));
memcpy(&rhs, temp, sizeof(*this)); memcpy(&rhs, temp, sizeof(*this));
} }
/// Call this after memcpying to update ref counts if needed /// Call this after memcpying to update ref counts if needed
void memcpyed() const { void memcpyed() const {
DEV verifyRefCountingIfShould();
if (refCounter) if (refCounter)
intrusive_ptr_add_ref(genericRCPtr); intrusive_ptr_add_ref(genericRCPtr);
} }
/// These are only to be called during Value construction on an emp ty Value /// These are only to be called during Value construction on an emp ty Value
void putString(const StringData& s); void putString(const StringData& s);
void putVector(const RCVector* v); void putVector(const RCVector* v);
void putDocument(const Document& d); void putDocument(const Document& d);
void putRegEx(const BSONRegEx& re); void putRegEx(const BSONRegEx& re);
void putBinData(const BSONBinData& bd) { void putBinData(const BSONBinData& bd) {
skipping to change at line 142 skipping to change at line 144
putRefCountable(new RCCodeWScope(cws.code.toString(), cws.scope )); putRefCountable(new RCCodeWScope(cws.code.toString(), cws.scope ));
} }
void putRefCountable(intrusive_ptr<const RefCountable> ptr) { void putRefCountable(intrusive_ptr<const RefCountable> ptr) {
genericRCPtr = ptr.get(); genericRCPtr = ptr.get();
if (genericRCPtr) { if (genericRCPtr) {
intrusive_ptr_add_ref(genericRCPtr); intrusive_ptr_add_ref(genericRCPtr);
refCounter = true; refCounter = true;
} }
DEV verifyRefCountingIfShould();
} }
StringData getString() const { StringData getString() const {
if (shortStr) { if (shortStr) {
return StringData(shortStrStorage, shortStrSize); return StringData(shortStrStorage, shortStrSize);
} }
else { else {
dassert(typeid(*genericRCPtr) == typeid(const RCString)); dassert(typeid(*genericRCPtr) == typeid(const RCString));
const RCString* stringPtr = static_cast<const RCString*>(ge nericRCPtr); const RCString* stringPtr = static_cast<const RCString*>(ge nericRCPtr);
return StringData(stringPtr->c_str(), stringPtr->size()); return StringData(stringPtr->c_str(), stringPtr->size());
skipping to change at line 193 skipping to change at line 196
void zero() { void zero() {
memset(this, 0, sizeof(*this)); memset(this, 0, sizeof(*this));
} }
// Byte-for-byte identical // Byte-for-byte identical
bool identical(const ValueStorage& other) const { bool identical(const ValueStorage& other) const {
return (i64[0] == other.i64[0] return (i64[0] == other.i64[0]
&& i64[1] == other.i64[1]); && i64[1] == other.i64[1]);
} }
void verifyRefCountingIfShould() const;
// This data is public because this should only be used by Value wh ich would be a friend // This data is public because this should only be used by Value wh ich would be a friend
union { union {
struct { struct {
// byte 1 // byte 1
signed char type; signed char type;
// byte 2 // byte 2
struct { struct {
bool refCounter : 1; // true if we need to refCount bool refCounter : 1; // true if we need to refCount
bool shortStr : 1; // true if we are using short string s bool shortStr : 1; // true if we are using short string s
 End of changes. 5 change blocks. 
1 lines changed or deleted 6 lines changed or added


 version.h   version.h 
skipping to change at line 49 skipping to change at line 49
void appendBuildInfo(BSONObjBuilder& result); void appendBuildInfo(BSONObjBuilder& result);
const char * gitVersion(); const char * gitVersion();
const char * compiledJSEngine(); const char * compiledJSEngine();
const char * allocator(); const char * allocator();
const char * loaderFlags(); const char * loaderFlags();
const char * compilerFlags(); const char * compilerFlags();
void printGitVersion(); void printGitVersion();
const std::string openSSLVersion(const std::string &prefix = "", const
std::string &suffix = "");
void printOpenSSLVersion();
std::string sysInfo(); std::string sysInfo();
void printSysInfo(); void printSysInfo();
void printAllocator(); void printAllocator();
void show_warnings(); void show_warnings();
} // namespace mongo } // namespace mongo
#endif // UTIL_VERSION_HEADER #endif // UTIL_VERSION_HEADER
 End of changes. 1 change blocks. 
0 lines changed or deleted 4 lines changed or added


 winutil.h   winutil.h 
skipping to change at line 19 skipping to change at line 19
// * // *
// * 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.
// * // *
// * You should have received a copy of the GNU Affero General Public Li cense // * You should have received a copy of the GNU Affero General Public Li cense
// * 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 "pch.h" // #include "mongo/pch.h"
#pragma once #pragma once
#if defined(_WIN32) #if defined(_WIN32)
#include <windows.h> #include <windows.h>
#include "text.h" #include "text.h"
namespace mongo { namespace mongo {
inline string GetWinErrMsg(DWORD err) { inline string GetWinErrMsg(DWORD err) {
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 working_set.h   working_set.h 
skipping to change at line 120 skipping to change at line 120
struct WorkingSetMember { struct WorkingSetMember {
WorkingSetMember(); WorkingSetMember();
enum MemberState { enum MemberState {
// Initial state. // Initial state.
INVALID, INVALID,
// Data is from 1 or more indices. // Data is from 1 or more indices.
LOC_AND_IDX, LOC_AND_IDX,
// Data is from a collection scan. // Data is from a collection scan, or data is from an index sca n and was fetched.
LOC_AND_UNOWNED_OBJ, LOC_AND_UNOWNED_OBJ,
// Data is from a fetch.
LOC_AND_OWNED_OBJ,
// DiskLoc has been invalidated, or the obj doesn't correspond to an on-disk document // DiskLoc has been invalidated, or the obj doesn't correspond to an on-disk document
// anymore (e.g. is a computed expression). // anymore (e.g. is a computed expression).
OWNED_OBJ, OWNED_OBJ,
}; };
DiskLoc loc; DiskLoc loc;
BSONObj obj; BSONObj obj;
vector<IndexKeyDatum> keyData; vector<IndexKeyDatum> keyData;
MemberState state; MemberState state;
skipping to change at line 150 skipping to change at line 147
/** /**
* getFieldDotted uses its state (obj or index data) to produce the field with the provided * getFieldDotted uses its state (obj or index data) to produce the field with the provided
* name. * name.
* *
* Returns true if there is the element is in an index key or in an (owned or unowned) * Returns true if there is the element is in an index key or in an (owned or unowned)
* object. *out is set to the element if so. * object. *out is set to the element if so.
* *
* Returns false otherwise. Returning false indicates a query plan ning error. * Returns false otherwise. Returning false indicates a query plan ning error.
*/ */
bool getFieldDotted(const string& field, BSONElement* out); bool getFieldDotted(const string& field, BSONElement* out) const;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 3 change blocks. 
5 lines changed or deleted 2 lines changed or added


 working_set_common.h   working_set_common.h 
skipping to change at line 26 skipping to change at line 26
#pragma once #pragma once
namespace mongo { namespace mongo {
struct WorkingSetMember; struct WorkingSetMember;
class WorkingSetCommon { class WorkingSetCommon {
public: public:
/** /**
* Fetch an unowned copy of the BSONObj that the provided WSM refer
s to. Updates
* member->obj to refer to that unowned BSONObj. Requires a valid
DiskLoc. Does nothing if
* WSM has a valid obj already.
*
* Returns true if the fetch succeeded, false otherwise.
*
* Used in SORT and FETCH.
*/
static bool fetch(WorkingSetMember* member);
/**
* Get an owned copy of the BSONObj the WSM refers to. * Get an owned copy of the BSONObj the WSM refers to.
* Requires either a valid BSONObj or valid DiskLoc. * Requires either a valid BSONObj or valid DiskLoc.
* Returns true if the fetch and invalidate succeeded, false otherw ise. * Returns true if the fetch and invalidate succeeded, false otherw ise.
*/ */
static bool fetchAndInvalidateLoc(WorkingSetMember* member); static bool fetchAndInvalidateLoc(WorkingSetMember* member);
}; };
} // namespace mongo } // namespace mongo
 End of changes. 1 change blocks. 
13 lines changed or deleted 0 lines changed or added


 writeback_listener.h   writeback_listener.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 "mongo/client/connpool.h"
#include "mongo/db/client.h"
#include "mongo/platform/unordered_map.h" #include "mongo/platform/unordered_map.h"
#include "mongo/platform/unordered_set.h" #include "mongo/platform/unordered_set.h"
#include "../client/connpool.h" #include "mongo/util/background.h"
#include "../util/background.h"
#include "../db/client.h"
namespace mongo { namespace mongo {
/* /*
* The writeback listener takes back write attempts that were made agai nst a wrong shard. * The writeback listener takes back write attempts that were made agai nst a wrong shard.
* (Wrong here in the sense that the target chunk moved before this mon gos had a chance to * (Wrong here in the sense that the target chunk moved before this mon gos had a chance to
* learn so.) It is responsible for reapplying these writes to the corr ect shard. * learn so.) It is responsible for reapplying these writes to the corr ect shard.
* *
* Runs (instantiated) on mongos. * Runs (instantiated) on mongos.
* Currently, there is one writebacklistener per shard. * Currently, there is one writebacklistener per shard.
 End of changes. 2 change blocks. 
3 lines changed or deleted 3 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/