2d.h   2d.h 
skipping to change at line 18 skipping to change at line 18
* 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/>.
*/ */
namespace mongo { namespace mongo {
bool run2DGeoNear(const IndexDetails &id, BSONObj& cmdObj, string& errm // We need cmdObj and parsedArgs so we can print a useful error msg
sg, // and pull other args out.
bool run2DGeoNear(const IndexDetails &id, const BSONObj& cmdObj,
const GeoNearArguments &parsedArgs, string& errmsg,
BSONObjBuilder& result); BSONObjBuilder& result);
} // namespace mongo } // namespace mongo
 End of changes. 1 change blocks. 
2 lines changed or deleted 4 lines changed or added


 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 applyOps;
static const ActionType captrunc; static const ActionType captrunc;
static const ActionType clean; static const ActionType clean;
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;
static const ActionType copyDBTarget;
static const ActionType cpuProfiler; static const ActionType cpuProfiler;
static const ActionType createCollection; static const ActionType createCollection;
static const ActionType cursorInfo; static const ActionType cursorInfo;
static const ActionType dbHash; static const ActionType dbHash;
static const ActionType dbStats; static const ActionType dbStats;
static const ActionType diagLogging; static const ActionType diagLogging;
static const ActionType dropCollection; static const ActionType dropCollection;
static const ActionType dropDatabase; static const ActionType dropDatabase;
static const ActionType dropIndexes; static const ActionType dropIndexes;
static const ActionType emptycapped; static const ActionType emptycapped;
skipping to change at line 86 skipping to change at line 86
static const ActionType find; static const ActionType find;
static const ActionType flushRouterConfig; static const ActionType flushRouterConfig;
static const ActionType fsync; static const ActionType fsync;
static const ActionType getCmdLineOpts; static const ActionType getCmdLineOpts;
static const ActionType getLog; static const ActionType getLog;
static const ActionType getParameter; static const ActionType getParameter;
static const ActionType getShardMap; static const ActionType getShardMap;
static const ActionType getShardVersion; static const ActionType getShardVersion;
static const ActionType handshake; static const ActionType handshake;
static const ActionType hostInfo; static const ActionType hostInfo;
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 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 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;
skipping to change at line 144 skipping to change at line 146
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,
applyOpsValue,
captruncValue, captruncValue,
cleanValue, cleanValue,
cloneValue, cloneValue,
cloneCollectionLocalSourceValue, cloneCollectionLocalSourceValue,
cloneCollectionTargetValue, cloneCollectionTargetValue,
closeAllDatabasesValue, closeAllDatabasesValue,
collModValue, collModValue,
collStatsValue, collStatsValue,
compactValue, compactValue,
connPoolStatsValue, connPoolStatsValue,
connPoolSyncValue, connPoolSyncValue,
convertToCappedValue, convertToCappedValue,
copyDBTargetValue,
cpuProfilerValue, cpuProfilerValue,
createCollectionValue, createCollectionValue,
cursorInfoValue, cursorInfoValue,
dbHashValue, dbHashValue,
dbStatsValue, dbStatsValue,
diagLoggingValue, diagLoggingValue,
dropCollectionValue, dropCollectionValue,
dropDatabaseValue, dropDatabaseValue,
dropIndexesValue, dropIndexesValue,
emptycappedValue, emptycappedValue,
skipping to change at line 179 skipping to change at line 181
findValue, findValue,
flushRouterConfigValue, flushRouterConfigValue,
fsyncValue, fsyncValue,
getCmdLineOptsValue, getCmdLineOptsValue,
getLogValue, getLogValue,
getParameterValue, getParameterValue,
getShardMapValue, getShardMapValue,
getShardVersionValue, getShardVersionValue,
handshakeValue, handshakeValue,
hostInfoValue, hostInfoValue,
indexReadValue,
indexStatsValue, indexStatsValue,
inprogValue, inprogValue,
insertValue, insertValue,
killCursorsValue,
killopValue, killopValue,
listDatabasesValue, listDatabasesValue,
listShardsValue, listShardsValue,
logRotateValue, logRotateValue,
mapReduceShardedFinishValue, mapReduceShardedFinishValue,
moveChunkValue, moveChunkValue,
movePrimaryValue, movePrimaryValue,
netstatValue, netstatValue,
profileEnableValue, profileEnableValue,
profileReadValue, profileReadValue,
 End of changes. 8 change blocks. 
2 lines changed or deleted 6 lines changed or added


 atomic_intrinsics_win32.h   atomic_intrinsics_win32.h 
skipping to change at line 26 skipping to change at line 26
/** /**
* Implementation of the AtomicIntrinsics<T>::* operations for Windows syst ems. * Implementation of the AtomicIntrinsics<T>::* operations for Windows syst ems.
*/ */
#pragma once #pragma once
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include "mongo/platform/windows_basic.h" #include "mongo/platform/windows_basic.h"
#include <intrin.h>
#pragma intrinsic(_InterlockedCompareExchange64)
namespace mongo { namespace mongo {
/** /**
* Default instantiation of AtomicIntrinsics<>, for unsupported types. * Default instantiation of AtomicIntrinsics<>, for unsupported types.
*/ */
template <typename T, typename _IsTSupported=void> template <typename T, typename _IsTSupported=void>
class AtomicIntrinsics { class AtomicIntrinsics {
private: private:
AtomicIntrinsics(); AtomicIntrinsics();
~AtomicIntrinsics(); ~AtomicIntrinsics();
skipping to change at line 87 skipping to change at line 90
AtomicIntrinsics(); AtomicIntrinsics();
~AtomicIntrinsics(); ~AtomicIntrinsics();
}; };
/** /**
* Instantiation of AtomicIntrinsics<> for 64-bit word sizes. * Instantiation of AtomicIntrinsics<> for 64-bit word sizes.
*/ */
template <typename T> template <typename T>
class AtomicIntrinsics<T, typename boost::enable_if_c<sizeof(T) == size of(LONGLONG)>::type> { class AtomicIntrinsics<T, typename boost::enable_if_c<sizeof(T) == size of(LONGLONG)>::type> {
public: public:
static const bool kHaveInterlocked64 = (_WIN32_WINNT >= _WIN32_WINN T_VISTA);
static T compareAndSwap(volatile T* dest, T expected, T newValue) { static T compareAndSwap(volatile T* dest, T expected, T newValue) {
return InterlockedCompareExchange64(reinterpret_cast<volatile L return InterlockedImpl<kHaveInterlocked64>::compareAndSwap(dest
ONGLONG*>(dest), , expected, newValue);
LONGLONG(newValue),
LONGLONG(expected));
} }
static T swap(volatile T* dest, T newValue) { static T swap(volatile T* dest, T newValue) {
return InterlockedExchange64(reinterpret_cast<volatile LONGLONG return InterlockedImpl<kHaveInterlocked64>::swap(dest, newValue
*>(dest), );
LONGLONG(newValue));
} }
static T load(volatile const T* value) { static T load(volatile const T* value) {
return LoadStoreImpl<T>::load(value); return LoadStoreImpl<T>::load(value);
} }
static void store(volatile T* dest, T newValue) { static void store(volatile T* dest, T newValue) {
LoadStoreImpl<T>::store(dest, newValue); LoadStoreImpl<T>::store(dest, newValue);
} }
static T fetchAndAdd(volatile T* dest, T increment) { static T fetchAndAdd(volatile T* dest, T increment) {
return InterlockedExchangeAdd64(reinterpret_cast<volatile LONGL return InterlockedImpl<kHaveInterlocked64>::fetchAndAdd(dest, i
ONG*>(dest), ncrement);
LONGLONG(increment));
} }
private: private:
AtomicIntrinsics(); AtomicIntrinsics();
~AtomicIntrinsics(); ~AtomicIntrinsics();
template <bool>
struct InterlockedImpl;
// Implementation of 64-bit Interlocked operations via Windows API
calls.
template<>
struct InterlockedImpl<true> {
static T compareAndSwap(volatile T* dest, T expected, T newValu
e) {
return InterlockedCompareExchange64(
reinterpret_cast<volatile LONGLONG*>(dest),
LONGLONG(newValue),
LONGLONG(expected));
}
static T swap(volatile T* dest, T newValue) {
return InterlockedExchange64(
reinterpret_cast<volatile LONGLONG*>(dest),
LONGLONG(newValue));
}
static T fetchAndAdd(volatile T* dest, T increment) {
return InterlockedExchangeAdd64(
reinterpret_cast<volatile LONGLONG*>(dest),
LONGLONG(increment));
}
};
// Implementation of 64-bit Interlocked operations for systems wher
e the API does not
// yet provide the Interlocked...64 operations.
template<>
struct InterlockedImpl<false> {
static T compareAndSwap(volatile T* dest, T expected, T newValu
e) {
// NOTE: We must use the compiler intrinsic here: WinXP doe
s not offer
// InterlockedCompareExchange64 as an API call.
return _InterlockedCompareExchange64(
reinterpret_cast<volatile LONGLONG*>(dest),
LONGLONG(newValue),
LONGLONG(expected));
}
static T swap(volatile T* dest, T newValue) {
// NOTE: You may be tempted to replace this with
// 'InterlockedExchange64'. Resist! It will compile just fi
ne despite not being
// listed in the docs as available on XP, but the compiler
may replace it with
// calls to the non-intrinsic 'InterlockedCompareExchange64
', which does not
// exist on XP. We work around this by rolling our own synt
hetic in terms of
// compareAndSwap which we have explicitly formulated in te
rms of the compiler
// provided _InterlockedCompareExchange64 intrinsic.
T currentValue = *dest;
while (true) {
const T result = compareAndSwap(dest, currentValue, new
Value);
if (result == currentValue)
return result;
currentValue = result;
}
}
static T fetchAndAdd(volatile T* dest, T increment) {
// NOTE: See note for 'swap' on why we roll this ourselves.
T currentValue = *dest;
while (true) {
const T incremented = currentValue + increment;
const T result = compareAndSwap(dest, currentValue, inc
remented);
if (result == currentValue)
return result;
currentValue = result;
}
}
};
// On 32-bit IA-32 systems, 64-bit load and store must be implement ed in terms of // On 32-bit IA-32 systems, 64-bit load and store must be implement ed in terms of
// Interlocked operations, but on 64-bit systems they support a sim pler, native // Interlocked operations, but on 64-bit systems they support a sim pler, native
// implementation. The LoadStoreImpl type represents the abstract implementation of // implementation. The LoadStoreImpl type represents the abstract implementation of
// loading and storing 64-bit values. // loading and storing 64-bit values.
template <typename T, typename _IsTTooBig=void> template <typename U, typename _IsTTooBig=void>
class LoadStoreImpl{}; class LoadStoreImpl{};
// Implementation on 64-bit systems. // Implementation on 64-bit systems.
template <typename U> template <typename U>
class LoadStoreImpl<U, typename boost::enable_if_c<sizeof(U) <= siz eof(void*)>::type> { class LoadStoreImpl<U, typename boost::enable_if_c<sizeof(U) <= siz eof(void*)>::type> {
public: public:
static U load(volatile const U* value) { static U load(volatile const U* value) {
MemoryBarrier(); MemoryBarrier();
U result = *value; U result = *value;
MemoryBarrier(); MemoryBarrier();
 End of changes. 7 change blocks. 
11 lines changed or deleted 92 lines changed or added


 authorization_manager.h   authorization_manager.h 
skipping to change at line 112 skipping to change at line 112
// Adds a new principal with the given principal name and authorize s it with full access. // Adds a new principal with the given principal name and authorize s it with full access.
// Used to grant internal threads full access. // Used to grant internal threads full access.
void grantInternalAuthorization(const std::string& principalName); void grantInternalAuthorization(const std::string& principalName);
// 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).
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 // Parses the privilege documents and acquires all privileges that the privilege document
// grants // grants
Status acquirePrivilegesFromPrivilegeDocument(const std::string& db name, Status acquirePrivilegesFromPrivilegeDocument(const std::string& db name,
const PrincipalName& principal, const PrincipalName& principal,
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 lines changed or added


 balancer_policy.h   balancer_policy.h 
skipping to change at line 59 skipping to change at line 59
TagRange( const BSONObj& a_min, const BSONObj& a_max, const string& a_tag ) TagRange( const BSONObj& a_min, const BSONObj& a_max, const string& a_tag )
: min( a_min.getOwned() ), max( a_max.getOwned() ), tag( a_tag ){} : min( a_min.getOwned() ), max( a_max.getOwned() ), tag( a_tag ){}
string toString() const; string toString() const;
}; };
class ShardInfo { class ShardInfo {
public: public:
ShardInfo(); ShardInfo();
ShardInfo( long long maxSize, long long currSize, ShardInfo( long long maxSize, long long currSize,
bool draining, bool opsQueued, bool draining, bool opsQueued,
const set<string>& tags = set<string>() ); const set<string>& tags = set<string>(),
const string& _mongoVersion = string("") );
void addTag( const string& tag ); void addTag( const string& tag );
/** @return true if we have the tag OR if the tag is "" */ /** @return true if we have the tag OR if the tag is "" */
bool hasTag( const string& tag ) const; bool hasTag( const string& tag ) const;
/** /**
* @return true if a shard cannot receive any new chunks because it reaches 'shardLimits'. * @return true if a shard cannot receive any new chunks because it reaches 'shardLimits'.
* Expects the optional fields "maxSize", can in size in MB, and "u sedSize", currently used size * Expects the optional fields "maxSize", can in size in MB, and "u sedSize", currently used size
* in MB, on 'shardLimits'. * in MB, on 'shardLimits'.
skipping to change at line 88 skipping to change at line 89
/** /**
* @return true if a shard currently has operations in any of its w riteback queues * @return true if a shard currently has operations in any of its w riteback queues
*/ */
bool hasOpsQueued() const { return _hasOpsQueued; } bool hasOpsQueued() const { return _hasOpsQueued; }
long long getMaxSize() const { return _maxSize; } long long getMaxSize() const { return _maxSize; }
long long getCurrSize() const { return _currSize; } long long getCurrSize() const { return _currSize; }
string getMongoVersion() const { return _mongoVersion; }
string toString() const; string toString() const;
private: private:
long long _maxSize; long long _maxSize;
long long _currSize; long long _currSize;
bool _draining; bool _draining;
bool _hasOpsQueued; bool _hasOpsQueued;
set<string> _tags; set<string> _tags;
string _mongoVersion;
}; };
struct MigrateInfo { struct MigrateInfo {
const string ns; const string ns;
const string to; const string to;
const string from; const string from;
const ChunkInfo chunk; const ChunkInfo chunk;
MigrateInfo( const string& a_ns , const string& a_to , const string & a_from , const BSONObj& a_chunk ) MigrateInfo( const string& a_ns , const string& a_to , const string & a_from , const BSONObj& a_chunk )
: ns( a_ns ) , to( a_to ) , from( a_from ), chunk( a_chunk ) {} : ns( a_ns ) , to( a_to ) , from( a_from ), chunk( a_chunk ) {}
 End of changes. 3 change blocks. 
1 lines changed or deleted 5 lines changed or added


 bench.h   bench.h 
/* /*
* Copyright (C) 2010 10gen Inc. * Copyright (C) 2010 10gen Inc.
* *
* This program is free software: you can redistribute it and/or modify * Licensed under the Apache License, Version 2.0 (the "License");
* it under the terms of the GNU Affero General Public License, version * you may not use this file except in compliance with the License.
3, * You may obtain a copy of the License at
* as published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * http://www.apache.org/licenses/LICENSE-2.0
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Lice * Unless required by applicable law or agreed to in writing, software
nse * distributed under the License is distributed on an "AS IS" BASIS,
* along with this program. If not, see <http://www.gnu.org/licenses/>. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#pragma once #pragma once
#include <string> #include <string>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/thread/condition.hpp> #include <boost/thread/condition.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <pcrecpp.h> #include <pcrecpp.h>
skipping to change at line 398 skipping to change at line 398
* Store the collected event data from a completed bench run activi ty into "stats." * Store the collected event data from a completed bench run activi ty into "stats."
* *
* Illegal to call until after stop() returns. * Illegal to call until after stop() returns.
*/ */
void populateStats(BenchRunStats *stats); void populateStats(BenchRunStats *stats);
OID oid() const { return _oid; } OID oid() const { return _oid; }
const BenchRunConfig &config() const { return *_config; } // TODO: Remove this function. const BenchRunConfig &config() const { return *_config; } // TODO: Remove this function.
// JS bindings
static BSONObj benchFinish(const BSONObj& argsFake, void* data);
static BSONObj benchStart(const BSONObj& argsFake, void* data);
static BSONObj benchRunSync(const BSONObj& argsFake, void* data);
private: private:
// TODO: Same as for createWithConfig. // TODO: Same as for createWithConfig.
static boost::mutex _staticMutex; static boost::mutex _staticMutex;
static map< OID, BenchRunner* > _activeRuns; static map< OID, BenchRunner* > _activeRuns;
OID _oid; OID _oid;
BenchRunState _brState; BenchRunState _brState;
boost::scoped_ptr<BenchRunConfig> _config; boost::scoped_ptr<BenchRunConfig> _config;
vector<BenchRunWorker *> _workers; vector<BenchRunWorker *> _workers;
 End of changes. 4 change blocks. 
11 lines changed or deleted 15 lines changed or added


 bgsync.h   bgsync.h 
skipping to change at line 91 skipping to change at line 91
// 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 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
struct QueueCounter {
QueueCounter();
unsigned long long waitTime;
unsigned int numElems;
} _queueCounter;
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();
// Check if rollback is necessary // Check if rollback is necessary
bool isRollbackRequired(OplogReader& r); bool isRollbackRequired(OplogReader& r);
 End of changes. 1 change blocks. 
6 lines changed or deleted 0 lines changed or added


 bson_field.h   bson_field.h 
skipping to change at line 77 skipping to change at line 77
const std::string& name() const { return _name; } const std::string& name() const { return _name; }
private: private:
std::string _name; std::string _name;
T _t; T _t;
}; };
template<typename T> template<typename T>
class BSONField { class BSONField {
public: public:
BSONField(const std::string& name, const std::string& longName="") BSONField(const std::string& name)
: _name(name), _longName(longName) {} : _name(name), _defaultSet(false) {}
BSONField(const std::string& name, const T& defaultVal)
: _name(name), _default(defaultVal), _defaultSet(true) {}
BSONFieldValue<T> make(const T& t) const { BSONFieldValue<T> make(const T& t) const {
return BSONFieldValue<T>(_name, t); return BSONFieldValue<T>(_name, t);
} }
BSONFieldValue<T> operator()(const T& t) const { BSONFieldValue<T> operator()(const T& t) const {
return BSONFieldValue<T>(_name, t); return BSONFieldValue<T>(_name, t);
} }
const std::string& name() const { const std::string& name() const {
return _name; return _name;
} }
const T& getDefault() const {
return _default;
}
const bool hasDefault() const {
return _defaultSet;
}
std::string operator()() const { std::string operator()() const {
return _name; return _name;
} }
BSONFieldValue<BSONObj> query(const char * q, const T& t) const; BSONFieldValue<BSONObj> query(const char * q, const T& t) const;
BSONFieldValue<BSONObj> gt(const T& t) const { BSONFieldValue<BSONObj> gt(const T& t) const {
return query("$gt", t); return query("$gt", t);
} }
BSONFieldValue<BSONObj> lt(const T& t) const { BSONFieldValue<BSONObj> lt(const T& t) const {
return query("$lt", t); return query("$lt", t);
} }
BSONFieldValue<BSONObj> ne(const T& t) const { BSONFieldValue<BSONObj> ne(const T& t) const {
return query("$ne", t); return query("$ne", t);
} }
private: private:
std::string _name; std::string _name;
std::string _longName; T _default;
bool _defaultSet;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 3 change blocks. 
3 lines changed or deleted 15 lines changed or added


 bson_template_evaluator.h   bson_template_evaluator.h 
/** @file templateevaluator.h */
/* /*
* Copyright (C) 2012 10gen Inc. * Copyright (C) 2012 10gen Inc.
* *
* This program is free software: you can redistribute it and/or modify * Licensed under the Apache License, Version 2.0 (the "License");
* it under the terms of the GNU Affero General Public License, version * you may not use this file except in compliance with the License.
3, * You may obtain a copy of the License at
* as published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * http://www.apache.org/licenses/LICENSE-2.0
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Lice * Unless required by applicable law or agreed to in writing, software
nse * distributed under the License is distributed on an "AS IS" BASIS,
* along with this program. If not, see <http://www.gnu.org/licenses/>. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
/* /*
* This library supports a templating language that helps in generating BSO N documents from a * This library supports a templating language that helps in generating BSO N documents from a
* template. The language supports the following template: * template. The language supports the following template:
* #RAND_INT, #RAND_STRING and #CONCAT. * #RAND_INT, #RAND_STRING and #CONCAT.
* *
* The language will help in quickly expressing richer documents for use i n benchRun. * The language will help in quickly expressing richer documents for use i n benchRun.
* Ex. : { key : { #RAND_INT: [10, 20] } } or { key : { #CONCAT: ["hello", " ", "world"] } } * Ex. : { key : { #RAND_INT: [10, 20] } } or { key : { #CONCAT: ["hello", " ", "world"] } }
* *
 End of changes. 4 change blocks. 
13 lines changed or deleted 10 lines changed or added


 bson_validate.h   bson_validate.h 
skipping to change at line 31 skipping to change at line 31
#include "mongo/base/string_data.h" #include "mongo/base/string_data.h"
#include "mongo/bson/bsontypes.h" #include "mongo/bson/bsontypes.h"
#include "mongo/platform/cstdint.h" #include "mongo/platform/cstdint.h"
namespace mongo { namespace mongo {
/** /**
* @param buf - bson data * @param buf - bson data
* @param maxLength - maxLength of buffer * @param maxLength - maxLength of buffer
* this is NOT the bson size, but how far we know th e buffer is valid * this is NOT the bson size, but how far we know th e buffer is valid
* @param bsonLength - OUT size of bson, set if bsonLength != NULL _and _ data is valid
*/ */
Status validateBSON( const char* buf, uint64_t maxLength, int* bsonLeng th = NULL ); Status validateBSON( const char* buf, uint64_t maxLength );
} }
 End of changes. 2 change blocks. 
2 lines changed or deleted 1 lines changed or added


 btree.h   btree.h 
skipping to change at line 628 skipping to change at line 628
* as a result of deallocation. A separate class representing a btree would * as a result of deallocation. A separate class representing a btree would
* alleviate some fragile cases where the implementation must currently * alleviate some fragile cases where the implementation must currently
* behave correctly if the 'this' pointer is suddenly invalidated by a * behave correctly if the 'this' pointer is suddenly invalidated by a
* callee. * callee.
*/ */
template< class V > template< class V >
class BtreeBucket : public BucketBasics<V> { class BtreeBucket : public BucketBasics<V> {
friend class BtreeCursor; friend class BtreeCursor;
friend struct IndexInsertionContinuationImpl<V>; friend struct IndexInsertionContinuationImpl<V>;
public: public:
// make compiler happy: // make compiler happy:
typedef typename V::Key Key; typedef typename V::Key Key;
typedef typename V::KeyOwned KeyOwned; typedef typename V::KeyOwned KeyOwned;
typedef typename BucketBasics<V>::KeyNode KeyNode; typedef typename BucketBasics<V>::KeyNode KeyNode;
typedef typename BucketBasics<V>::_KeyNode _KeyNode; typedef typename BucketBasics<V>::_KeyNode _KeyNode;
typedef typename BucketBasics<V>::Loc Loc; typedef typename BucketBasics<V>::Loc Loc;
const _KeyNode& k(int i) const { return static_cast< const Buck etBasics<V> * >(this)->k(i); } const _KeyNode& k(int i) const { return static_cast< const Buck etBasics<V> * >(this)->k(i); }
protected: protected:
_KeyNode& k(int i) { return static_cast< BucketBasi cs<V> * >(this)->_k(i); } _KeyNode& k(int i) { return static_cast< BucketBasi cs<V> * >(this)->_k(i); }
public: public:
const KeyNode keyNode(int i) const { return static_cast< const Buck etBasics<V> * >(this)->keyNode(i); } const KeyNode keyNode(int i) const { return static_cast< const Buck etBasics<V> * >(this)->keyNode(i); }
bool isHead() const { return this->parent.isNull(); } bool isHead() const { return this->parent.isNull(); }
void dumpTree(const DiskLoc &thisLoc, const BSONObj &order) const; void dumpTree(const DiskLoc &thisLoc, const BSONObj &order) const;
long long fullValidate(const DiskLoc& thisLoc, const BSONObj &order , long long *unusedCount = 0, bool strict = false, unsigned depth=0) const; /* traverses everything */ long long fullValidate(const DiskLoc& thisLoc, const BSONObj &order , long long *unusedCount = 0, bool strict = false, unsigned depth=0) const; /* traverses everything */
 End of changes. 2 change blocks. 
4 lines changed or deleted 4 lines changed or added


 chunk.h   chunk.h 
skipping to change at line 100 skipping to change at line 100
void appendShortVersion( const char * name , BSONObjBuilder& b ) co nst; void appendShortVersion( const char * name , BSONObjBuilder& b ) co nst;
ChunkVersion getLastmod() const { return _lastmod; } ChunkVersion getLastmod() const { return _lastmod; }
void setLastmod( ChunkVersion v ) { _lastmod = v; } void setLastmod( ChunkVersion v ) { _lastmod = v; }
// //
// split support // split support
// //
long getBytesWritten() const { return _dataWritten; }
// Const since _dataWritten is mutable and a heuristic
// TODO: Split data tracking and chunk information
void setBytesWritten( long bytesWritten ) const { _dataWritten = by
tesWritten; }
/** /**
* if the amount of data written nears the max size of a shard * if the amount of data written nears the max size of a shard
* then we check the real size, and if its too big, we split * then we check the real size, and if its too big, we split
* @return if something was split * @return if something was split
*/ */
bool splitIfShould( long dataWritten ) const; bool splitIfShould( long dataWritten ) const;
/** /**
* Splits this chunk at a non-specificed split key to be chosen by the mongod holding this chunk. * Splits this chunk at a non-specificed split key to be chosen by the mongod holding this chunk.
* *
skipping to change at line 178 skipping to change at line 183
* marks this chunk as a jumbo chunk * marks this chunk as a jumbo chunk
* that means the chunk will be inelligble for migrates * that means the chunk will be inelligble for migrates
*/ */
void markAsJumbo() const; void markAsJumbo() const;
bool isJumbo() const { return _jumbo; } bool isJumbo() const { return _jumbo; }
/** /**
* Attempt to refresh maximum chunk size from config. * Attempt to refresh maximum chunk size from config.
*/ */
static void refreshChunkSize(); static void refreshChunkSize();
/**
* sets MaxChunkSize
* 1 <= newMaxChunkSize <= 1024
* @return true if newMaxChunkSize is valid and was set
*/
static bool setMaxChunkSizeSizeMB( int newMaxChunkSize );
// //
// public constants // public constants
// //
static int MaxChunkSize; static int MaxChunkSize;
static int MaxObjectPerChunk; static int MaxObjectPerChunk;
static bool ShouldAutoSplit; static bool ShouldAutoSplit;
// //
 End of changes. 2 change blocks. 
1 lines changed or deleted 14 lines changed or added


 chunk_version.h   chunk_version.h 
skipping to change at line 197 skipping to change at line 197
} }
if( el.isNumber() ){ if( el.isNumber() ){
return ChunkVersion( static_cast<unsigned long long>(el.num berLong()), OID() ); return ChunkVersion( static_cast<unsigned long long>(el.num berLong()), OID() );
} }
if( type == Timestamp || type == Date ){ if( type == Timestamp || type == Date ){
return ChunkVersion( el._numberLong(), OID() ); return ChunkVersion( el._numberLong(), OID() );
} }
// Note - we used to throw here, we can't anymore b/c debug bui
lds will be unhappy
warning() << "can't load version from element type (" << (int)(
el.type()) << ") "
<< el << endl;
*canParse = false; *canParse = false;
return ChunkVersion( 0, OID() ); return ChunkVersion( 0, OID() );
} }
// //
// { version : <TS>, versionEpoch : <OID> } object format // { version : <TS>, versionEpoch : <OID> } object format
// //
static bool canParseBSON( const BSONObj& obj, const string& prefix= "" ){ static bool canParseBSON( const BSONObj& obj, const string& prefix= "" ){
 End of changes. 1 change blocks. 
6 lines changed or deleted 0 lines changed or added


 client.h   client.h 
skipping to change at line 87 skipping to change at line 87
/** this has to be called as the client goes away, but before threa d termination /** this has to be called as the client goes away, but before threa d termination
* @return true if anything was done * @return true if anything was done
*/ */
bool shutdown(); bool shutdown();
string clientAddress(bool includePort=false) const; string clientAddress(bool includePort=false) const;
CurOp* curop() const { return _curOp; } CurOp* curop() const { return _curOp; }
Context* getContext() const { return _context; } Context* getContext() const { return _context; }
Database* database() const { return _context ? _context->db() : 0; } Database* database() const { return _context ? _context->db() : 0; }
const char *ns() const { return _context->ns(); } const char *ns() const { return _context->ns(); }
const std::string desc() const { return _desc; } const StringData desc() const { return _desc; }
void setLastOp( OpTime op ) { _lastOp = op; } void setLastOp( OpTime op ) { _lastOp = op; }
OpTime getLastOp() const { return _lastOp; } OpTime getLastOp() const { return _lastOp; }
/** caution -- use Context class instead */ /** caution -- use Context class instead */
void setContext(Context *c) { _context = c; } void setContext(Context *c) { _context = c; }
/* report what the last operation was. used by getlasterror */ /* report what the last operation was. used by getlasterror */
void appendLastOp( BSONObjBuilder& b ) const; void appendLastOp( BSONObjBuilder& b ) const;
bool isGod() const { return _god; } /* this is for map/reduce write s */ bool isGod() const { return _god; } /* this is for map/reduce write s */
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 clientcursor.h   clientcursor.h 
skipping to change at line 126 skipping to change at line 126
_id = c->_cursorid; _id = c->_cursorid;
} }
else { else {
_c = 0; _c = 0;
_id = INVALID_CURSOR_ID; _id = INVALID_CURSOR_ID;
} }
} }
~Holder() { ~Holder() {
DESTRUCTOR_GUARD ( reset(); ); DESTRUCTOR_GUARD ( reset(); );
} }
ClientCursor* get() { return _c; }
operator bool() { return _c; } operator bool() { return _c; }
ClientCursor * operator-> () { return _c; } ClientCursor * operator-> () { return _c; }
const ClientCursor * operator-> () const { return _c; } const ClientCursor * operator-> () const { return _c; }
/** Release ownership of the ClientCursor. */ /** Release ownership of the ClientCursor. */
void release() { void release() {
_c = 0; _c = 0;
_id = INVALID_CURSOR_ID; _id = INVALID_CURSOR_ID;
} }
private: private:
ClientCursor *_c; ClientCursor *_c;
skipping to change at line 332 skipping to change at line 333
} }
/** /**
* Deletes the cursor with the provided @param 'id' if one exists. * Deletes the cursor with the provided @param 'id' if one exists.
* @throw if the cursor with the provided id is pinned. * @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 * This does not do any auth checking and should be used only when erasing cursors as part
* of cleaning up internal operations. * of cleaning up internal operations.
*/ */
static bool erase(CursorId id); static bool erase(CursorId id);
// Same as erase but checks to make sure this thread has read permi ssion on the cursor's // 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 // namespace. This should be called when receiving killCursors fro
m a client. m a client. This should
// not be called when ccmutex is held.
static bool eraseIfAuthorized(CursorId id); static bool eraseIfAuthorized(CursorId id);
/** /**
* @return number of cursors found * @return number of cursors found
*/ */
static int erase(int n, long long* ids); static int erase(int n, long long* ids);
static int eraseIfAuthorized(int n, long long* ids); static int eraseIfAuthorized(int n, long long* ids);
void mayUpgradeStorage() { void mayUpgradeStorage() {
/* if ( !ids_.get() ) /* if ( !ids_.get() )
 End of changes. 2 change blocks. 
2 lines changed or deleted 4 lines changed or added


 cmdline.h   cmdline.h 
skipping to change at line 140 skipping to change at line 140
pid_t parentProc; // --fork pid of initial process pid_t parentProc; // --fork pid of initial process
pid_t leaderProc; // --fork pid of leader process pid_t leaderProc; // --fork pid of leader process
#endif #endif
#ifdef MONGO_SSL #ifdef MONGO_SSL
bool sslOnNormalPorts; // --sslOnNormalPorts bool sslOnNormalPorts; // --sslOnNormalPorts
std::string sslPEMKeyFile; // --sslPEMKeyFile std::string sslPEMKeyFile; // --sslPEMKeyFile
std::string sslPEMKeyPassword; // --sslPEMKeyPassword std::string sslPEMKeyPassword; // --sslPEMKeyPassword
std::string sslCAFile; // --sslCAFile std::string sslCAFile; // --sslCAFile
std::string sslCRLFile; // --sslCRLFile std::string sslCRLFile; // --sslCRLFile
bool sslForceCertificateValidation; bool sslWeakCertificateValidation;
bool sslFIPSMode;
#endif #endif
/** /**
* Switches to enable experimental (unsupported) features. * Switches to enable experimental (unsupported) features.
*/ */
struct ExperimentalFeatures { struct ExperimentalFeatures {
ExperimentalFeatures() ExperimentalFeatures()
: indexStatsCmdEnabled(false) : indexStatsCmdEnabled(false)
, storageDetailsCmdEnabled(false) , storageDetailsCmdEnabled(false)
{} {}
 End of changes. 1 change blocks. 
1 lines changed or deleted 2 lines changed or added


 collection_manager.h   collection_manager.h 
skipping to change at line 50 skipping to change at line 50
class CollectionManager { class CollectionManager {
MONGO_DISALLOW_COPYING(CollectionManager); MONGO_DISALLOW_COPYING(CollectionManager);
public: public:
~CollectionManager(); ~CollectionManager();
// //
// cloning support // cloning support
// //
/** /**
* Returns a new manager's instance based on 'this's state by remov * Returns a new manager's instance based on 'this's state by remov
ing 'chunk'. The new ing 'chunk'.
* manager will be at 'newShardVersion', which should be higher tha * When cloning away the last chunk, 'newShardVersion' must be zero
n the current . In any case,
* one. When cloning away the last chunk, 'newShardVersion' must be * the caller owns the new manager when the cloning is successful.
zero. In any case,
* the caller owns the new manager when the cloning is succesful.
* *
* If a new manager can't be created, returns NULL and fills in 'er rMsg', if it was * If a new manager can't be created, returns NULL and fills in 'er rMsg', if it was
* provided. * provided.
*/ */
CollectionManager* cloneMinus(const ChunkType& chunk, CollectionManager* cloneMinus(const ChunkType& chunk,
const ChunkVersion& newShardVersion, const ChunkVersion& newShardVersion,
string* errMsg) const; string* errMsg) const;
/** /**
* Returns a new manager's instance based on 'this's state by addin g 'chunk'. The new * Returns a new manager's instance based on 'this's state by addin g 'chunk'. The new
* manager will be at 'newShardVersion', which should be higher tha * manager can never be zero, though (see cloneMinus). The caller o
n the current wns the new manager.
* one. It can never be zero, though (see cloneMinus). The caller o
wns the new manager.
* *
* If a new manager can't be created, returns NULL and fills in 'er rMsg', if it was * If a new manager can't be created, returns NULL and fills in 'er rMsg', if it was
* provided. * provided.
*/ */
CollectionManager* clonePlus(const ChunkType& chunk, CollectionManager* clonePlus(const ChunkType& chunk,
const ChunkVersion& newShardVersion, const ChunkVersion& newShardVersion,
string* errMsg) const; string* errMsg) const;
/** /**
* Returns a new manager's instance by splitting an existing 'chunk ' at the points * Returns a new manager's instance by splitting an existing 'chunk ' at the points
skipping to change at line 105 skipping to change at line 103
* collection / chunkset yet. 'doc' must contain the sharding key a nd, optionally, * collection / chunkset yet. 'doc' must contain the sharding key a nd, optionally,
* other attributes. * other attributes.
*/ */
bool belongsToMe(const BSONObj& doc) const; bool belongsToMe(const BSONObj& doc) const;
/** /**
* Given the chunk's min key (or empty doc) in 'lookupKey', gets th e boundaries of the * Given the chunk's min key (or empty doc) in 'lookupKey', gets th e boundaries of the
* chunk following that one (the first), and fills in 'foundChunk' with those * chunk following that one (the first), and fills in 'foundChunk' with those
* boundaries. If the next chunk happens to be the last one, retur ns true otherwise * boundaries. If the next chunk happens to be the last one, retur ns true otherwise
* false. * false.
*
* @param lookupKey passing a doc that does not belong to this mana
ger 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) const; bool getNextChunk(const BSONObj& lookupKey, ChunkType* foundChunk) const;
// //
// accessors // accessors
// //
ChunkVersion getMaxCollVersion() const { return _maxCollVersion; } ChunkVersion getMaxCollVersion() const { return _maxCollVersion; }
ChunkVersion getMaxShardVersion() const { return _maxShardVersion; } ChunkVersion getMaxShardVersion() const { return _maxShardVersion; }
skipping to change at line 132 skipping to change at line 134
private: private:
// Effectively, the MetadataLoader is this class's builder. So we o pen an exception // Effectively, the MetadataLoader is this class's builder. So we o pen an exception
// and grant it friendship. // and grant it friendship.
friend class MetadataLoader; friend class MetadataLoader;
// a version for this collection that identifies the collection inc arnation (ie, a // a version for this collection that identifies the collection inc arnation (ie, a
// dropped and recreated collection with the same name would have a different version) // dropped and recreated collection with the same name would have a different version)
ChunkVersion _maxCollVersion; ChunkVersion _maxCollVersion;
// //
// sharded state below, for when the colelction gets sharded // sharded state below, for when the collection gets sharded
// //
// highest ChunkVersion for which this manager's information is acc urate // highest ChunkVersion for which this manager's information is acc urate
ChunkVersion _maxShardVersion; ChunkVersion _maxShardVersion;
// key pattern for chunks under this range // key pattern for chunks under this range
BSONObj _key; BSONObj _key;
// a map from a min key into the chunk's (or range's) max boundary // a map from a min key into the chunk's (or range's) max boundary
typedef map< BSONObj, BSONObj , BSONObjCmp > RangeMap; typedef map< BSONObj, BSONObj , BSONObjCmp > RangeMap;
 End of changes. 4 change blocks. 
12 lines changed or deleted 14 lines changed or added


 counter.h   counter.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 "mongo/platform/atomic_word.h" #include "mongo/platform/atomic_word.h"
#include "mongo/platform/cstdint.h" #include "mongo/platform/cstdint.h"
namespace mongo { namespace mongo {
/**
* A 64bit (atomic) counter.
*
* The constructor allows setting the start value, and increment([int])
is used to change it.
*
* The value can be returned using get() or the (long long) function op
erator.
*/
class Counter64 { class Counter64 {
public: public:
/** Atomically increment. */
void increment( uint64_t n = 1 ) { _counter.addAndFetch(n); } void increment( uint64_t n = 1 ) { _counter.addAndFetch(n); }
/** Atomically decrement. */
void decrement( uint64_t n = 1 ) { _counter.subtractAndFetch(n); }
/** Return the current value */
long long get() const { return _counter.load(); } long long get() const { return _counter.load(); }
operator long long() const { return get(); } operator long long() const { return get(); }
private: private:
AtomicInt64 _counter; AtomicInt64 _counter;
}; };
} }
 End of changes. 3 change blocks. 
1 lines changed or deleted 14 lines changed or added


 d_logic.h   d_logic.h 
skipping to change at line 46 skipping to change at line 46
// -------------- // --------------
class ShardingState { class ShardingState {
public: public:
ShardingState(); ShardingState();
bool enabled() const { return _enabled; } bool enabled() const { return _enabled; }
const string& getConfigServer() const { return _configServer; } const string& getConfigServer() const { return _configServer; }
void enable( const string& server ); void enable( const string& server );
// Initialize sharding state and begin authenticating outgoing conn
ections and handling
// shard versions. If this is not run before sharded operations oc
cur auth will not work
// and versions will not be tracked.
static void initialize(const string& server);
void gotShardName( const string& name ); void gotShardName( const string& name );
void gotShardHost( string host ); void gotShardHost( string host );
string getShardName() { return _shardName; } string getShardName() { return _shardName; }
string getShardHost() { return _shardHost; } string getShardHost() { return _shardHost; }
/** Reverts back to a state where this mongod is not sharded. */ /** Reverts back to a state where this mongod is not sharded. */
void resetShardingState(); void resetShardingState();
// versioning support // versioning support
 End of changes. 1 change blocks. 
0 lines changed or deleted 7 lines changed or added


 database.h   database.h 
skipping to change at line 38 skipping to change at line 38
class Extent; class Extent;
class MongoDataFile; class MongoDataFile;
/** /**
* 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:
static bool _openAllFiles;
// 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);
private: private:
~Database(); // closes files and other cleanup see below. ~Database(); // closes files and other cleanup see below.
public: public:
/* you must use this to close - there is essential code in this met hod that is not in the ~Database destructor. /* you must use this to close - there is essential code in this met hod that is not in the ~Database destructor.
thus the destructor is private. this could be cleaned up one da y... thus the destructor is private. this could be cleaned up one da y...
*/ */
static void closeDatabase( const char *db, const string& path ); static void closeDatabase( const char *db, const string& path );
void openAllFiles(); void openAllFiles();
void clearTmpCollections();
/** /**
* 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
 End of changes. 2 change blocks. 
2 lines changed or deleted 1 lines changed or added


 dbclient.h   dbclient.h 
skipping to change at line 38 skipping to change at line 38
#include "mongo/client/redef_macros.h" #include "mongo/client/redef_macros.h"
#include "mongo/pch.h" #include "mongo/pch.h"
#include "mongo/client/connpool.h" #include "mongo/client/connpool.h"
#include "mongo/client/dbclient_rs.h" #include "mongo/client/dbclient_rs.h"
#include "mongo/client/dbclientcursor.h" #include "mongo/client/dbclientcursor.h"
#include "mongo/client/dbclientinterface.h" #include "mongo/client/dbclientinterface.h"
#include "mongo/client/gridfs.h" #include "mongo/client/gridfs.h"
#include "mongo/client/model.h" #include "mongo/client/model.h"
#include "mongo/client/sasl_client_authenticate.h"
#include "mongo/client/syncclusterconnection.h" #include "mongo/client/syncclusterconnection.h"
#include "mongo/client/undef_macros.h" #include "mongo/client/undef_macros.h"
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 lines changed or added


 dbclient_rs.h   dbclient_rs.h 
skipping to change at line 34 skipping to change at line 34
#include <set> #include <set>
#include <utility> #include <utility>
#include "mongo/client/dbclientinterface.h" #include "mongo/client/dbclientinterface.h"
#include "mongo/util/net/hostandport.h" #include "mongo/util/net/hostandport.h"
namespace mongo { namespace mongo {
class ReplicaSetMonitor; class ReplicaSetMonitor;
class TagSet; class TagSet;
struct ReadPreferenceSetting;
typedef shared_ptr<ReplicaSetMonitor> ReplicaSetMonitorPtr; typedef shared_ptr<ReplicaSetMonitor> ReplicaSetMonitorPtr;
typedef pair<set<string>,set<int> > NodeDiff; typedef pair<set<string>,set<int> > NodeDiff;
/** /**
* manages state about a replica set for client * manages state about a replica set for client
* keeps tabs on whose master and what slaves are up * keeps tabs on whose master and what slaves are up
* can hand a slave to someone for SLAVE_OK * can hand a slave to someone for SLAVE_OK
* one instance per process per replica set * one instance per process per replica set
* TODO: we might be able to use a regular Node * to avoid _lock * TODO: we might be able to use a regular Node * to avoid _lock
*/ */
skipping to change at line 434 skipping to change at line 435
DBClientReplicaSet( const string& name , const vector<HostAndPort>& servers, double so_timeout=0 ); DBClientReplicaSet( const string& name , const vector<HostAndPort>& servers, double so_timeout=0 );
virtual ~DBClientReplicaSet(); virtual ~DBClientReplicaSet();
/** /**
* Returns false if no member of the set were reachable. This objec t * Returns false if no member of the set were reachable. This objec t
* can still be used even when false was returned as it will try to * can still be used even when false was returned as it will try to
* reconnect when you use it later. * reconnect when you use it later.
*/ */
bool connect(); bool connect();
/** Authorize. Authorizes all nodes as needed
*/
virtual bool auth(const string &dbname, const string &username, con
st string &pwd, string& errmsg, bool digestPassword = true, Auth::Level * l
evel = NULL);
/** /**
* Logs out the connection for the given database. * Logs out the connection for the given database.
* *
* @param dbname the database to logout from. * @param dbname the database to logout from.
* @param info the result object for the logout command (provided f or backwards * @param info the result object for the logout command (provided f or backwards
* compatibility with mongo shell) * compatibility with mongo shell)
*/ */
virtual void logout(const string& dbname, BSONObj& info); virtual void logout(const string& dbname, BSONObj& info);
// ----------- simple functions -------------- // ----------- simple functions --------------
skipping to change at line 477 skipping to change at line 474
// ---- access raw connections ---- // ---- access raw connections ----
/** /**
* WARNING: this method is very dangerous - this object can decide to free the * WARNING: this method is very dangerous - this object can decide to free the
* returned master connection any time. * returned master connection any time.
* *
* @return the reference to the address that points to the master c onnection. * @return the reference to the address that points to the master c onnection.
*/ */
DBClientConnection& masterConn(); DBClientConnection& masterConn();
/**
* WARNING: this method is very dangerous - this object can decide
to free the
* returned master connection any time. This can also unpin the
cached
* slaveOk/read preference connection.
*
* @return the reference to the address that points to a secondary
connection.
*/
DBClientConnection& slaveConn(); DBClientConnection& slaveConn();
// ---- callback pieces ------- // ---- callback pieces -------
virtual void say( Message &toSend, bool isRetry = false , string* a ctualServer = 0); virtual void say( Message &toSend, bool isRetry = false , string* a ctualServer = 0);
virtual bool recv( Message &toRecv ); virtual bool recv( Message &toRecv );
virtual void checkResponse( const char* data, int nReturned, bool* retry = NULL, string* targetHost = NULL ); virtual void checkResponse( const char* data, int nReturned, bool* retry = NULL, string* targetHost = NULL );
/* this is the callback from our underlying connections to notify u s that we got a "not master" error. /* this is the callback from our underlying connections to notify u s that we got a "not master" error.
*/ */
skipping to change at line 514 skipping to change at line 519
virtual ConnectionString::ConnectionType type() const { return Conn ectionString::SET; } virtual ConnectionString::ConnectionType type() const { return Conn ectionString::SET; }
virtual bool lazySupported() const { return true; } virtual bool lazySupported() const { return true; }
// ---- low level ------ // ---- low level ------
virtual bool call( Message &toSend, Message &response, bool assertO k=true , string * actualServer = 0 ); virtual bool call( Message &toSend, Message &response, bool assertO k=true , string * actualServer = 0 );
virtual bool callRead( Message& toSend , Message& response ) { retu rn checkMaster()->callRead( toSend , response ); } virtual bool callRead( Message& toSend , Message& response ) { retu rn checkMaster()->callRead( toSend , response ); }
protected: protected:
/** Authorize. Authorizes all nodes as needed
*/
virtual void _auth(const BSONObj& params);
virtual void sayPiggyBack( Message &toSend ) { checkMaster()->say( toSend ); } virtual void sayPiggyBack( Message &toSend ) { checkMaster()->say( toSend ); }
private: private:
/** /**
* Used to simplify slave-handling logic on errors * Used to simplify slave-handling logic on errors
* *
* @return back the passed cursor * @return back the passed cursor
* @throws DBException if the directed node cannot accept the query because it * @throws DBException if the directed node cannot accept the query because it
* is not a master * is not a master
*/ */
auto_ptr<DBClientCursor> checkSlaveQueryResult( auto_ptr<DBClientCu rsor> result ); auto_ptr<DBClientCursor> checkSlaveQueryResult( auto_ptr<DBClientCu rsor> result );
DBClientConnection * checkMaster(); DBClientConnection * checkMaster();
/** /**
* Helper method for selecting a node based on the read preference. Will advance * Helper method for selecting a node based on the read preference. Will advance
* the tag tags object if it cannot find a node that matches the cu rrent tag. * the tag tags object if it cannot find a node that matches the cu rrent tag.
* *
* @param preference the preference to use for selecting a node * @param readPref the preference to use for selecting a node.
* @param tags pointer to the list of tags.
* *
* @return a pointer to the new connection object if it can find a good connection. * @return a pointer to the new connection object if it can find a good connection.
* Otherwise it returns NULL. * Otherwise it returns NULL.
* *
* @throws DBException when an error occurred either when trying to connect to * @throws DBException when an error occurred either when trying to connect to
* a node that was thought to be ok or when an assertion happen ed. * a node that was thought to be ok or when an assertion happen ed.
*/ */
DBClientConnection* selectNodeUsingTags(ReadPreference preference, DBClientConnection* selectNodeUsingTags(shared_ptr<ReadPreferenceSe
TagSet* tags); tting> readPref);
/** /**
* @return true if the last host used in the last slaveOk query is still in the * @return true if the last host used in the last slaveOk query is still in the
* set and can be used for the given read preference. * set and can be used for the given read preference.
*/ */
bool checkLastHost( ReadPreference preference, const TagSet* tags ) ; bool checkLastHost(const ReadPreferenceSetting* readPref);
/** /**
* Destroys all cached information about the last slaveOk operation . * Destroys all cached information about the last slaveOk operation .
*/ */
void invalidateLastSlaveOkCache(); void invalidateLastSlaveOkCache();
void _auth( DBClientConnection * conn ); void _auth( DBClientConnection * conn );
/** /**
* Maximum number of retries to make for auto-retry logic when perf orming a slave ok * Maximum number of retries to make for auto-retry logic when perf orming a slave ok
skipping to change at line 581 skipping to change at line 588
// This is because the primary connection is special in mongos - it is the only // This is because the primary connection is special in mongos - it is the only
// connection that is versioned. // connection that is versioned.
// WARNING: do not assign this variable (which will increment the i nternal ref // WARNING: do not assign this variable (which will increment the i nternal ref
// counter) to any other variable other than _lastSlaveOkConn. // counter) to any other variable other than _lastSlaveOkConn.
boost::shared_ptr<DBClientConnection> _master; boost::shared_ptr<DBClientConnection> _master;
// Last used host in a slaveOk query (can be a primary) // Last used host in a slaveOk query (can be a primary)
HostAndPort _lastSlaveOkHost; HostAndPort _lastSlaveOkHost;
// Last used connection in a slaveOk query (can be a primary) // Last used connection in a slaveOk query (can be a primary)
boost::shared_ptr<DBClientConnection> _lastSlaveOkConn; boost::shared_ptr<DBClientConnection> _lastSlaveOkConn;
boost::shared_ptr<ReadPreferenceSetting> _lastReadPref;
double _so_timeout; double _so_timeout;
/**
* for storing authentication info
* fields are exactly for DBClientConnection::auth
*/
struct AuthInfo {
// Default constructor provided only to make it compatible with
std::map::operator[]
AuthInfo(): digestPassword(false) { }
AuthInfo( string d , string u , string p , bool di )
: dbname( d ) , username( u ) , pwd( p ) , digestPassword(
di ) {}
string dbname;
string username;
string pwd;
bool digestPassword;
};
// we need to store so that when we connect to a new node on failur e // we need to store so that when we connect to a new node on failur e
// we can re-auth // we can re-auth
// this could be a security issue, as the password is stored in mem ory // this could be a security issue, as the password is stored in mem ory
// not sure if/how we should handle // not sure if/how we should handle
std::map<string, AuthInfo> _auths; // dbName -> AuthInfo std::map<string, BSONObj> _auths; // dbName -> auth parameters
protected: protected:
/** /**
* for storing (non-threadsafe) information between lazy calls * for storing (non-threadsafe) information between lazy calls
*/ */
class LazyState { class LazyState {
public: public:
LazyState() : _lastClient( NULL ), _lastOp( -1 ), _slaveOk( fal se ), _retries( 0 ) {} LazyState() : _lastClient( NULL ), _lastOp( -1 ), _slaveOk( fal se ), _retries( 0 ) {}
DBClientConnection* _lastClient; DBClientConnection* _lastClient;
skipping to change at line 669 skipping to change at line 662
* @return true if the iterator has been exhausted. * @return true if the iterator has been exhausted.
*/ */
bool isExhausted() const; bool isExhausted() const;
/** /**
* @return an unordered iterator to the tag list. The caller is res ponsible for * @return an unordered iterator to the tag list. The caller is res ponsible for
* destroying the returned iterator. * destroying the returned iterator.
*/ */
BSONObjIterator* getIterator() const; BSONObjIterator* getIterator() const;
/**
* Create a new copy of this tag set and wuth the iterator pointing
at the
* head.
*/
TagSet* clone() const;
/**
* @returns true if the other TagSet has the same tag set specifica
tion with
* this tag set, disregarding where the current iterator is poi
nting to.
*/
bool equals(const TagSet& other) const;
private: private:
BSONObj _currentTag; BSONObj _currentTag;
bool _isExhausted; bool _isExhausted;
// Important: do not re-order _tags & _tagIterator // Important: do not re-order _tags & _tagIterator
BSONArray _tags; BSONArray _tags;
BSONArrayIteratorSorted _tagIterator; BSONArrayIteratorSorted _tagIterator;
}; };
struct ReadPreferenceSetting {
/**
* @param tag cannot be NULL.
*/
ReadPreferenceSetting(ReadPreference pref, TagSet* tag):
pref(pref), tags(tag->clone()) {
}
~ReadPreferenceSetting() {
delete tags;
}
inline bool equals(const ReadPreferenceSetting& other) const {
return pref == other.pref && tags->equals(*other.tags);
}
const ReadPreference pref;
/**
* Note: This object owns this memory.
*/
TagSet* tags;
};
} }
 End of changes. 12 change blocks. 
29 lines changed or deleted 61 lines changed or added


 dbclientcursor.h   dbclientcursor.h 
skipping to change at line 65 skipping to change at line 65
then perhaps stop. then perhaps stop.
*/ */
int objsLeftInBatch() const { _assertIfNull(); return _putBack.size () + batch.nReturned - batch.pos; } int objsLeftInBatch() const { _assertIfNull(); return _putBack.size () + batch.nReturned - batch.pos; }
bool moreInCurrentBatch() { return objsLeftInBatch() > 0; } bool moreInCurrentBatch() { return objsLeftInBatch() > 0; }
/** next /** next
@return next object in the result cursor. @return next object in the result cursor.
on an error at the remote server, you will get back: on an error at the remote server, you will get back:
{ $err: <string> } { $err: <string> }
if you do not want to handle that yourself, call nextSafe(). if you do not want to handle that yourself, call nextSafe().
Warning: The returned BSONObj will become invalid after the next
batch
is fetched or when this cursor is destroyed.
*/ */
BSONObj next(); BSONObj next();
/** /**
restore an object previously returned by next() to the cursor restore an object previously returned by next() to the cursor
*/ */
void putBack( const BSONObj &o ) { _putBack.push( o.getOwned() ); } void putBack( const BSONObj &o ) { _putBack.push( o.getOwned() ); }
/** throws AssertionException if get back { $err : ... } */ /** throws AssertionException if get back { $err : ... } */
BSONObj nextSafe() { BSONObj nextSafe() {
skipping to change at line 141 skipping to change at line 144
int _nToSkip, const BSONObj *_fieldsToReturn, int q ueryOptions , int bs ) : int _nToSkip, const BSONObj *_fieldsToReturn, int q ueryOptions , int bs ) :
_client(client), _client(client),
ns(_ns), ns(_ns),
query(_query), query(_query),
nToReturn(_nToReturn), nToReturn(_nToReturn),
haveLimit( _nToReturn > 0 && !(queryOptions & QueryOption_Curso rTailable)), haveLimit( _nToReturn > 0 && !(queryOptions & QueryOption_Curso rTailable)),
nToSkip(_nToSkip), nToSkip(_nToSkip),
fieldsToReturn(_fieldsToReturn), fieldsToReturn(_fieldsToReturn),
opts(queryOptions), opts(queryOptions),
batchSize(bs==1?2:bs), batchSize(bs==1?2:bs),
resultFlags(0),
cursorId(), cursorId(),
_ownCursor( true ), _ownCursor( true ),
wasError( false ) { wasError( false ) {
_finishConsInit(); _finishConsInit();
} }
DBClientCursor( DBClientBase* client, const string &_ns, long long _cursorId, int _nToReturn, int options ) : DBClientCursor( DBClientBase* client, const string &_ns, long long _cursorId, int _nToReturn, int options ) :
_client(client), _client(client),
ns(_ns), ns(_ns),
nToReturn( _nToReturn ), nToReturn( _nToReturn ),
haveLimit( _nToReturn > 0 && !(options & QueryOption_CursorTail able)), haveLimit( _nToReturn > 0 && !(options & QueryOption_CursorTail able)),
nToSkip(0),
fieldsToReturn(0),
opts( options ), opts( options ),
batchSize(0),
resultFlags(0),
cursorId(_cursorId), cursorId(_cursorId),
_ownCursor( true ) { _ownCursor(true),
wasError(false) {
_finishConsInit(); _finishConsInit();
} }
virtual ~DBClientCursor(); virtual ~DBClientCursor();
long long getCursorId() const { return cursorId; } long long getCursorId() const { return cursorId; }
/** by default we "own" the cursor and will send the server a KillC ursor /** by default we "own" the cursor and will send the server a KillC ursor
message when ~DBClientCursor() is called. This function overrid es that. message when ~DBClientCursor() is called. This function overrid es that.
*/ */
 End of changes. 5 change blocks. 
1 lines changed or deleted 11 lines changed or added


 dbclientinterface.h   dbclientinterface.h 
skipping to change at line 25 skipping to change at line 25
* 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 "mongo/client/authlevel.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/platform/atomic_word.h" #include "mongo/platform/atomic_word.h"
#include "mongo/util/net/message.h" #include "mongo/util/net/message.h"
#include "mongo/util/net/message_port.h" #include "mongo/util/net/message_port.h"
namespace mongo { namespace mongo {
/** the query field 'options' can have these bits set: */ /** the query field 'options' can have these bits set: */
enum QueryOptions { enum QueryOptions {
/** Tailable means cursor is not closed when the last data is retri eved. rather, the cursor marks /** Tailable means cursor is not closed when the last data is retri eved. rather, the cursor marks
skipping to change at line 167 skipping to change at line 166
* Read from a secondary if available, otherwise read from the prim ary. * Read from a secondary if available, otherwise read from the prim ary.
*/ */
ReadPreference_SecondaryPreferred, ReadPreference_SecondaryPreferred,
/** /**
* Read from any member. * Read from any member.
*/ */
ReadPreference_Nearest, ReadPreference_Nearest,
}; };
/**
* @return true if the query object contains a read preference specific
ation object.
*/
bool hasReadPreference(const BSONObj& queryObj);
class DBClientBase; class DBClientBase;
class DBClientConnection; class DBClientConnection;
/** /**
* ConnectionString handles parsing different ways to connect to mongo and determining method * ConnectionString handles parsing different ways to connect to mongo and determining method
* samples: * samples:
* server * server
* server:port * server:port
* foo/server:port,server:port SET * foo/server:port,server:port SET
* server,server,server SYNC * server,server,server SYNC
skipping to change at line 332 skipping to change at line 326
class DBClientCursor; class DBClientCursor;
class DBClientCursorBatchIterator; class DBClientCursorBatchIterator;
/** Represents a Mongo query expression. Typically one uses the QUERY( ...) macro to construct a Query object. /** Represents a Mongo query expression. Typically one uses the QUERY( ...) macro to construct a Query object.
Examples: Examples:
QUERY( "age" << 33 << "school" << "UCLA" ).sort("name") QUERY( "age" << 33 << "school" << "UCLA" ).sort("name")
QUERY( "age" << GT << 30 << LT << 50 ) QUERY( "age" << GT << 30 << LT << 50 )
*/ */
class Query { class Query {
public: public:
static const BSONField<BSONObj> ReadPrefField;
static const BSONField<std::string> ReadPrefModeField;
static const BSONField<BSONArray> ReadPrefTagsField;
BSONObj obj; BSONObj obj;
Query() : obj(BSONObj()) { } Query() : obj(BSONObj()) { }
Query(const BSONObj& b) : obj(b) { } Query(const BSONObj& b) : obj(b) { }
Query(const string &json); Query(const string &json);
Query(const char * json); Query(const char * json);
/** Add a sort (ORDER BY) criteria to the query expression. /** Add a sort (ORDER BY) criteria to the query expression.
@param sortPattern the sort order template. For example to ord er by name ascending, time descending: @param sortPattern the sort order template. For example to ord er by name ascending, time descending:
{ name : 1, ts : -1 } { name : 1, ts : -1 }
i.e. i.e.
skipping to change at line 407 skipping to change at line 405
of these as "bind variables". of these as "bind variables".
Examples: Examples:
conn.findOne("test.coll", Query("{a:3}").where("this.b == 2 | | this.c == 3")); conn.findOne("test.coll", Query("{a:3}").where("this.b == 2 | | this.c == 3"));
Query badBalance = Query().where("this.debits - this.credits < 0"); Query badBalance = Query().where("this.debits - this.credits < 0");
*/ */
Query& where(const string &jscode, BSONObj scope); Query& where(const string &jscode, BSONObj scope);
Query& where(const string &jscode) { return where(jscode, BSONObj() ); } Query& where(const string &jscode) { return where(jscode, BSONObj() ); }
/** /**
* Sets the read preference for this query.
*
* @param pref the read preference mode for this query.
* @param tags the set of tags to use for this query.
*/
Query& readPref(ReadPreference pref, const BSONArray& tags);
/**
* @return true if this query has an orderby, hint, or some other f ield * @return true if this query has an orderby, hint, or some other f ield
*/ */
bool isComplex( bool * hasDollar = 0 ) const; bool isComplex( bool * hasDollar = 0 ) const;
static bool isComplex(const BSONObj& obj, bool* hasDollar = 0);
BSONObj getFilter() const; BSONObj getFilter() const;
BSONObj getSort() const; BSONObj getSort() const;
BSONObj getHint() const; BSONObj getHint() const;
bool isExplain() const; bool isExplain() const;
/**
* @return true if the query object contains a read preference spec
ification object.
*/
static bool hasReadPreference(const BSONObj& queryObj);
string toString() const; string toString() const;
operator string() const { return toString(); } operator string() const { return toString(); }
private: private:
void makeComplex(); void makeComplex();
template< class T > template< class T >
void appendComplex( const char *fieldName, const T& val ) { void appendComplex( const char *fieldName, const T& val ) {
makeComplex(); makeComplex();
BSONObjBuilder b; BSONObjBuilder b;
b.appendElements(obj); b.appendElements(obj);
b.append(fieldName, val); b.append(fieldName, val);
skipping to change at line 595 skipping to change at line 607
@param info the result object the database returns. Typically h as { ok : ..., errmsg : ... } fields @param info the result object the database returns. Typically h as { ok : ..., errmsg : ... } fields
set. set.
@param options see enum QueryOptions - normally not needed to r un a command @param options see enum QueryOptions - normally not needed to r un a command
@param auth if set, the BSONObj representation will be appended to the command object sent @param auth if set, the BSONObj representation will be appended to the command object sent
@return true if the command returned "ok". @return true if the command returned "ok".
*/ */
virtual bool runCommand(const string &dbname, const BSONObj& cmd, B SONObj &info, virtual bool runCommand(const string &dbname, const BSONObj& cmd, B SONObj &info,
int options=0); int options=0);
/**
* Authenticate a user.
*
* The "params" BSONObj should be initialized with some of the fiel
ds below. Which fields
* are required depends on the mechanism, which is mandatory.
*
* "mechanism": The string name of the sasl mechanism to use.
Mandatory.
* "user": The string name of the principal to authenticate. M
andatory.
* "userSource": The database target of the auth command, which
identifies the location
* of the credential information for the principal. May be
"$external" if
* credential information is stored outside of the mongo cl
uster. Mandatory.
* "pwd": The password data.
* "digestPassword": Boolean, set to true if the "pwd" is undig
ested (default).
* "serviceName": The GSSAPI service name to use. Defaults to
"mongodb".
* "serviceHostname": The GSSAPI hostname to use. Defaults to
the name of the remote
* host.
*
* Other fields in "params" are silently ignored.
*
* Returns normally on success, and throws on error. Throws a DBEx
ception with getCode() ==
* ErrorCodes::AuthenticationFailed if authentication is rejected.
All other exceptions are
* tantamount to authentication failure, but may also indicate more
serious problems.
*/
void auth(const BSONObj& params);
/** Authorize access to a particular database. /** Authorize access to a particular database.
Authentication is separate for each database on the server -- y ou may authenticate for any Authentication is separate for each database on the server -- y ou may authenticate for any
number of databases on a single connection. number of databases on a single connection.
The "admin" database is special and once authenticated provides access to all databases on the The "admin" database is special and once authenticated provides access to all databases on the
server. server.
@param digestPassword if password is plain text, set this to true. otherwise assumed to be pre-digested @param digestPassword if password is plain text, set this to true. otherwise assumed to be pre-digested
@param[out] authLevel level of authentication for the giv en user @param[out] authLevel level of authentication for the giv en user
@return true if successful @return true if successful
*/ */
virtual bool auth(const string &dbname, const string &username, con st string &pwd, string& errmsg, bool digestPassword = true, Auth::Level * l evel = NULL); bool auth(const string &dbname, const string &username, const strin g &pwd, string& errmsg, bool digestPassword = true);
/** /**
* Logs out the connection for the given database. * Logs out the connection for the given database.
* *
* @param dbname the database to logout from. * @param dbname the database to logout from.
* @param info the result object for the logout command (provided f or backwards * @param info the result object for the logout command (provided f or backwards
* compatibility with mongo shell) * compatibility with mongo shell)
*/ */
virtual void logout(const string& dbname, BSONObj& info); virtual void logout(const string& dbname, BSONObj& info);
skipping to change at line 869 skipping to change at line 906
bool exists( const string& ns ); bool exists( const string& ns );
/** Create an index if it does not already exist. /** Create an index if it does not already exist.
ensureIndex calls are remembered so it is safe/fast to call thi s function many ensureIndex calls are remembered so it is safe/fast to call thi s function many
times in your code. times in your code.
@param ns collection to be indexed @param ns collection to be indexed
@param keys the "key pattern" for the index. e.g., { name : 1 } @param keys the "key pattern" for the index. e.g., { name : 1 }
@param unique if true, indicates that key uniqueness should be e nforced for this index @param unique if true, indicates that key uniqueness should be e nforced for this index
@param name if not specified, it will be created from the keys a utomatically (which is recommended) @param name if not specified, it will be created from the keys a utomatically (which is recommended)
@param cache if set to false, the index cache for the connection won't remember this call @param cache if set to false, the index cache for the connection won't remember this call
@param background build index in the background (see mongodb doc s/wiki for details) @param background build index in the background (see mongodb doc s for details)
@param v index version. leave at default value. (unit tests set this parameter.) @param v index version. leave at default value. (unit tests set this parameter.)
@param ttl. The value of how many seconds before data should be removed from a collection. @param ttl. The value of how many seconds before data should be removed from a collection.
@return whether or not sent message to db. @return whether or not sent message to db.
should be true on first call, false on subsequent unless reset IndexCache was called should be true on first call, false on subsequent unless reset IndexCache was called
*/ */
virtual bool ensureIndex( const string &ns, virtual bool ensureIndex( const string &ns,
BSONObj keys, BSONObj keys,
bool unique = false, bool unique = false,
const string &name = "", const string &name = "",
bool cache = true, bool cache = true,
skipping to change at line 928 skipping to change at line 965
BSONObj _countCmd(const string &ns, const BSONObj& query, int optio ns, int limit, int skip ); BSONObj _countCmd(const string &ns, const BSONObj& query, int optio ns, int limit, int skip );
/** /**
* Look up the options available on this client. Caches the answer from * Look up the options available on this client. Caches the answer from
* _lookupAvailableOptions(), below. * _lookupAvailableOptions(), below.
*/ */
QueryOptions availableOptions(); QueryOptions availableOptions();
virtual QueryOptions _lookupAvailableOptions(); virtual QueryOptions _lookupAvailableOptions();
virtual void _auth(const BSONObj& params);
/**
* Use the MONGODB-CR protocol to authenticate as "username" agains
t the database "dbname",
* with the given password. If digestPassword is false, the passwo
rd is assumed to be
* pre-digested. Returns false on failure, and sets "errmsg".
*/
bool _authMongoCR(const string &dbname,
const string &username,
const string &pwd,
string& errmsg,
bool digestPassword);
private: private:
enum QueryOptions _cachedAvailableOptions; enum QueryOptions _cachedAvailableOptions;
bool _haveCachedAvailableOptions; bool _haveCachedAvailableOptions;
}; };
/** /**
abstract class that implements the core db operations abstract class that implements the core db operations
*/ */
class DBClientBase : public DBClientWithCommands, public DBConnector { class DBClientBase : public DBClientWithCommands, public DBConnector {
protected: protected:
skipping to change at line 1115 skipping to change at line 1165
false was returned -- it will try to connect again. false was returned -- it will try to connect again.
@param serverHostname host to connect to. can include port numb er ( 127.0.0.1 , 127.0.0.1:5555 ) @param serverHostname host to connect to. can include port numb er ( 127.0.0.1 , 127.0.0.1:5555 )
*/ */
void connect(const string& serverHostname) { void connect(const string& serverHostname) {
string errmsg; string errmsg;
if( !connect(HostAndPort(serverHostname), errmsg) ) if( !connect(HostAndPort(serverHostname), errmsg) )
throw ConnectException(string("can't connect ") + errmsg); throw ConnectException(string("can't connect ") + errmsg);
} }
virtual bool auth(const string &dbname, const string &username, con
st string &pwd, string& errmsg, bool digestPassword = true, Auth::Level* le
vel=NULL);
virtual auto_ptr<DBClientCursor> query(const string &ns, Query quer y=Query(), int nToReturn = 0, int nToSkip = 0, virtual auto_ptr<DBClientCursor> query(const string &ns, Query quer y=Query(), int nToReturn = 0, int nToSkip = 0,
const BSONObj *fieldsToRetur n = 0, int queryOptions = 0 , int batchSize = 0 ) { const BSONObj *fieldsToRetur n = 0, int queryOptions = 0 , int batchSize = 0 ) {
checkConnection(); checkConnection();
return DBClientBase::query( ns, query, nToReturn, nToSkip, fiel dsToReturn, queryOptions , batchSize ); return DBClientBase::query( ns, query, nToReturn, nToSkip, fiel dsToReturn, queryOptions , batchSize );
} }
virtual unsigned long long query( boost::function<void(DBClientCurs orBatchIterator &)> f, virtual unsigned long long query( boost::function<void(DBClientCurs orBatchIterator &)> f,
const string& ns, const string& ns,
Query query, Query query,
const BSONObj *fieldsToReturn, const BSONObj *fieldsToReturn,
skipping to change at line 1189 skipping to change at line 1237
*/ */
void setReplSetClientCallback(DBClientReplicaSet* rsClient); void setReplSetClientCallback(DBClientReplicaSet* rsClient);
static void setLazyKillCursor( bool lazy ) { _lazyKillCursor = lazy ; } static void setLazyKillCursor( bool lazy ) { _lazyKillCursor = lazy ; }
static bool getLazyKillCursor() { return _lazyKillCursor; } static bool getLazyKillCursor() { return _lazyKillCursor; }
uint64_t getSockCreationMicroSec() const; uint64_t getSockCreationMicroSec() const;
protected: protected:
friend class SyncClusterConnection; friend class SyncClusterConnection;
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; time_t lastReconnectTry;
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, pair<string,string> > authCache; map<string, BSONObj> authCache;
double _so_timeout; double _so_timeout;
bool _connect( string& errmsg ); bool _connect( string& errmsg );
static AtomicUInt _numConnections; static AtomicUInt _numConnections;
static bool _lazyKillCursor; // lazy means we piggy back kill curso rs on next op static bool _lazyKillCursor; // lazy means we piggy back kill curso rs on next op
#ifdef MONGO_SSL #ifdef MONGO_SSL
SSLManager* sslManager(); SSLManager* sslManager();
#endif #endif
}; };
 End of changes. 13 change blocks. 
14 lines changed or deleted 75 lines changed or added


 dbmessage.h   dbmessage.h 
skipping to change at line 204 skipping to change at line 204
BSONObj nextJsObj() { BSONObj nextJsObj() {
if ( nextjsobj == data ) { if ( nextjsobj == data ) {
nextjsobj += strlen(data) + 1; // skip namespace nextjsobj += strlen(data) + 1; // skip namespace
massert( 13066 , "Message contains no documents", theEnd > nextjsobj ); massert( 13066 , "Message contains no documents", theEnd > nextjsobj );
} }
massert( 10304, massert( 10304,
"Client Error: Remaining data too small for BSON objec t", "Client Error: Remaining data too small for BSON objec t",
theEnd - nextjsobj >= 5 ); theEnd - nextjsobj >= 5 );
if ( cmdLine.objcheck ) { if ( cmdLine.objcheck ) {
Status status = validateBSON( nextjsobj, theEnd - nextjsobj , NULL ); Status status = validateBSON( nextjsobj, theEnd - nextjsobj );
massert( 10307, massert( 10307,
str::stream() << "Client Error: bad object in mess age: " << status.reason(), str::stream() << "Client Error: bad object in mess age: " << status.reason(),
status.isOK() ); status.isOK() );
} }
BSONObj js(nextjsobj); BSONObj js(nextjsobj);
verify( js.objsize() >= 5 ); verify( js.objsize() >= 5 );
verify( js.objsize() < ( theEnd - data ) ); verify( js.objsize() < ( theEnd - data ) );
nextjsobj += js.objsize(); nextjsobj += js.objsize();
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 document_source.h   document_source.h 
skipping to change at line 508 skipping to change at line 508
virtual ~DocumentSourceFilterBase(); virtual ~DocumentSourceFilterBase();
virtual bool eof(); virtual bool eof();
virtual bool advance(); virtual bool advance();
virtual Document getCurrent(); 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 wiki documentation for the See db/Matcher.h and the associated documentation for the format.
format. This conversion is used to move back to the low-level This conversion is used to move back to the low-level find()
find() Cursor mechanism. Cursor mechanism.
@param pBuilder the builder to write to @param pBuilder the builder to write to
*/ */
virtual void toMatcherBson(BSONObjBuilder *pBuilder) const = 0; virtual void toMatcherBson(BSONObjBuilder *pBuilder) const = 0;
protected: protected:
DocumentSourceFilterBase( DocumentSourceFilterBase(
const intrusive_ptr<ExpressionContext> &pExpCtx); const intrusive_ptr<ExpressionContext> &pExpCtx);
/** /**
skipping to change at line 574 skipping to change at line 574
*/ */
static intrusive_ptr<DocumentSourceFilter> create( static intrusive_ptr<DocumentSourceFilter> create(
const intrusive_ptr<Expression> &pFilter, const intrusive_ptr<Expression> &pFilter,
const intrusive_ptr<ExpressionContext> &pExpCtx); const intrusive_ptr<ExpressionContext> &pExpCtx);
/** /**
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 wiki documentation for the See db/Matcher.h and the associated documentation for the format.
format. This conversion is used to move back to the low-level This conversion is used to move back to the low-level find()
find() Cursor mechanism. Cursor mechanism.
@param pBuilder the builder to write to @param pBuilder the builder to write to
*/ */
void toMatcherBson(BSONObjBuilder *pBuilder) const; void toMatcherBson(BSONObjBuilder *pBuilder) const;
static const char filterName[]; static const char filterName[];
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;
skipping to change at line 734 skipping to change at line 734
*/ */
static intrusive_ptr<DocumentSource> createFromBson( static intrusive_ptr<DocumentSource> createFromBson(
BSONElement *pBsonElement, BSONElement *pBsonElement,
const intrusive_ptr<ExpressionContext> &pCtx); const intrusive_ptr<ExpressionContext> &pCtx);
/** /**
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 wiki documentation for the See db/Matcher.h and the associated documentation for the format.
format. This conversion is used to move back to the low-level This conversion is used to move back to the low-level find()
find() Cursor mechanism. Cursor mechanism.
@param pBuilder the builder to write to @param pBuilder the builder to write to
*/ */
void toMatcherBson(BSONObjBuilder *pBuilder) const; void toMatcherBson(BSONObjBuilder *pBuilder) const;
static const char matchName[]; static const char matchName[];
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;
 End of changes. 3 change blocks. 
9 lines changed or deleted 9 lines changed or added


 dur_commitjob.h   dur_commitjob.h 
skipping to change at line 111 skipping to change at line 111
wassert( _intents.size() < 2000000 ); wassert( _intents.size() < 2000000 );
} }
#if defined(DEBUG_WRITE_INTENT) #if defined(DEBUG_WRITE_INTENT)
map<void*,int> _debug; map<void*,int> _debug;
#endif #endif
}; };
/** so we don't have to lock the groupCommitMutex too often */ /** so we don't have to lock the groupCommitMutex too often */
class ThreadLocalIntents { class ThreadLocalIntents {
enum { N = 21 }; enum { N = 21 };
dur::WriteIntent i[N]; std::vector<dur::WriteIntent> intents;
int n; bool condense();
public: public:
ThreadLocalIntents() : n(0) { } ThreadLocalIntents() : intents(N) { intents.clear(); }
~ThreadLocalIntents();
void _unspool(); void _unspool();
void unspool(); void unspool();
void push(const WriteIntent& i); void push(const WriteIntent& i);
int n_informational() const { return n; } int n_informational() const { return intents.size(); }
static AtomicUInt nSpooled; static AtomicUInt nSpooled;
}; };
/** A commit job object for a group commit. Currently there is one instance of this object. /** A commit job object for a group commit. Currently there is one instance of this object.
concurrency: assumption is caller is appropriately locking. concurrency: assumption is caller is appropriately locking.
for example note() invocations are from the write lock. for example note() invocations are from the write lock.
other uses are in a read lock from a single thread (durThread) other uses are in a read lock from a single thread (durThread)
*/ */
class CommitJob : boost::noncopyable { class CommitJob : boost::noncopyable {
 End of changes. 3 change blocks. 
4 lines changed or deleted 5 lines changed or added


 engine.h   engine.h 
skipping to change at line 25 skipping to change at line 25
* limitations under the License. * limitations under the License.
*/ */
#pragma once #pragma once
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
namespace mongo { namespace mongo {
typedef unsigned long long ScriptingFunction; typedef unsigned long long ScriptingFunction;
typedef BSONObj (*NativeFunction)(const BSONObj& args, void* data); typedef BSONObj (*NativeFunction)(const BSONObj& args, void* data);
typedef map<string, ScriptingFunction> FunctionCacheMap;
class DBClientWithCommands; class DBClientWithCommands;
static const unsigned kMaxJsFileLength = std::numeric_limits<unsigned>:
:max() - 1;
struct JSFile { struct JSFile {
const char* name; const char* name;
const StringData& source; const StringData& source;
}; };
class Scope : boost::noncopyable { class Scope : boost::noncopyable {
public: public:
Scope(); Scope();
virtual ~Scope(); virtual ~Scope();
virtual void reset() = 0; virtual void reset() = 0;
virtual void init(const BSONObj* data) = 0; virtual void init(const BSONObj* data) = 0;
void init(const char* data) { void init(const char* data) {
BSONObj o(data); BSONObj o(data);
init(&o); init(&o);
} }
virtual void localConnect(const char* dbName) = 0; virtual void localConnect(const char* dbName) = 0;
virtual void externalSetup() = 0; virtual void externalSetup() = 0;
virtual void setLocalDB(const string& localDBName) { _localDBName = localDBName; }
virtual BSONObj getObject(const char* field) = 0; virtual BSONObj getObject(const char* field) = 0;
virtual string getString(const char* field) = 0; virtual string getString(const char* field) = 0;
virtual bool getBoolean(const char* field) = 0; virtual bool getBoolean(const char* field) = 0;
virtual double getNumber(const char* field) = 0; virtual double getNumber(const char* field) = 0;
virtual int getNumberInt(const char* field) { return (int)getNumber (field); } virtual int getNumberInt(const char* field) { return (int)getNumber (field); }
virtual long long getNumberLongLong(const char* field) { virtual long long getNumberLongLong(const char* field) {
return static_cast<long long>(getNumber(field)); return static_cast<long long>(getNumber(field));
} }
virtual void setElement(const char* field, const BSONElement& e) = 0; virtual void setElement(const char* field, const BSONElement& e) = 0;
skipping to change at line 76 skipping to change at line 75
virtual int type(const char* field) = 0; virtual int type(const char* field) = 0;
virtual void append(BSONObjBuilder& builder, const char* fieldName, const char* scopeName); virtual void append(BSONObjBuilder& builder, const char* fieldName, const char* scopeName);
virtual void rename(const char* from, const char* to) = 0; virtual void rename(const char* from, const char* to) = 0;
virtual string getError() = 0; virtual string getError() = 0;
virtual bool hasOutOfMemoryException() = 0; virtual bool hasOutOfMemoryException() = 0;
virtual void installBenchRun();
virtual bool isKillPending() const = 0; virtual bool isKillPending() const = 0;
virtual void gc() = 0; virtual void gc() = 0;
virtual ScriptingFunction createFunction(const char* code); virtual ScriptingFunction createFunction(const char* code);
/** /**
* @return 0 on success * @return 0 on success
*/ */
int invoke(const char* code, const BSONObj* args, const BSONObj* re cv, int timeoutMs = 0); int invoke(const char* code, const BSONObj* args, const BSONObj* re cv, int timeoutMs = 0);
skipping to change at line 126 skipping to change at line 127
void execSetup(const JSFile& file) { void execSetup(const JSFile& file) {
execSetup(file.source, file.name); execSetup(file.source, file.name);
} }
virtual bool execFile(const string& filename, bool printResult, boo l reportError, virtual bool execFile(const string& filename, bool printResult, boo l reportError,
int timeoutMs = 0); int timeoutMs = 0);
void execCoreFiles(); void execCoreFiles();
void loadStored(bool ignoreNotConnected = false); virtual void loadStored(bool ignoreNotConnected = false);
/** /**
* if any changes are made to .system.js, call this * if any changes are made to .system.js, call this
* right now its just global - slightly inefficient, but a lot simp ler * right now its just global - slightly inefficient, but a lot simp ler
*/ */
static void storedFuncMod(); static void storedFuncMod();
static void validateObjectIdString(const string& str); static void validateObjectIdString(const string& str);
/** increments the number of times a scope was used */ /** increments the number of times a scope was used */
void incTimeUsed() { ++_numTimeUsed; } void incTimeUsed() { ++_numTimeUsed; }
/** gets the number of times a scope was used */ /** gets the number of times a scope was used */
int getTimeUsed() { return _numTimeUsed; } int getTimeUsed() { return _numTimeUsed; }
/** return true if last invoke() return'd native code */
virtual bool isLastRetNativeCode() { return _lastRetIsNativeCode; }
class NoDBAccess { class NoDBAccess {
Scope* _s; Scope* _s;
public: public:
NoDBAccess(Scope* s) : _s(s) { NoDBAccess(Scope* s) : _s(s) {
} }
~NoDBAccess() { ~NoDBAccess() {
_s->rename("____db____", "db"); _s->rename("____db____", "db");
} }
}; };
NoDBAccess disableDBAccess(const char* why) { NoDBAccess disableDBAccess(const char* why) {
rename("db", "____db____"); rename("db", "____db____");
return NoDBAccess(this); return NoDBAccess(this);
} }
protected: protected:
virtual ScriptingFunction _createFunction(const char* code) = 0; friend class PooledScope;
virtual FunctionCacheMap& getFunctionCache() { return _cachedFuncti
ons; }
virtual ScriptingFunction _createFunction(const char* code,
ScriptingFunction functio
nNumber = 0) = 0;
string _localDBName; string _localDBName;
long long _loadedVersion; long long _loadedVersion;
set<string> _storedNames; set<string> _storedNames;
static long long _lastVersion; static long long _lastVersion;
map<string, ScriptingFunction> _cachedFunctions; FunctionCacheMap _cachedFunctions;
int _numTimeUsed; int _numTimeUsed;
bool _lastRetIsNativeCode; // v8 only: set to true if eval'd script returns a native func
}; };
class ScriptEngine : boost::noncopyable { class ScriptEngine : boost::noncopyable {
public: public:
ScriptEngine(); ScriptEngine();
virtual ~ScriptEngine(); virtual ~ScriptEngine();
virtual Scope* newScope() { virtual Scope* newScope() {
return createScope(); return createScope();
} }
skipping to change at line 186 skipping to change at line 194
virtual void runTest() = 0; virtual void runTest() = 0;
virtual bool utf8Ok() const = 0; virtual bool utf8Ok() const = 0;
static void setup(); static void setup();
/** gets a scope from the pool or a new one if pool is empty /** gets a scope from the pool or a new one if pool is empty
* @param pool An identifier for the pool, usually the db name * @param pool An identifier for the pool, usually the db name
* @return the scope * @return the scope
*/ */
auto_ptr<Scope> getPooledScope(const string& pool); auto_ptr<Scope> getPooledScope(const string& pool, const string& sc opeType);
/** /**
* call this method to release some JS resources when a thread is d one * call this method to release some JS resources when a thread is d one
*/ */
void threadDone(); void threadDone();
void setScopeInitCallback(void (*func)(Scope&)) { _scopeInitCallbac k = func; } void setScopeInitCallback(void (*func)(Scope&)) { _scopeInitCallbac k = func; }
static void setConnectCallback(void (*func)(DBClientWithCommands&)) { static void setConnectCallback(void (*func)(DBClientWithCommands&)) {
_connectCallback = func; _connectCallback = func;
} }
 End of changes. 10 change blocks. 
8 lines changed or deleted 17 lines changed or added


 engine_spidermonkey_internal.h   engine_spidermonkey_internal.h 
skipping to change at line 228 skipping to change at line 228
void setNumber( const char *field , double val ); void setNumber( const char *field , double val );
void setString( const char *field , const char * val ); void setString( const char *field , const char * val );
void setObject( const char *field , const BSONObj& obj , bool readO nly ); void setObject( const char *field , const BSONObj& obj , bool readO nly );
void setBoolean( const char *field , bool val ); void setBoolean( const char *field , bool val );
void setThis( const BSONObj * obj ); void setThis( const BSONObj * obj );
void setFunction( const char *field , const char * code ); void setFunction( const char *field , const char * code );
void rename( const char * from , const char * to ); void rename( const char * from , const char * to );
// ---- functions ----- // ---- functions -----
ScriptingFunction _createFunction( const char * code ); ScriptingFunction _createFunction(const char* code, ScriptingFuncti on functionNumber);
struct TimeoutSpec { struct TimeoutSpec {
boost::posix_time::ptime start; boost::posix_time::ptime start;
boost::posix_time::time_duration timeout; boost::posix_time::time_duration timeout;
int count; int count;
}; };
// should not generate exceptions, as those can be caught in // should not generate exceptions, as those can be caught in
// javascript code; returning false without an exception exits // javascript code; returning false without an exception exits
// immediately // immediately
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 engine_v8.h   engine_v8.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 <v8.h> #include <v8.h>
#include <vector> #include <vector>
#include "mongo/scripting/engine.h"
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/client/dbclientinterface.h"
#include "mongo/client/dbclientcursor.h"
#include "mongo/scripting/engine.h"
#include "mongo/scripting/v8_deadline_monitor.h"
#include "mongo/scripting/v8_profiler.h"
/** /**
* V8_SIMPLE_HEADER must be placed in any function called from a public API * V8_SIMPLE_HEADER must be placed in any function called from a public API
* that work with v8 handles (and/or must be within the V8Scope's isolate * that work with v8 handles (and/or must be within the V8Scope's isolate
* and context). Be sure to close the handle_scope if returning a v8::Hand le! * and context). Be sure to close the handle_scope if returning a v8::Hand le!
*/ */
#define V8_SIMPLE_HEADER \ #define V8_SIMPLE_HEADER \
v8::Locker v8lock(_isolate); /* acquire isolate lock */ \ v8::Locker v8lock(_isolate); /* acquire isolate lock */ \
v8::Isolate::Scope iscope(_isolate); /* enter the isolate; exit wh en out of scope */ \ v8::Isolate::Scope iscope(_isolate); /* enter the isolate; exit wh en out of scope */ \
v8::HandleScope handle_scope; /* make the current scope own local handles */ \ v8::HandleScope handle_scope; /* make the current scope own local handles */ \
v8::Context::Scope context_scope(_context); /* enter the context; e xit when out of scope */ v8::Context::Scope context_scope(_context); /* enter the context; e xit when out of scope */
namespace mongo { namespace mongo {
class V8ScriptEngine; class V8ScriptEngine;
class V8Scope; class V8Scope;
class BSONHolder;
typedef v8::Handle<v8::Value> (*v8Function)(V8Scope* scope, const v8::A rguments& args); typedef v8::Handle<v8::Value> (*v8Function)(V8Scope* scope, const v8::A rguments& args);
class BSONHolder { /**
* The ObjTracker class keeps track of all weakly referenced v8 objects
. This is
* required because v8 does not invoke the WeakReferenceCallback when s
hutting down
* the context/isolate. To track a new object, add an ObjTracker<MyObj
Type> member
* variable to the V8Scope (if one does not already exist for that type
). Instead
* of calling v8::Persistent::MakeWeak() directly, simply invoke track(
) with the
* persistent handle and the pointer to be freed.
*/
template <typename _ObjType>
class ObjTracker {
public: public:
BSONHolder(BSONObj obj) { /** Track an object to be freed when it is no longer referenced in
_obj = obj.getOwned(); JavaScript.
_modified = false; * @param instanceHandle persistent handle to the weakly referenc
v8::V8::AdjustAmountOfExternalAllocatedMemory(_obj.objsize()); ed object
* @param rawData pointer to the object instance
*/
void track(v8::Persistent<v8::Value> instanceHandle, _ObjType* inst
ance) {
TrackedPtr* collectionHandle = new TrackedPtr(instance, this);
instanceHandle.MakeWeak(collectionHandle, deleteOnCollect);
} }
~BSONHolder() { /**
v8::V8::AdjustAmountOfExternalAllocatedMemory(-_obj.objsize()); * Free any remaining objects which are being tracked. Invoked whe
n
* the V8Scope is destructed.
*/
~ObjTracker() {
if (!_container.empty())
LOG(1) << "freeing " << _container.size() << " uncollected
"
<< typeid(_ObjType).name() << " objects" << endl;
typename set<_ObjType*>::iterator it = _container.begin();
while (it != _container.end()) {
delete *it;
_container.erase(it++);
}
} }
BSONObj _obj; private:
bool _modified; /**
list<string> _extra; * Simple struct which contains a pointer to the tracked object, an
set<string> _removed; d a pointer
* to the ObjTracker which owns it. This is the argument supplied
to v8's
* WeakReferenceCallback and MakeWeak().
*/
struct TrackedPtr {
public:
TrackedPtr(_ObjType* instance, ObjTracker<_ObjType>* tracker) :
_objPtr(instance),
_tracker(tracker) { }
_ObjType* _objPtr;
ObjTracker<_ObjType>* _tracker;
};
/**
* v8 callback for weak persistent handles that have been marked fo
r removal by the
* garbage collector. Signature conforms to v8's WeakReferenceCall
back.
* @param instanceHandle persistent handle to the weakly referenc
ed object
* @param rawData pointer to the TrackedPtr instance
*/
static void deleteOnCollect(v8::Persistent<v8::Value> instanceHandl
e, void* rawData) {
TrackedPtr* trackedPtr = static_cast<TrackedPtr*>(rawData);
trackedPtr->_tracker->_container.erase(trackedPtr->_objPtr);
delete trackedPtr->_objPtr;
delete trackedPtr;
instanceHandle.Dispose();
}
// container for all instances of the tracked _ObjType
set<_ObjType*> _container;
}; };
/** /**
* A V8Scope represents a unit of javascript execution environment; spe cifically a single * A V8Scope represents a unit of javascript execution environment; spe cifically a single
* isolate and a single context executing in a single mongo thread. A V8Scope can be reused * isolate and a single context executing in a single mongo thread. A V8Scope can be reused
* in another thread only after reset() has been called. * in another thread only after reset() has been called.
* *
* NB: * NB:
* - v8 objects/handles/etc. cannot be shared between V8Scopes * - v8 objects/handles/etc. cannot be shared between V8Scopes
* - in mongod, each scope is associated with an opId (for KillOp sup port) * - in mongod, each scope is associated with an opId (for KillOp sup port)
skipping to change at line 94 skipping to change at line 148
virtual void reset(); virtual void reset();
/** /**
* Terminate this scope * Terminate this scope
*/ */
virtual void kill(); virtual void kill();
/** check if there is a pending killOp request */ /** check if there is a pending killOp request */
bool isKillPending() const; bool isKillPending() const;
/**
* Connect to a local database, create a Mongo object instance, and
load any
* server-side js into the global object
*/
virtual void localConnect(const char* dbName); virtual void localConnect(const char* dbName);
virtual void externalSetup(); virtual void externalSetup();
virtual void installDBAccess();
virtual void installBSONTypes();
virtual string getError() { return _error; } virtual string getError() { return _error; }
virtual bool hasOutOfMemoryException(); virtual bool hasOutOfMemoryException();
/** /**
* Run the garbage collector on this scope (native function). @see GCV8 for the * Run the garbage collector on this scope (native function). @see GCV8 for the
* javascript binding version. * javascript binding version.
*/ */
void gc(); void gc();
skipping to change at line 146 skipping to change at line 208
bool reportError, bool assertOnError, int timeout Ms); bool reportError, bool assertOnError, int timeout Ms);
// functions to create v8 object and function templates // functions to create v8 object and function templates
virtual void injectNative(const char* field, NativeFunction func, v oid* data = 0); virtual void injectNative(const char* field, NativeFunction func, v oid* data = 0);
void injectNative(const char* field, NativeFunction func, v8::Handl e<v8::Object>& obj, void injectNative(const char* field, NativeFunction func, v8::Handl e<v8::Object>& obj,
void* data = 0); void* data = 0);
void injectV8Function(const char* field, v8Function func); void injectV8Function(const char* field, v8Function func);
void injectV8Function(const char* field, v8Function func, v8::Handl e<v8::Object>& obj); void injectV8Function(const char* field, v8Function func, v8::Handl e<v8::Object>& obj);
void injectV8Function(const char* field, v8Function func, v8::Handl e<v8::Template>& t); void injectV8Function(const char* field, v8Function func, v8::Handl e<v8::Template>& t);
v8::Handle<v8::FunctionTemplate> createV8Function(v8Function func); v8::Handle<v8::FunctionTemplate> createV8Function(v8Function func);
virtual ScriptingFunction _createFunction(const char* code); virtual ScriptingFunction _createFunction(const char* code,
v8::Local<v8::Function> __createFunction(const char* code); ScriptingFunction functio
nNumber = 0);
v8::Local<v8::Function> __createFunction(const char* code,
ScriptingFunction function
Number = 0);
/** /**
* Convert BSON types to v8 Javascript types * Convert BSON types to v8 Javascript types
*/ */
v8::Local<v8::Object> mongoToV8(const mongo::BSONObj& m, bool array = 0, v8::Local<v8::Object> mongoToV8(const mongo::BSONObj& m, bool array = 0,
bool readOnly = false); bool readOnly = false);
v8::Persistent<v8::Object> mongoToLZV8(const mongo::BSONObj& m, boo l readOnly = false); v8::Persistent<v8::Object> mongoToLZV8(const mongo::BSONObj& m, boo l readOnly = false);
v8::Handle<v8::Value> mongoToV8Element(const BSONElement& f, bool r eadOnly = false); v8::Handle<v8::Value> mongoToV8Element(const BSONElement& f, bool r eadOnly = false);
/** /**
skipping to change at line 183 skipping to change at line 247
v8::Handle<v8::Value> value, v8::Handle<v8::Value> value,
BSONObj* originalParent); BSONObj* originalParent);
void v8ToMongoNumberLong(BSONObjBuilder& b, void v8ToMongoNumberLong(BSONObjBuilder& b,
const string& elementName, const string& elementName,
v8::Handle<v8::Object> obj); v8::Handle<v8::Object> obj);
void v8ToMongoInternal(BSONObjBuilder& b, void v8ToMongoInternal(BSONObjBuilder& b,
const string& elementName, const string& elementName,
v8::Handle<v8::Object> obj); v8::Handle<v8::Object> obj);
void v8ToMongoRegex(BSONObjBuilder& b, void v8ToMongoRegex(BSONObjBuilder& b,
const string& elementName, const string& elementName,
string& regex); v8::Handle<v8::Object> v8Regex);
void v8ToMongoDBRef(BSONObjBuilder& b, void v8ToMongoDBRef(BSONObjBuilder& b,
const string& elementName, const string& elementName,
v8::Handle<v8::Object> obj); v8::Handle<v8::Object> obj);
void v8ToMongoBinData(BSONObjBuilder& b, void v8ToMongoBinData(BSONObjBuilder& b,
const string& elementName, const string& elementName,
v8::Handle<v8::Object> obj); v8::Handle<v8::Object> obj);
void v8ToMongoObjectID(BSONObjBuilder& b, void v8ToMongoObjectID(BSONObjBuilder& b,
const string& elementName, const string& elementName,
v8::Handle<v8::Object> obj); v8::Handle<v8::Object> obj);
v8::Function* getNamedCons(const char* name); v8::Function* getNamedCons(const char* name);
v8::Function* getObjectIdCons(); v8::Function* getObjectIdCons();
v8::Local<v8::Value> newId(const OID& id); v8::Local<v8::Value> newId(const OID& id);
/** /**
* GC callback for weak references to BSON objects (via BSONHolder) * Convert a JavaScript exception to a stl string. Requires
* access to the V8Scope instance to report source context informat
ion.
*/ */
v8::Persistent<v8::Object> wrapBSONObject(v8::Local<v8::Object> obj std::string v8ExceptionToSTLString(const v8::TryCatch* try_catch);
, BSONHolder* data);
v8::Persistent<v8::Object> wrapArrayObject(v8::Local<v8::Object> ob
j, char* data);
/** /**
* Get a V8 string from the scope's cache, creating one if needed ( * GC callback for weak references to BSON objects (via BSONHolder)
NOTE: this may be
* dangerous due to use in multiple threads without changing the v8
Locker)
*/ */
v8::Handle<v8::String> getV8Str(string str); v8::Persistent<v8::Object> wrapBSONObject(v8::Local<v8::Object> obj , BSONHolder* data);
/** /**
* Create a V8 string with a local handle * Create a V8 string with a local handle
*/ */
inline v8::Handle<v8::String> getLocalV8Str(string str) { static inline v8::Handle<v8::String> v8StringData(StringData str) {
return v8::String::New(str.c_str()); return v8::String::New(str.rawData());
} }
/** /**
* Get the isolate this scope belongs to (can be called from any th read, but v8 requires * Get the isolate this scope belongs to (can be called from any th read, but v8 requires
* the new thread enter the isolate and context. Only one thread can enter the isolate. * the new thread enter the isolate and context. Only one thread can enter the isolate.
*/ */
v8::Isolate* getIsolate() { return _isolate; } v8::Isolate* getIsolate() { return _isolate; }
/** /**
* Get the JS context this scope executes within. * Get the JS context this scope executes within.
*/ */
v8::Persistent<v8::Context> getContext() { return _context; } v8::Persistent<v8::Context> getContext() { return _context; }
/** ObjTracker<BSONHolder> bsonHolderTracker;
* Static v8 strings for various identifiers ObjTracker<DBClientWithCommands> dbClientWithCommandsTracker;
*/ ObjTracker<DBClientBase> dbClientBaseTracker;
v8::Handle<v8::String> V8STR_CONN; ObjTracker<DBClientCursor> dbClientCursorTracker;
v8::Handle<v8::String> V8STR_ID;
v8::Handle<v8::String> V8STR_LENGTH;
v8::Handle<v8::String> V8STR_LEN;
v8::Handle<v8::String> V8STR_TYPE;
v8::Handle<v8::String> V8STR_ISOBJECTID;
v8::Handle<v8::String> V8STR_NATIVE_FUNC;
v8::Handle<v8::String> V8STR_NATIVE_DATA;
v8::Handle<v8::String> V8STR_V8_FUNC;
v8::Handle<v8::String> V8STR_RETURN;
v8::Handle<v8::String> V8STR_ARGS;
v8::Handle<v8::String> V8STR_T;
v8::Handle<v8::String> V8STR_I;
v8::Handle<v8::String> V8STR_EMPTY;
v8::Handle<v8::String> V8STR_MINKEY;
v8::Handle<v8::String> V8STR_MAXKEY;
v8::Handle<v8::String> V8STR_NUMBERLONG;
v8::Handle<v8::String> V8STR_NUMBERINT;
v8::Handle<v8::String> V8STR_DBPTR;
v8::Handle<v8::String> V8STR_BINDATA;
v8::Handle<v8::String> V8STR_WRAPPER;
v8::Handle<v8::String> V8STR_RO;
v8::Handle<v8::String> V8STR_FULLNAME;
v8::Handle<v8::String> V8STR_BSON;
private: private:
/** /**
* Trampoline to call a c++ function with a specific signature (V8S cope*, v8::Arguments&). * Trampoline to call a c++ function with a specific signature (V8S cope*, v8::Arguments&).
* Handles interruption, exceptions, etc. * Handles interruption, exceptions, etc.
*/ */
static v8::Handle<v8::Value> v8Callback(const v8::Arguments& args); static v8::Handle<v8::Value> v8Callback(const v8::Arguments& args);
/** /**
skipping to change at line 280 skipping to change at line 320
static v8::Handle<v8::Value> nativeCallback(V8Scope* scope, const v 8::Arguments& args); static v8::Handle<v8::Value> nativeCallback(V8Scope* scope, const v 8::Arguments& args);
/** /**
* v8-specific implementations of basic global functions * v8-specific implementations of basic global functions
*/ */
static v8::Handle<v8::Value> load(V8Scope* scope, const v8::Argumen ts& args); static v8::Handle<v8::Value> load(V8Scope* scope, const v8::Argumen ts& args);
static v8::Handle<v8::Value> Print(V8Scope* scope, const v8::Argume nts& args); static v8::Handle<v8::Value> Print(V8Scope* scope, const v8::Argume nts& args);
static v8::Handle<v8::Value> Version(V8Scope* scope, const v8::Argu ments& args); static v8::Handle<v8::Value> Version(V8Scope* scope, const v8::Argu ments& args);
static v8::Handle<v8::Value> GCV8(V8Scope* scope, const v8::Argumen ts& args); static v8::Handle<v8::Value> GCV8(V8Scope* scope, const v8::Argumen ts& args);
static v8::Handle<v8::Value> startCpuProfiler(V8Scope* scope, const
v8::Arguments& args);
static v8::Handle<v8::Value> stopCpuProfiler(V8Scope* scope, const
v8::Arguments& args);
static v8::Handle<v8::Value> getCpuProfile(V8Scope* scope, const v8
::Arguments& args);
/** Signal that this scope has entered a native (C++) execution con text. /** Signal that this scope has entered a native (C++) execution con text.
* @return false if execution has been interrupted * @return false if execution has been interrupted
*/ */
bool nativePrologue(); bool nativePrologue();
/** Signal that this scope has completed native execution and is re turning to v8. /** Signal that this scope has completed native execution and is re turning to v8.
* @return false if execution has been interrupted * @return false if execution has been interrupted
*/ */
bool nativeEpilogue(); bool nativeEpilogue();
skipping to change at line 303 skipping to change at line 347
* be supported. * be supported.
*/ */
void registerOpId(); void registerOpId();
/** /**
* Unregister this scope with the mongo op id. * Unregister this scope with the mongo op id.
*/ */
void unregisterOpId(); void unregisterOpId();
/** /**
* Creates a new instance of the MinKey object
*/
v8::Local<v8::Object> newMinKeyInstance();
/**
* Creates a new instance of the MaxKey object
*/
v8::Local<v8::Object> newMaxKeyInstance();
/**
* Create a new function; primarily used for BSON/V8 conversion. * Create a new function; primarily used for BSON/V8 conversion.
*/ */
v8::Local<v8::Value> newFunction(const char *code); v8::Local<v8::Value> newFunction(const char *code);
template <typename _HandleType>
bool checkV8ErrorState(const _HandleType& resultHandle,
const v8::TryCatch& try_catch,
bool reportError = true,
bool assertOnError = true);
V8ScriptEngine* _engine; V8ScriptEngine* _engine;
v8::Persistent<v8::Context> _context; v8::Persistent<v8::Context> _context;
v8::Persistent<v8::Object> _global; v8::Persistent<v8::Object> _global;
string _error; string _error;
vector<v8::Persistent<v8::Value> > _funcs; vector<v8::Persistent<v8::Value> > _funcs;
enum ConnectState { NOT, LOCAL, EXTERNAL }; enum ConnectState { NOT, LOCAL, EXTERNAL };
ConnectState _connectState; ConnectState _connectState;
std::map <string, v8::Persistent<v8::String> > _strCache;
v8::Persistent<v8::FunctionTemplate> lzFunctionTemplate; v8::Persistent<v8::FunctionTemplate> lzFunctionTemplate;
v8::Persistent<v8::ObjectTemplate> lzObjectTemplate; v8::Persistent<v8::ObjectTemplate> lzObjectTemplate;
v8::Persistent<v8::ObjectTemplate> roObjectTemplate; v8::Persistent<v8::ObjectTemplate> roObjectTemplate;
v8::Persistent<v8::ObjectTemplate> lzArrayTemplate; v8::Persistent<v8::ObjectTemplate> lzArrayTemplate;
v8::Persistent<v8::ObjectTemplate> internalFieldObjects; v8::Persistent<v8::ObjectTemplate> internalFieldObjects;
v8::Isolate* _isolate; v8::Isolate* _isolate;
V8CpuProfiler _cpuProfiler;
mongo::mutex _interruptLock; // protects interruption-related flags mongo::mutex _interruptLock; // protects interruption-related flags
bool _inNativeExecution; // protected by _interruptLock bool _inNativeExecution; // protected by _interruptLock
bool _pendingKill; // protected by _interruptLock bool _pendingKill; // protected by _interruptLock
int _opId; // op id for this scope int _opId; // op id for this scope
}; };
class V8ScriptEngine : public ScriptEngine { class V8ScriptEngine : public ScriptEngine {
public: public:
V8ScriptEngine(); V8ScriptEngine();
skipping to change at line 361 skipping to change at line 420
/** /**
* Interrupt all v8 contexts (and isolates). @see interrupt(). * Interrupt all v8 contexts (and isolates). @see interrupt().
*/ */
virtual void interruptAll(); virtual void interruptAll();
private: private:
friend class V8Scope; friend class V8Scope;
std::string printKnownOps_inlock(); std::string printKnownOps_inlock();
/**
* Get the deadline monitor instance for the v8 ScriptEngine
*/
DeadlineMonitor<V8Scope>* getDeadlineMonitor() { return &_deadlineM
onitor; }
typedef map<unsigned, V8Scope*> OpIdToScopeMap; typedef map<unsigned, V8Scope*> OpIdToScopeMap;
mongo::mutex _globalInterruptLock; // protects map of all operatio n ids -> scope mongo::mutex _globalInterruptLock; // protects map of all operatio n ids -> scope
OpIdToScopeMap _opToScopeMap; // map of mongo op ids to scope s (protected by OpIdToScopeMap _opToScopeMap; // map of mongo op ids to scope s (protected by
// _globalInterruptLock). // _globalInterruptLock).
DeadlineMonitor<V8Scope> _deadlineMonitor;
};
class BSONHolder {
MONGO_DISALLOW_COPYING(BSONHolder);
public:
explicit BSONHolder(BSONObj obj) :
_scope(NULL),
_obj(obj.getOwned()),
_modified(false) {
// give hint v8's GC
v8::V8::AdjustAmountOfExternalAllocatedMemory(_obj.objsize());
}
~BSONHolder() {
if (_scope && _scope->getIsolate())
// if v8 is still up, send hint to GC
v8::V8::AdjustAmountOfExternalAllocatedMemory(-_obj.objsize
());
}
V8Scope* _scope;
BSONObj _obj;
bool _modified;
list<string> _extra;
set<string> _removed;
}; };
/**
* Check for an error condition (e.g. empty handle, JS exception, OOM)
after executing
* a v8 operation.
* @resultHandle handle storing the result of the preceeding v8
operation
* @try_catch the active v8::TryCatch exception handler
* @param reportError if true, log an error message
* @param assertOnError if true, throw an exception if an error is det
ected
* if false, return value indicates error state
* @return true if an error was detected and assertOnError is set to fa
lse
* false if no error was detected
*/
template <typename _HandleType>
bool V8Scope::checkV8ErrorState(const _HandleType& resultHandle,
const v8::TryCatch& try_catch,
bool reportError,
bool assertOnError) {
bool haveError = false;
if (try_catch.HasCaught() && try_catch.CanContinue()) {
// normal JS exception
_error = string("JavaScript execution failed: ") + v8ExceptionT
oSTLString(&try_catch);
haveError = true;
}
else if (hasOutOfMemoryException()) {
// out of memory exception (treated as terminal)
_error = "JavaScript execution failed -- v8 is out of memory";
haveError = true;
}
else if (resultHandle.IsEmpty() || try_catch.HasCaught()) {
// terminal exception (due to empty handle, termination, etc.)
_error = "JavaScript execution failed";
haveError = true;
}
if (haveError) {
if (reportError)
log() << _error << endl;
if (assertOnError)
uasserted(16722, _error);
return true;
}
return false;
}
extern ScriptEngine* globalScriptEngine; extern ScriptEngine* globalScriptEngine;
} }
 End of changes. 25 change blocks. 
57 lines changed or deleted 215 lines changed or added


 field_parser-inl.h   field_parser-inl.h 
skipping to change at line 26 skipping to change at line 26
#include "mongo/s/field_parser.h" #include "mongo/s/field_parser.h"
#include "mongo/util/mongoutils/str.h" #include "mongo/util/mongoutils/str.h"
namespace mongo { namespace mongo {
using mongoutils::str::stream; using mongoutils::str::stream;
// Extracts an array into a vector // Extracts an array into a vector
template<typename T> template<typename T>
bool FieldParser::extract(BSONObj doc, FieldParser::FieldState FieldParser::extract(BSONObj doc,
const BSONField<vector<T> >& field, const BSONField<vector<T> >& field,
const vector<T>& def,
vector<T>* out, vector<T>* out,
string* errMsg) string* errMsg)
{ {
BSONElement elem = doc[field.name()]; BSONElement elem = doc[field.name()];
if (elem.eoo()) { if (elem.eoo()) {
*out = def; if (field.hasDefault()) {
return true; *out = field.getDefault();
return FIELD_DEFAULT;
}
else {
return FIELD_NONE;
}
} }
if (elem.type() == Array) { if (elem.type() == Array) {
BSONArray arr = BSONArray(elem.embeddedObject()); BSONArray arr = BSONArray(elem.embeddedObject());
string elErrMsg; string elErrMsg;
// Append all the new elements to the end of the vector // Append all the new elements to the end of the vector
size_t initialSize = out->size(); size_t initialSize = out->size();
out->resize(initialSize + arr.nFields()); out->resize(initialSize + arr.nFields());
int i = 0; int i = 0;
BSONObjIterator objIt(arr); BSONObjIterator objIt(arr);
while (objIt.more()) { while (objIt.more()) {
BSONElement next = objIt.next(); BSONElement next = objIt.next();
BSONField<T> fieldFor(next.fieldName()); BSONField<T> fieldFor(next.fieldName(), out->at(initialSize + i));
if (!FieldParser::extract(arr, if (!FieldParser::extract(arr,
fieldFor, fieldFor,
out->at(initialSize + i),
&out->at(initialSize + i), &out->at(initialSize + i),
&elErrMsg)) &elErrMsg))
{ {
if (errMsg) { if (errMsg) {
*errMsg = stream() << "error parsing element " << i << " of field " *errMsg = stream() << "error parsing element " << i << " of field "
<< field() << causedBy(elErrMsg) ; << field() << causedBy(elErrMsg) ;
} }
return false; return FIELD_INVALID;
} }
i++; i++;
} }
return true; return FIELD_SET;
} }
if (errMsg) { if (errMsg) {
*errMsg = stream() << "wrong type for '" << field() << "' field , expected " *errMsg = stream() << "wrong type for '" << field() << "' field , expected "
<< "vector array" << ", found " << doc[field .name()].toString(); << "vector array" << ", found " << doc[field .name()].toString();
} }
return false; return FIELD_INVALID;
} }
// Extracts an object into a map // Extracts an object into a map
template<typename K, typename T> template<typename K, typename T>
bool FieldParser::extract(BSONObj doc, FieldParser::FieldState FieldParser::extract(BSONObj doc,
const BSONField<map<K, T> >& field, const BSONField<map<K, T> >& field,
const map<K, T>& def,
map<K, T>* out, map<K, T>* out,
string* errMsg) string* errMsg)
{ {
BSONElement elem = doc[field.name()]; BSONElement elem = doc[field.name()];
if (elem.eoo()) { if (elem.eoo()) {
*out = def; if (field.hasDefault()) {
return true; *out = field.getDefault();
return FIELD_DEFAULT;
}
else {
return FIELD_NONE;
}
} }
if (elem.type() == Object) { if (elem.type() == Object) {
BSONObj obj = elem.embeddedObject(); BSONObj obj = elem.embeddedObject();
string elErrMsg; string elErrMsg;
BSONObjIterator objIt(obj); BSONObjIterator objIt(obj);
while (objIt.more()) { while (objIt.more()) {
BSONElement next = objIt.next(); BSONElement next = objIt.next();
BSONField<T> fieldFor(next.fieldName());
T& value = (*out)[next.fieldName()]; T& value = (*out)[next.fieldName()];
if (!FieldParser::extract(obj, fieldFor, value, &value, &el
ErrMsg)) { BSONField<T> fieldFor(next.fieldName(), value);
if (!FieldParser::extract(obj, fieldFor, &value, &elErrMsg)
) {
if (errMsg) { if (errMsg) {
*errMsg = stream() << "error parsing map element " << next.fieldName() *errMsg = stream() << "error parsing map element " << next.fieldName()
<< " of field " << field() << ca usedBy(elErrMsg); << " of field " << field() << ca usedBy(elErrMsg);
} }
return false; return FIELD_INVALID;
} }
} }
return true; return FIELD_SET;
} }
if (errMsg) { if (errMsg) {
*errMsg = stream() << "wrong type for '" << field() << "' field , expected " *errMsg = stream() << "wrong type for '" << field() << "' field , expected "
<< "vector array" << ", found " << doc[field .name()].toString(); << "vector array" << ", found " << doc[field .name()].toString();
} }
return false; return FIELD_INVALID;
} }
} // namespace mongo } // namespace mongo
 End of changes. 16 change blocks. 
20 lines changed or deleted 27 lines changed or added


 field_parser.h   field_parser.h 
skipping to change at line 41 skipping to change at line 41
* 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.
* *
* NOTE ON BSON OWNERSHIP: * NOTE ON BSON OWNERSHIP:
* *
* The caller must assume that this class will point to data insi de 'doc' without * The caller must assume that this class will point to data insi de 'doc' without
* copying it. In practice this means that 'doc' MUST EXIST for a s long as 'out' * copying it. In practice this means that 'doc' MUST EXIST for a s long as 'out'
* stays in scope. * stays in scope.
*/ */
static bool extract(BSONObj doc,
enum FieldState {
// The field is present but has the wrong type
FIELD_INVALID = 0,
// The field is present and has the correct type
FIELD_SET,
// The field is absent in the BSON object but set from default
FIELD_DEFAULT,
// The field is absent and no default was specified
FIELD_NONE
};
static FieldState extract(BSONObj doc,
const BSONField<bool>& field, const BSONField<bool>& field,
bool def,
bool* out, bool* out,
string* errMsg = NULL); string* errMsg = NULL);
static bool extract(BSONObj doc, static FieldState extract(BSONObj doc,
const BSONField<BSONArray>& field, const BSONField<BSONArray>& field,
const BSONArray& def,
BSONArray* out, BSONArray* out,
string* errMsg = NULL); string* errMsg = NULL);
static bool extract(BSONObj doc, static FieldState extract(BSONObj doc,
const BSONField<BSONObj>& field, const BSONField<BSONObj>& field,
const BSONObj& def,
BSONObj* out, BSONObj* out,
string* errMsg = NULL); string* errMsg = NULL);
static bool extract(BSONObj doc, static FieldState extract(BSONObj doc,
const BSONField<Date_t>& field, const BSONField<Date_t>& field,
const Date_t def,
Date_t* out, Date_t* out,
string* errMsg = NULL); string* errMsg = NULL);
static bool extract(BSONObj doc, static FieldState extract(BSONObj doc,
const BSONField<string>& field, const BSONField<string>& field,
const string& def,
string* out, string* out,
string* errMsg = NULL); string* errMsg = NULL);
static bool extract(BSONObj doc, static FieldState extract(BSONObj doc,
const BSONField<OID>& field, const BSONField<OID>& field,
const OID& def,
OID* out, OID* out,
string* errMsg = NULL); string* errMsg = NULL);
static bool extract(BSONObj doc, static FieldState extract(BSONObj doc,
const BSONField<int>& field, const BSONField<int>& field,
const int& def,
int* out, int* out,
string* errMsg = NULL); string* errMsg = NULL);
static bool extract(BSONObj doc, static FieldState extract(BSONObj doc,
const BSONField<long long>& field, const BSONField<long long>& field,
const long long& def,
long long* out, long long* out,
string* errMsg = NULL); string* errMsg = NULL);
/** /**
* The following extractNumber methods do implicit conversion betwe en any numeric type and * The following extractNumber methods do implicit conversion betwe en any numeric type and
* the BSONField type. This can be useful when an exact numeric ty pe is not needed, for * the BSONField type. This can be useful when an exact numeric ty pe is not needed, for
* example if the field is sometimes modified from the shell which can change the type. * example if the field is sometimes modified from the shell which can change the type.
*/ */
static bool extractNumber(BSONObj doc, static FieldState extractNumber(BSONObj doc,
const BSONField<int>& field, const BSONField<int>& field,
const int& def,
int* out, int* out,
string* errMsg = NULL); string* errMsg = NULL);
static bool extractNumber(BSONObj doc, static FieldState extractNumber(BSONObj doc,
const BSONField<long long>& field, const BSONField<long long>& field,
const long long& def,
long long* out, long long* out,
string* errMsg = NULL); string* errMsg = NULL);
/** /**
* The following extract methods are templatized to handle extracti on of vectors and * The following extract methods are templatized to handle extracti on of vectors and
* maps of sub-objects. Keys in the map should be StringData compa tible. * maps of sub-objects. Keys in the map should be StringData compa tible.
* *
* It's possible to nest extraction of vectors and maps to any dept h, i.e: * It's possible to nest extraction of vectors and maps to any dept h, i.e:
* *
* vector<map<string,vector<string> > > val; * vector<map<string,vector<string> > > val;
* FieldParser::extract(doc, field, val, &val); * FieldParser::extract(doc, field, val, &val);
*/ */
template<typename T> template<typename T>
static bool extract(BSONObj doc, static FieldState extract(BSONObj doc,
const BSONField<vector<T> >& field, const BSONField<vector<T> >& field,
const vector<T>& def,
vector<T>* out, vector<T>* out,
string* errMsg = NULL); string* errMsg = NULL);
template<typename K, typename T> template<typename K, typename T>
static bool extract(BSONObj doc, static FieldState extract(BSONObj doc,
const BSONField<map<K, T> >& field, const BSONField<map<K, T> >& field,
const map<K, T>& def,
map<K, T>* out, map<K, T>* out,
string* errMsg = NULL); string* errMsg = NULL);
}; };
} // namespace mongo } // namespace mongo
// Inline functions for templating // Inline functions for templating
#include "field_parser-inl.h" #include "field_parser-inl.h"
 End of changes. 24 change blocks. 
24 lines changed or deleted 27 lines changed or added


 fts_index.h   fts_index.h 
skipping to change at line 63 skipping to change at line 63
}; };
class FTSIndexPlugin : public IndexPlugin { class FTSIndexPlugin : public IndexPlugin {
public: public:
FTSIndexPlugin(); FTSIndexPlugin();
IndexType* generate( const IndexSpec* spec ) const; IndexType* generate( const IndexSpec* spec ) const;
BSONObj adjustIndexSpec( const BSONObj& spec ) const; BSONObj adjustIndexSpec( const BSONObj& spec ) const;
void postBuildHook( const IndexSpec& spec ) const;
}; };
} //namespace fts } //namespace fts
} //namespace mongo } //namespace mongo
 End of changes. 1 change blocks. 
0 lines changed or deleted 2 lines changed or added


 geoparser.h   geoparser.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 "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include <vector> #include <vector>
#include "third_party/s2/s2.h" #include "third_party/s2/s2.h"
#include "mongo/db/geo/shapes.h" #include "mongo/db/geo/shapes.h"
class S2Cap;
class S2Cell; class S2Cell;
class S2Polyline; class S2Polyline;
class S2Polygon; class S2Polygon;
namespace mongo { namespace mongo {
// TODO: move this to geoparser, perhaps? // This class parses geographic data.
// This class parses a subset of GeoJSON and creates S2 shapes from it. // It parses a subset of GeoJSON and creates S2 shapes from it.
// See http://geojson.org/geojson-spec.html for the spec. // See http://geojson.org/geojson-spec.html for the spec.
// //
// This class also parses the ad-hoc geo formats that MongoDB introduce d. // This class also parses the ad-hoc geo formats that MongoDB introduce d.
// //
// The parseFoo methods that return a bool internally call isFoo and re
turn true
// if the foo is parsed correctly.
// The parseFoo methods that do not return a bool assume isFoo is true.
//
// We assume that if you're trying to parse something, you know it's va lid. // We assume that if you're trying to parse something, you know it's va lid.
// This means don't call parsePoint(x) unless you're sure isPoint(x).
// Perhaps there should just be parsePoint that returns bool and calls
isPoint itself?
class GeoParser { class GeoParser {
public: public:
// Try to parse GeoJSON, then try legacy format, return true if eit her succeed. // Try to parse GeoJSON, then try legacy format, return true if eit her succeed.
// These call the various isPoint and parsePoint methods below. // These call the various isPoint and parsePoint methods below.
// You can just use these bool parsePoint(...) methods. // You can just use these bool parsePoint(...) methods.
static bool parsePoint(const BSONObj &obj, S2Point *out); static bool parsePoint(const BSONObj &obj, S2Point *out);
static bool parsePoint(const BSONObj &obj, S2Cell *out); static bool parsePoint(const BSONObj &obj, S2Cell *out);
static bool parsePoint(const BSONObj &obj, Point *out);
// Check to see if it's GeoJSON or if it's legacy geo. // Check to see if it's GeoJSON or if it's legacy geo.
static bool isPoint(const BSONObj &obj); static bool isPoint(const BSONObj &obj);
static bool isGeoJSONPoint(const BSONObj &obj); static bool isGeoJSONPoint(const BSONObj &obj);
static void parseGeoJSONPoint(const BSONObj &obj, S2Point *out); static void parseGeoJSONPoint(const BSONObj &obj, S2Point *out);
static void parseGeoJSONPoint(const BSONObj &obj, S2Cell *out); static void parseGeoJSONPoint(const BSONObj &obj, S2Cell *out);
static void parseGeoJSONPoint(const BSONObj &obj, Point *out);
static bool isLegacyPoint(const BSONObj &obj); static bool isLegacyPoint(const BSONObj &obj);
// Point is the legacy/planar class (2d), S2Point is the future (2d sphere).
static void parseLegacyPoint(const BSONObj &obj, S2Point *out); static void parseLegacyPoint(const BSONObj &obj, S2Point *out);
static void parseLegacyPoint(const BSONObj &obj, Point *out); static void parseLegacyPoint(const BSONObj &obj, Point *out);
static bool parseLineString(const BSONObj &obj, S2Polyline *out); static bool parseLineString(const BSONObj &obj, S2Polyline *out);
static bool isLineString(const BSONObj &obj); static bool isLineString(const BSONObj &obj);
static bool isGeoJSONLineString(const BSONObj &obj); static bool isGeoJSONLineString(const BSONObj &obj);
static void parseGeoJSONLineString(const BSONObj &obj, S2Polyline * out); static void parseGeoJSONLineString(const BSONObj &obj, S2Polyline * out);
// There are no legacy lines.
static bool parsePolygon(const BSONObj &obj, S2Polygon *out); static bool parsePolygon(const BSONObj &obj, S2Polygon *out);
static bool parsePolygon(const BSONObj &obj, Polygon *out);
static bool isPolygon(const BSONObj &obj); static bool isPolygon(const BSONObj &obj);
static bool isGeoJSONPolygon(const BSONObj &obj); static bool isGeoJSONPolygon(const BSONObj &obj);
static bool isLegacyPolygon(const BSONObj &obj); static bool isLegacyPolygon(const BSONObj &obj);
static void parseGeoJSONPolygon(const BSONObj &obj, S2Polygon *out) ; static void parseGeoJSONPolygon(const BSONObj &obj, S2Polygon *out) ;
static void parseLegacyPolygon(const BSONObj &obj, S2Polygon *out);
static void parseLegacyPolygon(const BSONObj &obj, Polygon *out); static void parseLegacyPolygon(const BSONObj &obj, Polygon *out);
// TODO(hk): We could do this in 2dsphere with an S2LatLngRect.
static bool isLegacyBox(const BSONObj &obj); static bool isLegacyBox(const BSONObj &obj);
static void parseLegacyBox(const BSONObj &obj, Box *out); static void parseLegacyBox(const BSONObj &obj, Box *out);
static bool isLegacyCenter(const BSONObj &obj); static bool isLegacyCenter(const BSONObj &obj);
static void parseLegacyCenter(const BSONObj &obj, Point *centerOut, static void parseLegacyCenter(const BSONObj &obj, Circle *out);
double *radiusOut);
static bool isLegacyCenterSphere(const BSONObj &obj);
static void parseLegacyCenterSphere(const BSONObj &obj, S2Cap *out)
;
// Return true if the CRS field is 1. missing, or 2. is well-formed and // Return true if the CRS field is 1. missing, or 2. is well-formed and
// has a datum we accept. Otherwise, return false. // has a datum we accept. Otherwise, return false.
// TODO(hk): If this is ever used anywhere but internally, consider // NOTE(hk): If this is ever used anywhere but internally, consider
// returning states: missing, invalid, unknown, ok, etc. -- whateve r // returning states: missing, invalid, unknown, ok, etc. -- whateve r
// needed. // needed.
static bool crsIsOK(const BSONObj& obj); static bool crsIsOK(const BSONObj& obj);
}; };
} // namespace mongo } // namespace mongo
 End of changes. 14 change blocks. 
12 lines changed or deleted 19 lines changed or added


 gsasl_session.h   gsasl_session.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 "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h" #include "mongo/base/status.h"
#include "mongo/base/string_data.h" #include "mongo/base/string_data.h"
#include "mongo/platform/cstdint.h" // Must be included at all because of SERVER-8086. #include "mongo/platform/cstdint.h" // Must be included before <gsasl.h> b ecause of SERVER-8086
#include <gsasl.h> // Must be included here because of SERVER-8086. #include <gsasl.h> // Must be included after "mongo/platform/cstdint.h" be cause of SERVER-8086.
namespace mongo { namespace mongo {
/** /**
* C++ wrapper around Gsasl_session. * C++ wrapper around Gsasl_session.
*/ */
class GsaslSession { class GsaslSession {
MONGO_DISALLOW_COPYING(GsaslSession); MONGO_DISALLOW_COPYING(GsaslSession);
public: public:
GsaslSession(); GsaslSession();
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 hashindex.h   hashindex.h 
skipping to change at line 90 skipping to change at line 90
/* The input is "obj" which should have a field corresponding to th e hashedfield. /* The input is "obj" which should have a field corresponding to th e hashedfield.
* The output is a BSONObj with a single BSONElement whose value is the hash * The output is a BSONObj with a single BSONElement whose value is the hash
* Eg if this is an index on "a" we have * Eg if this is an index on "a" we have
* obj is {a : 45} --> key becomes {"" : hash(45) } * obj is {a : 45} --> key becomes {"" : hash(45) }
* *
* Limitation: arrays values are not currently supported. This fun ction uasserts * Limitation: arrays values are not currently supported. This fun ction uasserts
* that the value is not an array, and errors out in that case. * that the value is not an array, and errors out in that case.
*/ */
void getKeys( const BSONObj &obj, BSONObjSet &keys ) const; void getKeys( const BSONObj &obj, BSONObjSet &keys ) const;
/* A field missing from a document is represented by the hash value
of a null BSONElement.
*/
BSONElement missingField() const { return _missingKey.firstElement(
); }
/* The newCursor method works for suitable queries by generating a BtreeCursor /* The newCursor method works for suitable queries by generating a BtreeCursor
* using the hash of point-intervals parsed by FieldRangeSet. * using the hash of point-intervals parsed by FieldRangeSet.
* For unsuitable queries it just instantiates a btree cursor over the whole tree * For unsuitable queries it just instantiates a btree cursor over the whole tree
*/ */
shared_ptr<Cursor> newCursor( const BSONObj& query , shared_ptr<Cursor> newCursor( const BSONObj& query ,
const BSONObj& order , int numWanted ) const; const BSONObj& order , int numWanted ) const;
/* Takes a BSONElement, seed and hashVersion, and outputs the /* Takes a BSONElement, seed and hashVersion, and outputs the
* 64-bit hash used for this index * 64-bit hash used for this index
* E.g. if the element is {a : 3} this outputs v1-hash(3) * E.g. if the element is {a : 3} this outputs v1-hash(3)
skipping to change at line 118 skipping to change at line 122
bool scanAndOrderRequired( const BSONObj& query , const BSONObj& or der ) const { bool scanAndOrderRequired( const BSONObj& query , const BSONObj& or der ) const {
return ! order.isEmpty(); return ! order.isEmpty();
} }
private: private:
string _hashedField; string _hashedField;
KeyPattern _keyPattern; KeyPattern _keyPattern;
HashSeed _seed; //defaults to zero if not in the IndexSpec HashSeed _seed; //defaults to zero if not in the IndexSpec
HashVersion _hashVersion; //defaults to zero if not in the IndexSpe c HashVersion _hashVersion; //defaults to zero if not in the IndexSpe c
bool _isSparse; bool _isSparse;
BSONObj _missingKey;
}; };
} }
 End of changes. 2 change blocks. 
0 lines changed or deleted 7 lines changed or added


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


 index_rebuilder.h   index_rebuilder.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/namespace_details.h" #include "mongo/db/namespace_details.h"
#include "mongo/util/background.h"
namespace mongo { namespace mongo {
class IndexRebuilder : public BackgroundJob { class IndexRebuilder {
public: public:
IndexRebuilder(); IndexRebuilder();
std::string name() const; std::string name() const;
void run(); void run();
private: private:
/** /**
* Check each collection in a database to see if it has any in-prog ress index builds that * Check each collection in a database to see if it has any in-prog ress index builds that
* need to be retried. If so, calls retryIndexBuild. * need to be retried. If so, calls retryIndexBuild.
*/ */
void checkDB(const std::string& dbname); void checkDB(const std::string& dbname, bool* firstTime);
/** /**
* Actually retry an index build on a given namespace. * Actually retry an index build on a given namespace.
* @param dbName the name of the database for accessing db.system.i ndexes * @param dbName the name of the database for accessing db.system.i ndexes
* @param nsd the namespace details of the namespace building the i ndex * @param nsd the namespace details of the namespace building the i ndex
* @param index the offset into nsd's index array of the partially- built index * @param index the offset into nsd's index array of the partially- built index
*/ */
void retryIndexBuild(const std::string& dbName, NamespaceDetails* n sd, const int index); void retryIndexBuild(const std::string& dbName, NamespaceDetails* n sd, const int index);
}; };
 End of changes. 3 change blocks. 
3 lines changed or deleted 2 lines changed or added


 indexkey.h   indexkey.h 
skipping to change at line 53 skipping to change at line 53
* done this way so parsing, etc... can be cached * done this way so parsing, etc... can be cached
* so if there is a FTS IndexPlugin, for each index using FTS * so if there is a FTS IndexPlugin, for each index using FTS
* there will be 1 of these, and it can have things pre-parsed, etc... * there will be 1 of these, and it can have things pre-parsed, etc...
*/ */
class IndexType : boost::noncopyable { class IndexType : boost::noncopyable {
public: public:
IndexType( const IndexPlugin * plugin , const IndexSpec * spec ); IndexType( const IndexPlugin * plugin , const IndexSpec * spec );
virtual ~IndexType(); virtual ~IndexType();
virtual void getKeys( const BSONObj &obj, BSONObjSet &keys ) const = 0; virtual void getKeys( const BSONObj &obj, BSONObjSet &keys ) const = 0;
/**
* Returns the element placed in an index key when indexing a field
absent from a document.
* By default this is a null BSONElement.
*/
virtual BSONElement missingField() const;
/* Full semantics of numWanted:
* numWanted == 0 : Return any number of results, but try to return
in batches of 101.
* numWanted == 1 : Return exactly one result.
* numWanted > 1 : Return any number of results, but try to return
in batches of numWanted.
*
* In practice, your cursor can ignore numWanted, as enforcement of
limits is done
* by the caller.
*/
virtual shared_ptr<Cursor> newCursor( const BSONObj& query , const BSONObj& order , int numWanted ) const = 0; virtual shared_ptr<Cursor> newCursor( const BSONObj& query , const BSONObj& order , int numWanted ) const = 0;
/** optional op : changes query to match what's in the index */ /** optional op : changes query to match what's in the index */
virtual BSONObj fixKey( const BSONObj& in ) { return in; } virtual BSONObj fixKey( const BSONObj& in ) { return in; }
/** optional op : compare 2 objects with regards to this index */ /** optional op : compare 2 objects with regards to this index */
virtual int compare( const BSONObj& l , const BSONObj& r ) const; virtual int compare( const BSONObj& l , const BSONObj& r ) const;
/** @return plugin */ /** @return plugin */
const IndexPlugin * getPlugin() const { return _plugin; } const IndexPlugin * getPlugin() const { return _plugin; }
skipping to change at line 104 skipping to change at line 119
virtual IndexType* generate( const IndexSpec * spec ) const = 0; virtual IndexType* generate( const IndexSpec * spec ) const = 0;
string getName() const { return _name; } string getName() const { return _name; }
/** /**
* @return new keyPattern * @return new keyPattern
* if nothing changes, should return keyPattern * if nothing changes, should return keyPattern
*/ */
virtual BSONObj adjustIndexSpec( const BSONObj& spec ) const { retu rn spec; } virtual BSONObj adjustIndexSpec( const BSONObj& spec ) const { retu rn spec; }
/**
* Hook function to run after an index that uses this plugin is bui
lt.
*
* This will be called with an active write context (and lock) on t
he database.
*
* @param spec The IndexSpec of the newly built index.
*/
virtual void postBuildHook( const IndexSpec& spec ) const { }
// ------- static below ------- // ------- static below -------
static IndexPlugin* get( const string& name ) { static IndexPlugin* get( const string& name ) {
if ( ! _plugins ) if ( ! _plugins )
return 0; return 0;
map<string,IndexPlugin*>::iterator i = _plugins->find( name ); map<string,IndexPlugin*>::iterator i = _plugins->find( name );
if ( i == _plugins->end() ) if ( i == _plugins->end() )
return 0; return 0;
return i->second; return i->second;
} }
/** /**
* @param keyPattern { x : "fts" } * @param keyPattern { x : "fts" }
* @return "" or the name * @return "" or the name
*/ */
static string findPluginName( const BSONObj& keyPattern ); static string findPluginName( const BSONObj& keyPattern );
/**
* True if is a regular (non-plugin) index or uses a plugin that ex
isted before 2.4.
* These plugins are grandfathered in and allowed to exist in DBs w
ith
* PDFILE_MINOR_VERSION_22_AND_OLDER
*/
static bool existedBefore24(const string& name) {
return name.empty()
|| name == "2d"
|| name == "geoHaystack"
|| name == "hashed"
;
}
private: private:
string _name; string _name;
static map<string,IndexPlugin*> * _plugins; static map<string,IndexPlugin*> * _plugins;
}; };
/* precomputed details about an index, used for inserting keys on updat es /* precomputed details about an index, used for inserting keys on updat es
stored/cached in NamespaceDetailsTransient, or can be used standalon e stored/cached in NamespaceDetailsTransient, or can be used standalon e
*/ */
class IndexSpec { class IndexSpec {
public: public:
enum PluginRules {
NoPlugins,
RulesFor22, // if !IndexPlugin::existedBefore24() treat as asce
nding
RulesFor24, // allow new plugins but error if unknown
};
BSONObj keyPattern; // e.g., { name : 1 } BSONObj keyPattern; // e.g., { name : 1 }
BSONObj info; // this is the same as IndexDetails::info.obj() BSONObj info; // this is the same as IndexDetails::info.obj()
IndexSpec() IndexSpec()
: _details(0) , _finishedInit(false) { : _details(0) , _finishedInit(false) {
} }
explicit IndexSpec( const BSONObj& k , const BSONObj& m = BSONObj() explicit IndexSpec(const BSONObj& k, const BSONObj& m=BSONObj(),
) PluginRules rules=RulesFor24)
: keyPattern(k) , info(m) , _details(0) , _finishedInit(false) { : keyPattern(k) , info(m) , _details(0) , _finishedInit(false) {
_init(); _init(rules);
} }
/** /**
this is a DiscLoc of an IndexDetails info this is a DiscLoc of an IndexDetails info
should have a key field should have a key field
*/ */
explicit IndexSpec( const DiskLoc& loc ) { explicit IndexSpec(const DiskLoc& loc, PluginRules rules=RulesFor24
reset( loc ); ) {
reset(loc, rules);
} }
void reset( const BSONObj& info ); void reset(const BSONObj& info, PluginRules rules=RulesFor24);
void reset( const DiskLoc& infoLoc ) { reset(infoLoc.obj()); } void reset(const IndexDetails * details); // determines rules based
void reset( const IndexDetails * details ); on pdfile version
void reset(const DiskLoc& infoLoc, PluginRules rules=RulesFor24) {
reset(infoLoc.obj(), rules);
}
void getKeys( const BSONObj &obj, BSONObjSet &keys ) const; void getKeys( const BSONObj &obj, BSONObjSet &keys ) const;
BSONElement missingField() const { return _nullElt; } /**
* Returns the element placed in an index key when indexing a field
absent from a document.
* By default this is a null BSONElement.
*/
BSONElement missingField() const {
if ( _indexType.get() )
return _indexType->missingField();
return _nullElt;
}
string getTypeName() const { string getTypeName() const {
if ( _indexType.get() ) if ( _indexType.get() )
return _indexType->getPlugin()->getName(); return _indexType->getPlugin()->getName();
return ""; return "";
} }
IndexType* getType() const { IndexType* getType() const {
return _indexType.get(); return _indexType.get();
} }
skipping to change at line 203 skipping to change at line 257
BSONElement _nullElt; // jstNull BSONElement _nullElt; // jstNull
BSONObj _undefinedObj; // only used for _undefinedElt BSONObj _undefinedObj; // only used for _undefinedElt
BSONElement _undefinedElt; // undefined BSONElement _undefinedElt; // undefined
int _nFields; // number of fields in the index int _nFields; // number of fields in the index
bool _sparse; // if the index is sparse bool _sparse; // if the index is sparse
shared_ptr<IndexType> _indexType; shared_ptr<IndexType> _indexType;
const IndexDetails * _details; const IndexDetails * _details;
void _init(); void _init(PluginRules rules);
friend class IndexType; friend class IndexType;
friend class KeyGeneratorV0; friend class KeyGeneratorV0;
friend class KeyGeneratorV1; friend class KeyGeneratorV1;
public: public:
bool _finishedInit; bool _finishedInit;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 10 change blocks. 
10 lines changed or deleted 75 lines changed or added


 json.h   json.h 
skipping to change at line 30 skipping to change at line 30
#include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobj.h"
#include "mongo/base/status.h" #include "mongo/base/status.h"
namespace mongo { namespace mongo {
/** /**
* Create a BSONObj from a JSON <http://www.json.org>, * Create a BSONObj from a JSON <http://www.json.org>,
* <http://www.ietf.org/rfc/rfc4627.txt> string. In addition to the JS ON * <http://www.ietf.org/rfc/rfc4627.txt> string. In addition to the JS ON
* extensions extensions described here * extensions extensions described here
* <http://mongodb.onconfluence.com/display/DOCS/Mongo+Extended+JSON>, * <http://dochub.mongodb.org/core/mongodbextendedjson>, this function
this * accepts unquoted field names and allows single quotes to optionally
* function accepts unquoted field names and allows single quotes to be
* optionally be used when specifying field names and string values ins * used when specifying field names and string values instead of double
tead * quotes. JSON unicode escape sequences (of the form \uXXXX) are
* of double quotes. JSON unicode escape sequences (of the form \uXXXX
) are
* converted to utf8. * converted to utf8.
* *
* @throws MsgAssertionException if parsing fails. The message include d with * @throws MsgAssertionException if parsing fails. The message include d with
* this assertion includes the character offset where parsing failed. * this assertion includes the character offset where parsing failed.
*/ */
BSONObj fromjson(const std::string& str); BSONObj fromjson(const std::string& str);
/** @param len will be size of JSON object in text chars. */ /** @param len will be size of JSON object in text chars. */
BSONObj fromjson(const char* str, int* len=NULL); BSONObj fromjson(const char* str, int* len=NULL);
 End of changes. 1 change blocks. 
7 lines changed or deleted 5 lines changed or added


 jsregexp.h   jsregexp.h 
// Copyright 2012 the V8 project authors. All rights reserved. /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// Redistribution and use in source and binary forms, with or without *
// modification, are permitted provided that the following conditions are * ***** BEGIN LICENSE BLOCK *****
// met: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
// *
// * Redistributions of source code must retain the above copyright * The contents of this file are subject to the Mozilla Public License Vers
// notice, this list of conditions and the following disclaimer. ion
// * Redistributions in binary form must reproduce the above * 1.1 (the "License"); you may not use this file except in compliance with
// copyright notice, this list of conditions and the following * the License. You may obtain a copy of the License at
// disclaimer in the documentation and/or other materials provided * http://www.mozilla.org/MPL/
// with the distribution. *
// * Neither the name of Google Inc. nor the names of its * Software distributed under the License is distributed on an "AS IS" basi
// contributors may be used to endorse or promote products derived s,
// from this software without specific prior written permission. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// * for the specific language governing rights and limitations under the
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * License.
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * The Original Code is Mozilla Communicator client code, released
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * March 31, 1998.
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * The Initial Developer of the Original Code is
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * Netscape Communications Corporation.
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * Portions created by the Initial Developer are Copyright (C) 1998
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * the Initial Developer. All Rights Reserved.
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * Contributor(s):
*
#ifndef V8_JSREGEXP_H_ * Alternatively, the contents of this file may be used under the terms of
#define V8_JSREGEXP_H_ * either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL
#include "allocation.h" "),
#include "assembler.h" * in which case the provisions of the GPL or the LGPL are applicable inste
#include "zone-inl.h" ad
* of those above. If you wish to allow use of your version of this file on
namespace v8 { ly
namespace internal { * under the terms of either the GPL or the LGPL, and not to allow others t
o
class NodeVisitor; * use your version of this file under the terms of the MPL, indicate your
class RegExpCompiler; * decision by deleting the provisions above and replace them with the noti
class RegExpMacroAssembler; ce
class RegExpNode; * and other provisions required by the GPL or the LGPL. If you do not dele
class RegExpTree; te
class BoyerMooreLookahead; * the provisions above, a recipient may use your version of this file unde
r
class RegExpImpl { * the terms of any one of the MPL, the GPL or the LGPL.
public: *
// Whether V8 is compiled with native regexp support or not. * ***** END LICENSE BLOCK ***** */
static bool UsesNativeRegExp() {
#ifdef V8_INTERPRETED_REGEXP #ifndef jsregexp_h___
return false; #define jsregexp_h___
#else /*
return true; * JS regular expression interface.
#endif */
} #include <stddef.h>
#include "jspubtd.h"
// Creates a regular expression literal in the old space. #include "jsstr.h"
// This function calls the garbage collector if necessary.
static Handle<Object> CreateRegExpLiteral(Handle<JSFunction> constructor,
Handle<String> pattern,
Handle<String> flags,
bool* has_pending_exception);
// Returns a string representation of a regular expression.
// Implements RegExp.prototype.toString, see ECMA-262 section 15.10.6.4.
// This function calls the garbage collector if necessary.
static Handle<String> ToString(Handle<Object> value);
// Parses the RegExp pattern and prepares the JSRegExp object with
// generic data and choice of implementation - as well as what
// the implementation wants to store in the data field.
// Returns false if compilation fails.
static Handle<Object> Compile(Handle<JSRegExp> re,
Handle<String> pattern,
Handle<String> flags,
Zone* zone);
// See ECMA-262 section 15.10.6.2.
// This function calls the garbage collector if necessary.
static Handle<Object> Exec(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
Handle<JSArray> lastMatchInfo);
// Prepares a JSRegExp object with Irregexp-specific data.
static void IrregexpInitialize(Handle<JSRegExp> re,
Handle<String> pattern,
JSRegExp::Flags flags,
int capture_register_count);
static void AtomCompile(Handle<JSRegExp> re,
Handle<String> pattern,
JSRegExp::Flags flags,
Handle<String> match_pattern);
static Handle<Object> AtomExec(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
Handle<JSArray> lastMatchInfo);
enum IrregexpResult { RE_FAILURE = 0, RE_SUCCESS = 1, RE_EXCEPTION = -1 }
;
// Prepare a RegExp for being executed one or more times (using
// IrregexpExecOnce) on the subject.
// This ensures that the regexp is compiled for the subject, and that
// the subject is flat.
// Returns the number of integer spaces required by IrregexpExecOnce
// as its "registers" argument. If the regexp cannot be compiled,
// an exception is set as pending, and this function returns negative.
static int IrregexpPrepare(Handle<JSRegExp> regexp,
Handle<String> subject);
// Calculate the size of offsets vector for the case of global regexp
// and the number of matches this vector is able to store.
static int GlobalOffsetsVectorSize(Handle<JSRegExp> regexp,
int registers_per_match,
int* max_matches);
// Execute a regular expression on the subject, starting from index.
// If matching succeeds, return the number of matches. This can be large
r
// than one in the case of global regular expressions.
// The captures and subcaptures are stored into the registers vector.
// If matching fails, returns RE_FAILURE.
// If execution fails, sets a pending exception and returns RE_EXCEPTION.
static int IrregexpExecRaw(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
Vector<int> registers);
// Execute an Irregexp bytecode pattern.
// On a successful match, the result is a JSArray containing
// captured positions. On a failure, the result is the null value.
// Returns an empty handle in case of an exception.
static Handle<Object> IrregexpExec(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
Handle<JSArray> lastMatchInfo);
// Array index in the lastMatchInfo array.
static const int kLastCaptureCount = 0;
static const int kLastSubject = 1;
static const int kLastInput = 2;
static const int kFirstCapture = 3;
static const int kLastMatchOverhead = 3;
// Direct offset into the lastMatchInfo array.
static const int kLastCaptureCountOffset =
FixedArray::kHeaderSize + kLastCaptureCount * kPointerSize;
static const int kLastSubjectOffset =
FixedArray::kHeaderSize + kLastSubject * kPointerSize;
static const int kLastInputOffset =
FixedArray::kHeaderSize + kLastInput * kPointerSize;
static const int kFirstCaptureOffset =
FixedArray::kHeaderSize + kFirstCapture * kPointerSize;
// Used to access the lastMatchInfo array.
static int GetCapture(FixedArray* array, int index) {
return Smi::cast(array->get(index + kFirstCapture))->value();
}
static void SetLastCaptureCount(FixedArray* array, int to) {
array->set(kLastCaptureCount, Smi::FromInt(to));
}
static void SetLastSubject(FixedArray* array, String* to) {
array->set(kLastSubject, to);
}
static void SetLastInput(FixedArray* array, String* to) {
array->set(kLastInput, to);
}
static void SetCapture(FixedArray* array, int index, int to) {
array->set(index + kFirstCapture, Smi::FromInt(to));
}
static int GetLastCaptureCount(FixedArray* array) {
return Smi::cast(array->get(kLastCaptureCount))->value();
}
// For acting on the JSRegExp data FixedArray.
static int IrregexpMaxRegisterCount(FixedArray* re);
static void SetIrregexpMaxRegisterCount(FixedArray* re, int value);
static int IrregexpNumberOfCaptures(FixedArray* re);
static int IrregexpNumberOfRegisters(FixedArray* re);
static ByteArray* IrregexpByteCode(FixedArray* re, bool is_ascii);
static Code* IrregexpNativeCode(FixedArray* re, bool is_ascii);
// Limit the space regexps take up on the heap. In order to limit this w
e
// would like to keep track of the amount of regexp code on the heap. Th
is
// is not tracked, however. As a conservative approximation we track the
// total regexp code compiled including code that has subsequently been f
reed
// and the total executable memory at any point.
static const int kRegExpExecutableMemoryLimit = 16 * MB;
static const int kRegWxpCompiledLimit = 1 * MB;
private:
static String* last_ascii_string_;
static String* two_byte_cached_string_;
static bool CompileIrregexp(
Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii);
static inline bool EnsureCompiledIrregexp(
Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii);
// Set the subject cache. The previous string buffer is not deleted, so
the
// caller should ensure that it doesn't leak.
static void SetSubjectCache(String* subject,
char* utf8_subject,
int uft8_length,
int character_position,
int utf8_position);
// A one element cache of the last utf8_subject string and its length. T
he
// subject JS String object is cached in the heap. We also cache a
// translation between position and utf8 position.
static char* utf8_subject_cache_;
static int utf8_length_cache_;
static int utf8_position_;
static int character_position_;
};
// Represents the location of one element relative to the intersection of
// two sets. Corresponds to the four areas of a Venn diagram.
enum ElementInSetsRelation {
kInsideNone = 0,
kInsideFirst = 1,
kInsideSecond = 2,
kInsideBoth = 3
};
// Represents code units in the range from from_ to to_, both ends are
// inclusive.
class CharacterRange {
public:
CharacterRange() : from_(0), to_(0) { }
// For compatibility with the CHECK_OK macro
CharacterRange(void* null) { ASSERT_EQ(NULL, null); } //NOLINT
CharacterRange(uc16 from, uc16 to) : from_(from), to_(to) { }
static void AddClassEscape(uc16 type, ZoneList<CharacterRange>* ranges,
Zone* zone);
static Vector<const int> GetWordBounds();
static inline CharacterRange Singleton(uc16 value) {
return CharacterRange(value, value);
}
static inline CharacterRange Range(uc16 from, uc16 to) {
ASSERT(from <= to);
return CharacterRange(from, to);
}
static inline CharacterRange Everything() {
return CharacterRange(0, 0xFFFF);
}
bool Contains(uc16 i) { return from_ <= i && i <= to_; }
uc16 from() const { return from_; }
void set_from(uc16 value) { from_ = value; }
uc16 to() const { return to_; }
void set_to(uc16 value) { to_ = value; }
bool is_valid() { return from_ <= to_; }
bool IsEverything(uc16 max) { return from_ == 0 && to_ >= max; }
bool IsSingleton() { return (from_ == to_); }
void AddCaseEquivalents(ZoneList<CharacterRange>* ranges, bool is_ascii,
Zone* zone);
static void Split(ZoneList<CharacterRange>* base,
Vector<const int> overlay,
ZoneList<CharacterRange>** included,
ZoneList<CharacterRange>** excluded,
Zone* zone);
// Whether a range list is in canonical form: Ranges ordered by from valu
e,
// and ranges non-overlapping and non-adjacent.
static bool IsCanonical(ZoneList<CharacterRange>* ranges);
// Convert range list to canonical form. The characters covered by the ra
nges
// will still be the same, but no character is in more than one range, an
d
// adjacent ranges are merged. The resulting list may be shorter than the
// original, but cannot be longer.
static void Canonicalize(ZoneList<CharacterRange>* ranges);
// Negate the contents of a character range in canonical form.
static void Negate(ZoneList<CharacterRange>* src,
ZoneList<CharacterRange>* dst,
Zone* zone);
static const int kStartMarker = (1 << 24);
static const int kPayloadMask = (1 << 24) - 1;
private:
uc16 from_;
uc16 to_;
};
// A set of unsigned integers that behaves especially well on small
// integers (< 32). May do zone-allocation.
class OutSet: public ZoneObject {
public:
OutSet() : first_(0), remaining_(NULL), successors_(NULL) { }
OutSet* Extend(unsigned value, Zone* zone);
bool Get(unsigned value);
static const unsigned kFirstLimit = 32;
private:
// Destructively set a value in this set. In most cases you want
// to use Extend instead to ensure that only one instance exists
// that contains the same values.
void Set(unsigned value, Zone* zone);
// The successors are a list of sets that contain the same values
// as this set and the one more value that is not present in this
// set.
ZoneList<OutSet*>* successors(Zone* zone) { return successors_; }
OutSet(uint32_t first, ZoneList<unsigned>* remaining)
: first_(first), remaining_(remaining), successors_(NULL) { }
uint32_t first_;
ZoneList<unsigned>* remaining_;
ZoneList<OutSet*>* successors_;
friend class Trace;
};
// A mapping from integers, specified as ranges, to a set of integers.
// Used for mapping character ranges to choices.
class DispatchTable : public ZoneObject {
public:
explicit DispatchTable(Zone* zone) : tree_(zone) { }
class Entry {
public:
Entry() : from_(0), to_(0), out_set_(NULL) { }
Entry(uc16 from, uc16 to, OutSet* out_set)
: from_(from), to_(to), out_set_(out_set) { }
uc16 from() { return from_; }
uc16 to() { return to_; }
void set_to(uc16 value) { to_ = value; }
void AddValue(int value, Zone* zone) {
out_set_ = out_set_->Extend(value, zone);
}
OutSet* out_set() { return out_set_; }
private:
uc16 from_;
uc16 to_;
OutSet* out_set_;
};
class Config {
public:
typedef uc16 Key;
typedef Entry Value;
static const uc16 kNoKey;
static const Entry NoValue() { return Value(); }
static inline int Compare(uc16 a, uc16 b) {
if (a == b)
return 0;
else if (a < b)
return -1;
else
return 1;
}
};
void AddRange(CharacterRange range, int value, Zone* zone);
OutSet* Get(uc16 value);
void Dump();
template <typename Callback>
void ForEach(Callback* callback) {
return tree()->ForEach(callback);
}
private:
// There can't be a static empty set since it allocates its
// successors in a zone and caches them.
OutSet* empty() { return &empty_; }
OutSet empty_;
ZoneSplayTree<Config>* tree() { return &tree_; }
ZoneSplayTree<Config> tree_;
};
#define FOR_EACH_NODE_TYPE(VISIT) \
VISIT(End) \
VISIT(Action) \
VISIT(Choice) \
VISIT(BackReference) \
VISIT(Assertion) \
VISIT(Text)
#define FOR_EACH_REG_EXP_TREE_TYPE(VISIT) \
VISIT(Disjunction) \
VISIT(Alternative) \
VISIT(Assertion) \
VISIT(CharacterClass) \
VISIT(Atom) \
VISIT(Quantifier) \
VISIT(Capture) \
VISIT(Lookahead) \
VISIT(BackReference) \
VISIT(Empty) \
VISIT(Text)
#define FORWARD_DECLARE(Name) class RegExp##Name;
FOR_EACH_REG_EXP_TREE_TYPE(FORWARD_DECLARE)
#undef FORWARD_DECLARE
class TextElement {
public:
enum Type {UNINITIALIZED, ATOM, CHAR_CLASS};
TextElement() : type(UNINITIALIZED) { }
explicit TextElement(Type t) : type(t), cp_offset(-1) { }
static TextElement Atom(RegExpAtom* atom);
static TextElement CharClass(RegExpCharacterClass* char_class);
int length();
Type type;
union {
RegExpAtom* u_atom;
RegExpCharacterClass* u_char_class;
} data;
int cp_offset;
};
class Trace;
struct NodeInfo {
NodeInfo()
: being_analyzed(false),
been_analyzed(false),
follows_word_interest(false),
follows_newline_interest(false),
follows_start_interest(false),
at_end(false),
visited(false),
replacement_calculated(false) { }
// Returns true if the interests and assumptions of this node
// matches the given one.
bool Matches(NodeInfo* that) {
return (at_end == that->at_end) &&
(follows_word_interest == that->follows_word_interest) &&
(follows_newline_interest == that->follows_newline_interest) &&
(follows_start_interest == that->follows_start_interest);
}
// Updates the interests of this node given the interests of the
// node preceding it.
void AddFromPreceding(NodeInfo* that) {
at_end |= that->at_end;
follows_word_interest |= that->follows_word_interest;
follows_newline_interest |= that->follows_newline_interest;
follows_start_interest |= that->follows_start_interest;
}
bool HasLookbehind() {
return follows_word_interest ||
follows_newline_interest ||
follows_start_interest;
}
// Sets the interests of this node to include the interests of the
// following node.
void AddFromFollowing(NodeInfo* that) {
follows_word_interest |= that->follows_word_interest;
follows_newline_interest |= that->follows_newline_interest;
follows_start_interest |= that->follows_start_interest;
}
void ResetCompilationState() {
being_analyzed = false;
been_analyzed = false;
}
bool being_analyzed: 1;
bool been_analyzed: 1;
// These bits are set of this node has to know what the preceding
// character was.
bool follows_word_interest: 1;
bool follows_newline_interest: 1;
bool follows_start_interest: 1;
bool at_end: 1;
bool visited: 1;
bool replacement_calculated: 1;
};
// Details of a quick mask-compare check that can look ahead in the
// input stream.
class QuickCheckDetails {
public:
QuickCheckDetails()
: characters_(0),
mask_(0),
value_(0),
cannot_match_(false) { }
explicit QuickCheckDetails(int characters)
: characters_(characters),
mask_(0),
value_(0),
cannot_match_(false) { }
bool Rationalize(bool ascii);
// Merge in the information from another branch of an alternation.
void Merge(QuickCheckDetails* other, int from_index);
// Advance the current position by some amount.
void Advance(int by, bool ascii);
void Clear();
bool cannot_match() { return cannot_match_; }
void set_cannot_match() { cannot_match_ = true; }
struct Position {
Position() : mask(0), value(0), determines_perfectly(false) { }
uc16 mask;
uc16 value;
bool determines_perfectly;
};
int characters() { return characters_; }
void set_characters(int characters) { characters_ = characters; }
Position* positions(int index) {
ASSERT(index >= 0);
ASSERT(index < characters_);
return positions_ + index;
}
uint32_t mask() { return mask_; }
uint32_t value() { return value_; }
private:
// How many characters do we have quick check information from. This is
// the same for all branches of a choice node.
int characters_;
Position positions_[4];
// These values are the condensate of the above array after Rationalize()
.
uint32_t mask_;
uint32_t value_;
// If set to true, there is no way this quick check can match at all.
// E.g., if it requires to be at the start of the input, and isn't.
bool cannot_match_;
};
extern int kUninitializedRegExpNodePlaceHolder;
class RegExpNode: public ZoneObject { #ifdef JS_THREADSAFE
public: #include "jsdhash.h"
explicit RegExpNode(Zone* zone) #endif
: replacement_(NULL), trace_count_(0), zone_(zone) {
bm_info_[0] = bm_info_[1] = NULL;
}
virtual ~RegExpNode();
virtual void Accept(NodeVisitor* visitor) = 0;
// Generates a goto to this node or actually generates the code at this p
oint.
virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0;
// How many characters must this node consume at a minimum in order to
// succeed. If we have found at least 'still_to_find' characters that
// must be consumed there is no need to ask any following nodes whether
// they are sure to eat any more characters. The not_at_start argument i
s
// used to indicate that we know we are not at the start of the input. I
n
// this case anchored branches will always fail and can be ignored when
// determining how many characters are consumed on success.
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
bool not_at_start) = 0;
// Emits some quick code that checks whether the preloaded characters mat
ch.
// Falls through on certain failure, jumps to the label on possible succe
ss.
// If the node cannot make a quick check it does nothing and returns fals
e.
bool EmitQuickCheck(RegExpCompiler* compiler,
Trace* trace,
bool preload_has_checked_bounds,
Label* on_possible_success,
QuickCheckDetails* details_return,
bool fall_through_on_failure);
// For a given number of characters this returns a mask and a value. The
// next n characters are anded with the mask and compared with the value.
// A comparison failure indicates the node cannot match the next n charac
ters.
// A comparison success indicates the node may match.
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
RegExpCompiler* compiler,
int characters_filled_in,
bool not_at_start) = 0;
static const int kNodeIsTooComplexForGreedyLoops = -1;
virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoo
ps; }
// Only returns the successor for a text node of length 1 that matches an
y
// character and that has no guards on it.
virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
RegExpCompiler* compiler) {
return NULL;
}
// Collects information on the possible code units (mod 128) that can mat
ch if
// we look forward. This is used for a Boyer-Moore-like string searching
// implementation. TODO(erikcorry): This should share more code with
// EatsAtLeast, GetQuickCheckDetails. The budget argument is used to lim
it
// the number of nodes we are willing to look at in order to create this
data.
static const int kFillInBMBudget = 200;
virtual void FillInBMInfo(int offset,
int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start) {
UNREACHABLE();
}
// If we know that the input is ASCII then there are some nodes that can
// never match. This method returns a node that can be substituted for
// itself, or NULL if the node can never match.
virtual RegExpNode* FilterASCII(int depth) { return this; }
// Helper for FilterASCII.
RegExpNode* replacement() {
ASSERT(info()->replacement_calculated);
return replacement_;
}
RegExpNode* set_replacement(RegExpNode* replacement) {
info()->replacement_calculated = true;
replacement_ = replacement;
return replacement; // For convenience.
}
// We want to avoid recalculating the lookahead info, so we store it on t
he
// node. Only info that is for this node is stored. We can tell that th
e
// info is for this node when offset == 0, so the information is calculat
ed
// relative to this node.
void SaveBMInfo(BoyerMooreLookahead* bm, bool not_at_start, int offset) {
if (offset == 0) set_bm_info(not_at_start, bm);
}
Label* label() { return &label_; }
// If non-generic code is generated for a node (i.e. the node is not at t
he
// start of the trace) then it cannot be reused. This variable sets a li
mit
// on how often we allow that to happen before we insist on starting a ne
w
// trace and generating generic code for a node that can be reused by flu
shing
// the deferred actions in the current trace and generating a goto.
static const int kMaxCopiesCodeGenerated = 10;
NodeInfo* info() { return &info_; }
BoyerMooreLookahead* bm_info(bool not_at_start) {
return bm_info_[not_at_start ? 1 : 0];
}
Zone* zone() const { return zone_; }
protected:
enum LimitResult { DONE, CONTINUE };
RegExpNode* replacement_;
LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace);
void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) {
bm_info_[not_at_start ? 1 : 0] = bm;
}
private:
static const int kFirstCharBudget = 10;
Label label_;
NodeInfo info_;
// This variable keeps track of how many times code has been generated fo
r
// this node (in different traces). We don't keep track of where the
// generated code is located unless the code is generated at the start of
// a trace, in which case it is generic and can be reused by flushing the
// deferred operations in the current trace and generating a goto.
int trace_count_;
BoyerMooreLookahead* bm_info_[2];
Zone* zone_;
};
// A simple closed interval.
class Interval {
public:
Interval() : from_(kNone), to_(kNone) { }
Interval(int from, int to) : from_(from), to_(to) { }
Interval Union(Interval that) {
if (that.from_ == kNone)
return *this;
else if (from_ == kNone)
return that;
else
return Interval(Min(from_, that.from_), Max(to_, that.to_));
}
bool Contains(int value) {
return (from_ <= value) && (value <= to_);
}
bool is_empty() { return from_ == kNone; }
int from() const { return from_; }
int to() const { return to_; }
static Interval Empty() { return Interval(); }
static const int kNone = -1;
private:
int from_;
int to_;
};
class SeqRegExpNode: public RegExpNode {
public:
explicit SeqRegExpNode(RegExpNode* on_success)
: RegExpNode(on_success->zone()), on_success_(on_success) { }
RegExpNode* on_success() { return on_success_; }
void set_on_success(RegExpNode* node) { on_success_ = node; }
virtual RegExpNode* FilterASCII(int depth);
virtual void FillInBMInfo(int offset,
int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start) {
on_success_->FillInBMInfo(
offset, recursion_depth + 1, budget - 1, bm, not_at_start);
if (offset == 0) set_bm_info(not_at_start, bm);
}
protected:
RegExpNode* FilterSuccessor(int depth);
private:
RegExpNode* on_success_;
};
class ActionNode: public SeqRegExpNode {
public:
enum Type {
SET_REGISTER,
INCREMENT_REGISTER,
STORE_POSITION,
BEGIN_SUBMATCH,
POSITIVE_SUBMATCH_SUCCESS,
EMPTY_MATCH_CHECK,
CLEAR_CAPTURES
};
static ActionNode* SetRegister(int reg, int val, RegExpNode* on_success);
static ActionNode* IncrementRegister(int reg, RegExpNode* on_success);
static ActionNode* StorePosition(int reg,
bool is_capture,
RegExpNode* on_success);
static ActionNode* ClearCaptures(Interval range, RegExpNode* on_success);
static ActionNode* BeginSubmatch(int stack_pointer_reg,
int position_reg,
RegExpNode* on_success);
static ActionNode* PositiveSubmatchSuccess(int stack_pointer_reg,
int restore_reg,
int clear_capture_count,
int clear_capture_from,
RegExpNode* on_success);
static ActionNode* EmptyMatchCheck(int start_register,
int repetition_register,
int repetition_limit,
RegExpNode* on_success);
virtual void Accept(NodeVisitor* visitor);
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
bool not_at_start);
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
RegExpCompiler* compiler,
int filled_in,
bool not_at_start) {
return on_success()->GetQuickCheckDetails(
details, compiler, filled_in, not_at_start);
}
virtual void FillInBMInfo(int offset,
int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start);
Type type() { return type_; }
// TODO(erikcorry): We should allow some action nodes in greedy loops.
virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoo
ps; }
private:
union {
struct {
int reg;
int value;
} u_store_register;
struct {
int reg;
} u_increment_register;
struct {
int reg;
bool is_capture;
} u_position_register;
struct {
int stack_pointer_register;
int current_position_register;
int clear_register_count;
int clear_register_from;
} u_submatch;
struct {
int start_register;
int repetition_register;
int repetition_limit;
} u_empty_match_check;
struct {
int range_from;
int range_to;
} u_clear_captures;
} data_;
ActionNode(Type type, RegExpNode* on_success)
: SeqRegExpNode(on_success),
type_(type) { }
Type type_;
friend class DotPrinter;
};
class TextNode: public SeqRegExpNode {
public:
TextNode(ZoneList<TextElement>* elms,
RegExpNode* on_success)
: SeqRegExpNode(on_success),
elms_(elms) { }
TextNode(RegExpCharacterClass* that,
RegExpNode* on_success)
: SeqRegExpNode(on_success),
elms_(new(zone()) ZoneList<TextElement>(1, zone())) {
elms_->Add(TextElement::CharClass(that), zone());
}
virtual void Accept(NodeVisitor* visitor);
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
bool not_at_start);
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
RegExpCompiler* compiler,
int characters_filled_in,
bool not_at_start);
ZoneList<TextElement>* elements() { return elms_; }
void MakeCaseIndependent(bool is_ascii);
virtual int GreedyLoopTextLength();
virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
RegExpCompiler* compiler);
virtual void FillInBMInfo(int offset,
int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start);
void CalculateOffsets();
virtual RegExpNode* FilterASCII(int depth);
private:
enum TextEmitPassType {
NON_ASCII_MATCH, // Check for characters that can't match.
SIMPLE_CHARACTER_MATCH, // Case-dependent single character check.
NON_LETTER_CHARACTER_MATCH, // Check characters that have no case equi
vs.
CASE_CHARACTER_MATCH, // Case-independent single character check
.
CHARACTER_CLASS_MATCH // Character class.
};
static bool SkipPass(int pass, bool ignore_case);
static const int kFirstRealPass = SIMPLE_CHARACTER_MATCH;
static const int kLastPass = CHARACTER_CLASS_MATCH;
void TextEmitPass(RegExpCompiler* compiler,
TextEmitPassType pass,
bool preloaded,
Trace* trace,
bool first_element_checked,
int* checked_up_to);
int Length();
ZoneList<TextElement>* elms_;
};
class AssertionNode: public SeqRegExpNode {
public:
enum AssertionNodeType {
AT_END,
AT_START,
AT_BOUNDARY,
AT_NON_BOUNDARY,
AFTER_NEWLINE
};
static AssertionNode* AtEnd(RegExpNode* on_success) {
return new(on_success->zone()) AssertionNode(AT_END, on_success);
}
static AssertionNode* AtStart(RegExpNode* on_success) {
return new(on_success->zone()) AssertionNode(AT_START, on_success);
}
static AssertionNode* AtBoundary(RegExpNode* on_success) {
return new(on_success->zone()) AssertionNode(AT_BOUNDARY, on_success);
}
static AssertionNode* AtNonBoundary(RegExpNode* on_success) {
return new(on_success->zone()) AssertionNode(AT_NON_BOUNDARY, on_succes
s);
}
static AssertionNode* AfterNewline(RegExpNode* on_success) {
return new(on_success->zone()) AssertionNode(AFTER_NEWLINE, on_success)
;
}
virtual void Accept(NodeVisitor* visitor);
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
bool not_at_start);
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
RegExpCompiler* compiler,
int filled_in,
bool not_at_start);
virtual void FillInBMInfo(int offset,
int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start);
AssertionNodeType type() { return type_; }
void set_type(AssertionNodeType type) { type_ = type; }
private:
void EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace);
enum IfPrevious { kIsNonWord, kIsWord };
void BacktrackIfPrevious(RegExpCompiler* compiler,
Trace* trace,
IfPrevious backtrack_if_previous);
AssertionNode(AssertionNodeType t, RegExpNode* on_success)
: SeqRegExpNode(on_success), type_(t) { }
AssertionNodeType type_;
};
class BackReferenceNode: public SeqRegExpNode {
public:
BackReferenceNode(int start_reg,
int end_reg,
RegExpNode* on_success)
: SeqRegExpNode(on_success),
start_reg_(start_reg),
end_reg_(end_reg) { }
virtual void Accept(NodeVisitor* visitor);
int start_register() { return start_reg_; }
int end_register() { return end_reg_; }
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
bool not_at_start);
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
RegExpCompiler* compiler,
int characters_filled_in,
bool not_at_start) {
return;
}
virtual void FillInBMInfo(int offset,
int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start);
private:
int start_reg_;
int end_reg_;
};
class EndNode: public RegExpNode {
public:
enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS };
explicit EndNode(Action action, Zone* zone)
: RegExpNode(zone), action_(action) { }
virtual void Accept(NodeVisitor* visitor);
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
bool not_at_start) { return 0; }
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
RegExpCompiler* compiler,
int characters_filled_in,
bool not_at_start) {
// Returning 0 from EatsAtLeast should ensure we never get here.
UNREACHABLE();
}
virtual void FillInBMInfo(int offset,
int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start) {
// Returning 0 from EatsAtLeast should ensure we never get here.
UNREACHABLE();
}
private:
Action action_;
};
class NegativeSubmatchSuccess: public EndNode {
public:
NegativeSubmatchSuccess(int stack_pointer_reg,
int position_reg,
int clear_capture_count,
int clear_capture_start,
Zone* zone)
: EndNode(NEGATIVE_SUBMATCH_SUCCESS, zone),
stack_pointer_register_(stack_pointer_reg),
current_position_register_(position_reg),
clear_capture_count_(clear_capture_count),
clear_capture_start_(clear_capture_start) { }
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
private:
int stack_pointer_register_;
int current_position_register_;
int clear_capture_count_;
int clear_capture_start_;
};
class Guard: public ZoneObject {
public:
enum Relation { LT, GEQ };
Guard(int reg, Relation op, int value)
: reg_(reg),
op_(op),
value_(value) { }
int reg() { return reg_; }
Relation op() { return op_; }
int value() { return value_; }
private:
int reg_;
Relation op_;
int value_;
};
class GuardedAlternative {
public:
explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL
) { }
void AddGuard(Guard* guard, Zone* zone);
RegExpNode* node() { return node_; }
void set_node(RegExpNode* node) { node_ = node; }
ZoneList<Guard*>* guards() { return guards_; }
private:
RegExpNode* node_;
ZoneList<Guard*>* guards_;
};
class AlternativeGeneration;
class ChoiceNode: public RegExpNode {
public:
explicit ChoiceNode(int expected_size, Zone* zone)
: RegExpNode(zone),
alternatives_(new(zone)
ZoneList<GuardedAlternative>(expected_size, zone)),
table_(NULL),
not_at_start_(false),
being_calculated_(false) { }
virtual void Accept(NodeVisitor* visitor);
void AddAlternative(GuardedAlternative node) {
alternatives()->Add(node, zone());
}
ZoneList<GuardedAlternative>* alternatives() { return alternatives_; }
DispatchTable* GetTable(bool ignore_case);
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
bool not_at_start);
int EatsAtLeastHelper(int still_to_find,
int recursion_depth,
RegExpNode* ignore_this_node,
bool not_at_start);
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
RegExpCompiler* compiler,
int characters_filled_in,
bool not_at_start);
virtual void FillInBMInfo(int offset,
int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start);
bool being_calculated() { return being_calculated_; }
bool not_at_start() { return not_at_start_; }
void set_not_at_start() { not_at_start_ = true; }
void set_being_calculated(bool b) { being_calculated_ = b; }
virtual bool try_to_emit_quick_check_for_alternative(int i) { return true
; }
virtual RegExpNode* FilterASCII(int depth);
protected:
int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative);
ZoneList<GuardedAlternative>* alternatives_;
private:
friend class DispatchTableConstructor;
friend class Analysis;
void GenerateGuard(RegExpMacroAssembler* macro_assembler,
Guard* guard,
Trace* trace);
int CalculatePreloadCharacters(RegExpCompiler* compiler, int eats_at_leas
t);
void EmitOutOfLineContinuation(RegExpCompiler* compiler,
Trace* trace,
GuardedAlternative alternative,
AlternativeGeneration* alt_gen,
int preload_characters,
bool next_expects_preload);
DispatchTable* table_;
// If true, this node is never checked at the start of the input.
// Allows a new trace to start with at_start() set to false.
bool not_at_start_;
bool being_calculated_;
};
class NegativeLookaheadChoiceNode: public ChoiceNode {
public:
explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail,
GuardedAlternative then_do_this,
Zone* zone)
: ChoiceNode(2, zone) {
AddAlternative(this_must_fail);
AddAlternative(then_do_this);
}
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
bool not_at_start);
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
RegExpCompiler* compiler,
int characters_filled_in,
bool not_at_start);
virtual void FillInBMInfo(int offset,
int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start) {
alternatives_->at(1).node()->FillInBMInfo(
offset, recursion_depth + 1, budget - 1, bm, not_at_start);
if (offset == 0) set_bm_info(not_at_start, bm);
}
// For a negative lookahead we don't emit the quick check for the
// alternative that is expected to fail. This is because quick check cod
e
// starts by loading enough characters for the alternative that takes few
est
// characters, but on a negative lookahead the negative branch did not ta
ke
// part in that calculation (EatsAtLeast) so the assumptions don't hold.
virtual bool try_to_emit_quick_check_for_alternative(int i) { return i !=
0; }
virtual RegExpNode* FilterASCII(int depth);
};
class LoopChoiceNode: public ChoiceNode {
public:
explicit LoopChoiceNode(bool body_can_be_zero_length, Zone* zone)
: ChoiceNode(2, zone),
loop_node_(NULL),
continue_node_(NULL),
body_can_be_zero_length_(body_can_be_zero_length) { }
void AddLoopAlternative(GuardedAlternative alt);
void AddContinueAlternative(GuardedAlternative alt);
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
bool not_at_start);
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
RegExpCompiler* compiler,
int characters_filled_in,
bool not_at_start);
virtual void FillInBMInfo(int offset,
int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start);
RegExpNode* loop_node() { return loop_node_; }
RegExpNode* continue_node() { return continue_node_; }
bool body_can_be_zero_length() { return body_can_be_zero_length_; }
virtual void Accept(NodeVisitor* visitor);
virtual RegExpNode* FilterASCII(int depth);
private:
// AddAlternative is made private for loop nodes because alternatives
// should not be added freely, we need to keep track of which node
// goes back to the node itself.
void AddAlternative(GuardedAlternative node) {
ChoiceNode::AddAlternative(node);
}
RegExpNode* loop_node_;
RegExpNode* continue_node_;
bool body_can_be_zero_length_;
};
// Improve the speed that we scan for an initial point where a non-anchored
// regexp can match by using a Boyer-Moore-like table. This is done by
// identifying non-greedy non-capturing loops in the nodes that eat any
// character one at a time. For example in the middle of the regexp
// /foo[\s\S]*?bar/ we find such a loop. There is also such a loop implici
tly
// inserted at the start of any non-anchored regexp.
//
// When we have found such a loop we look ahead in the nodes to find the se
t of
// characters that can come at given distances. For example for the regexp
// /.?foo/ we know that there are at least 3 characters ahead of us, and th
e
// sets of characters that can occur are [any, [f, o], [o]]. We find a rang
e in
// the lookahead info where the set of characters is reasonably constrained
. In
// our example this is from index 1 to 2 (0 is not constrained). We can now
// look 3 characters ahead and if we don't find one of [f, o] (the union of
// [f, o] and [o]) then we can skip forwards by the range size (in this cas
e 2).
//
// For Unicode input strings we do the same, but modulo 128.
//
// We also look at the first string fed to the regexp and use that to get a
hint
// of the character frequencies in the inputs. This affects the assessment
of
// whether the set of characters is 'reasonably constrained'.
//
// We also have another lookahead mechanism (called quick check in the code
),
// which uses a wide load of multiple characters followed by a mask and com
pare
// to determine whether a match is possible at this point.
enum ContainedInLattice {
kNotYet = 0,
kLatticeIn = 1,
kLatticeOut = 2,
kLatticeUnknown = 3 // Can also mean both in and out.
};
inline ContainedInLattice Combine(ContainedInLattice a, ContainedInLattice
b) {
return static_cast<ContainedInLattice>(a | b);
}
ContainedInLattice AddRange(ContainedInLattice a,
const int* ranges,
int ranges_size,
Interval new_range);
class BoyerMoorePositionInfo : public ZoneObject {
public:
explicit BoyerMoorePositionInfo(Zone* zone)
: map_(new(zone) ZoneList<bool>(kMapSize, zone)),
map_count_(0),
w_(kNotYet),
s_(kNotYet),
d_(kNotYet),
surrogate_(kNotYet) {
for (int i = 0; i < kMapSize; i++) {
map_->Add(false, zone);
}
}
bool& at(int i) { return map_->at(i); }
static const int kMapSize = 128;
static const int kMask = kMapSize - 1;
int map_count() const { return map_count_; }
void Set(int character);
void SetInterval(const Interval& interval);
void SetAll();
bool is_non_word() { return w_ == kLatticeOut; }
bool is_word() { return w_ == kLatticeIn; }
private:
ZoneList<bool>* map_;
int map_count_; // Number of set bits in the map.
ContainedInLattice w_; // The \w character class.
ContainedInLattice s_; // The \s character class.
ContainedInLattice d_; // The \d character class.
ContainedInLattice surrogate_; // Surrogate UTF-16 code units.
};
class BoyerMooreLookahead : public ZoneObject {
public:
BoyerMooreLookahead(int length, RegExpCompiler* compiler, Zone* zone);
int length() { return length_; }
int max_char() { return max_char_; }
RegExpCompiler* compiler() { return compiler_; }
int Count(int map_number) {
return bitmaps_->at(map_number)->map_count();
}
BoyerMoorePositionInfo* at(int i) { return bitmaps_->at(i); }
void Set(int map_number, int character) {
if (character > max_char_) return;
BoyerMoorePositionInfo* info = bitmaps_->at(map_number);
info->Set(character);
}
void SetInterval(int map_number, const Interval& interval) {
if (interval.from() > max_char_) return;
BoyerMoorePositionInfo* info = bitmaps_->at(map_number);
if (interval.to() > max_char_) {
info->SetInterval(Interval(interval.from(), max_char_));
} else {
info->SetInterval(interval);
}
}
void SetAll(int map_number) {
bitmaps_->at(map_number)->SetAll();
}
void SetRest(int from_map) {
for (int i = from_map; i < length_; i++) SetAll(i);
}
bool EmitSkipInstructions(RegExpMacroAssembler* masm);
private:
// This is the value obtained by EatsAtLeast. If we do not have at least
this
// many characters left in the sample string then the match is bound to f
ail.
// Therefore it is OK to read a character this far ahead of the current m
atch
// point.
int length_;
RegExpCompiler* compiler_;
// 0x7f for ASCII, 0xffff for UTF-16.
int max_char_;
ZoneList<BoyerMoorePositionInfo*>* bitmaps_;
int GetSkipTable(int min_lookahead,
int max_lookahead,
Handle<ByteArray> boolean_skip_table);
bool FindWorthwhileInterval(int* from, int* to);
int FindBestInterval(
int max_number_of_chars, int old_biggest_points, int* from, int* to);
};
// There are many ways to generate code for a node. This class encapsulate
s
// the current way we should be generating. In other words it encapsulates
// the current state of the code generator. The effect of this is that we
// generate code for paths that the matcher can take through the regular
// expression. A given node in the regexp can be code-generated several ti
mes
// as it can be part of several traces. For example for the regexp:
// /foo(bar|ip)baz/ the code to match baz will be generated twice, once as
part
// of the foo-bar-baz trace and once as part of the foo-ip-baz trace. The
code
// to match foo is generated only once (the traces have a common prefix).
The
// code to store the capture is deferred and generated (twice) after the pl
aces
// where baz has been matched.
class Trace {
public:
// A value for a property that is either known to be true, know to be fal
se,
// or not known.
enum TriBool {
UNKNOWN = -1, FALSE = 0, TRUE = 1
};
class DeferredAction {
public:
DeferredAction(ActionNode::Type type, int reg)
: type_(type), reg_(reg), next_(NULL) { }
DeferredAction* next() { return next_; }
bool Mentions(int reg);
int reg() { return reg_; }
ActionNode::Type type() { return type_; }
private:
ActionNode::Type type_;
int reg_;
DeferredAction* next_;
friend class Trace;
};
class DeferredCapture : public DeferredAction {
public:
DeferredCapture(int reg, bool is_capture, Trace* trace)
: DeferredAction(ActionNode::STORE_POSITION, reg),
cp_offset_(trace->cp_offset()),
is_capture_(is_capture) { }
int cp_offset() { return cp_offset_; }
bool is_capture() { return is_capture_; }
private:
int cp_offset_;
bool is_capture_;
void set_cp_offset(int cp_offset) { cp_offset_ = cp_offset; }
};
class DeferredSetRegister : public DeferredAction {
public:
DeferredSetRegister(int reg, int value)
: DeferredAction(ActionNode::SET_REGISTER, reg),
value_(value) { }
int value() { return value_; }
private:
int value_;
};
class DeferredClearCaptures : public DeferredAction {
public:
explicit DeferredClearCaptures(Interval range)
: DeferredAction(ActionNode::CLEAR_CAPTURES, -1),
range_(range) { }
Interval range() { return range_; }
private:
Interval range_;
};
class DeferredIncrementRegister : public DeferredAction {
public:
explicit DeferredIncrementRegister(int reg)
: DeferredAction(ActionNode::INCREMENT_REGISTER, reg) { }
};
Trace()
: cp_offset_(0),
actions_(NULL),
backtrack_(NULL),
stop_node_(NULL),
loop_label_(NULL),
characters_preloaded_(0),
bound_checked_up_to_(0),
flush_budget_(100),
at_start_(UNKNOWN) { }
// End the trace. This involves flushing the deferred actions in the tra
ce
// and pushing a backtrack location onto the backtrack stack. Once this
is
// done we can start a new trace or go to one that has already been
// generated.
void Flush(RegExpCompiler* compiler, RegExpNode* successor);
int cp_offset() { return cp_offset_; }
DeferredAction* actions() { return actions_; }
// A trivial trace is one that has no deferred actions or other state tha
t
// affects the assumptions used when generating code. There is no record
ed
// backtrack location in a trivial trace, so with a trivial trace we will
// generate code that, on a failure to match, gets the backtrack location
// from the backtrack stack rather than using a direct jump instruction.
We
// always start code generation with a trivial trace and non-trivial trac
es
// are created as we emit code for nodes or add to the list of deferred
// actions in the trace. The location of the code generated for a node u
sing
// a trivial trace is recorded in a label in the node so that gotos can b
e
// generated to that code.
bool is_trivial() {
return backtrack_ == NULL &&
actions_ == NULL &&
cp_offset_ == 0 &&
characters_preloaded_ == 0 &&
bound_checked_up_to_ == 0 &&
quick_check_performed_.characters() == 0 &&
at_start_ == UNKNOWN;
}
TriBool at_start() { return at_start_; }
void set_at_start(bool at_start) { at_start_ = at_start ? TRUE : FALSE; }
Label* backtrack() { return backtrack_; }
Label* loop_label() { return loop_label_; }
RegExpNode* stop_node() { return stop_node_; }
int characters_preloaded() { return characters_preloaded_; }
int bound_checked_up_to() { return bound_checked_up_to_; }
int flush_budget() { return flush_budget_; }
QuickCheckDetails* quick_check_performed() { return &quick_check_performe
d_; }
bool mentions_reg(int reg);
// Returns true if a deferred position store exists to the specified
// register and stores the offset in the out-parameter. Otherwise
// returns false.
bool GetStoredPosition(int reg, int* cp_offset);
// These set methods and AdvanceCurrentPositionInTrace should be used onl
y on
// new traces - the intention is that traces are immutable after creation
.
void add_action(DeferredAction* new_action) {
ASSERT(new_action->next_ == NULL);
new_action->next_ = actions_;
actions_ = new_action;
}
void set_backtrack(Label* backtrack) { backtrack_ = backtrack; }
void set_stop_node(RegExpNode* node) { stop_node_ = node; }
void set_loop_label(Label* label) { loop_label_ = label; }
void set_characters_preloaded(int count) { characters_preloaded_ = count;
}
void set_bound_checked_up_to(int to) { bound_checked_up_to_ = to; }
void set_flush_budget(int to) { flush_budget_ = to; }
void set_quick_check_performed(QuickCheckDetails* d) {
quick_check_performed_ = *d;
}
void InvalidateCurrentCharacter();
void AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler);
private:
int FindAffectedRegisters(OutSet* affected_registers, Zone* zone);
void PerformDeferredActions(RegExpMacroAssembler* macro,
int max_register,
OutSet& affected_registers,
OutSet* registers_to_pop,
OutSet* registers_to_clear,
Zone* zone);
void RestoreAffectedRegisters(RegExpMacroAssembler* macro,
int max_register,
OutSet& registers_to_pop,
OutSet& registers_to_clear);
int cp_offset_;
DeferredAction* actions_;
Label* backtrack_;
RegExpNode* stop_node_;
Label* loop_label_;
int characters_preloaded_;
int bound_checked_up_to_;
QuickCheckDetails quick_check_performed_;
int flush_budget_;
TriBool at_start_;
};
class NodeVisitor {
public:
virtual ~NodeVisitor() { }
#define DECLARE_VISIT(Type) \
virtual void Visit##Type(Type##Node* that) = 0;
FOR_EACH_NODE_TYPE(DECLARE_VISIT)
#undef DECLARE_VISIT
virtual void VisitLoopChoice(LoopChoiceNode* that) { VisitChoice(that); }
};
// Node visitor used to add the start set of the alternatives to the
// dispatch table of a choice node.
class DispatchTableConstructor: public NodeVisitor {
public:
DispatchTableConstructor(DispatchTable* table, bool ignore_case,
Zone* zone)
: table_(table),
choice_index_(-1),
ignore_case_(ignore_case),
zone_(zone) { }
void BuildTable(ChoiceNode* node);
void AddRange(CharacterRange range) {
table()->AddRange(range, choice_index_, zone_);
}
void AddInverse(ZoneList<CharacterRange>* ranges);
#define DECLARE_VISIT(Type) \
virtual void Visit##Type(Type##Node* that);
FOR_EACH_NODE_TYPE(DECLARE_VISIT)
#undef DECLARE_VISIT
DispatchTable* table() { return table_; }
void set_choice_index(int value) { choice_index_ = value; }
protected:
DispatchTable* table_;
int choice_index_;
bool ignore_case_;
Zone* zone_;
};
// Assertion propagation moves information about assertions such as
// \b to the affected nodes. For instance, in /.\b./ information must
// be propagated to the first '.' that whatever follows needs to know
// if it matched a word or a non-word, and to the second '.' that it
// has to check if it succeeds a word or non-word. In this case the
// result will be something like:
//
// +-------+ +------------+
// | . | | . |
// +-------+ ---> +------------+
// | word? | | check word |
// +-------+ +------------+
class Analysis: public NodeVisitor {
public:
Analysis(bool ignore_case, bool is_ascii)
: ignore_case_(ignore_case),
is_ascii_(is_ascii),
error_message_(NULL) { }
void EnsureAnalyzed(RegExpNode* node);
#define DECLARE_VISIT(Type) \
virtual void Visit##Type(Type##Node* that);
FOR_EACH_NODE_TYPE(DECLARE_VISIT)
#undef DECLARE_VISIT
virtual void VisitLoopChoice(LoopChoiceNode* that);
bool has_failed() { return error_message_ != NULL; }
const char* error_message() {
ASSERT(error_message_ != NULL);
return error_message_;
}
void fail(const char* error_message) {
error_message_ = error_message;
}
private:
bool ignore_case_;
bool is_ascii_;
const char* error_message_;
DISALLOW_IMPLICIT_CONSTRUCTORS(Analysis);
};
struct RegExpCompileData {
RegExpCompileData()
: tree(NULL),
node(NULL),
simple(true),
contains_anchor(false),
capture_count(0) { }
RegExpTree* tree;
RegExpNode* node;
bool simple;
bool contains_anchor;
Handle<String> error;
int capture_count;
};
class RegExpEngine: public AllStatic {
public:
struct CompilationResult {
explicit CompilationResult(const char* error_message)
: error_message(error_message),
code(HEAP->the_hole_value()),
num_registers(0) {}
CompilationResult(Object* code, int registers)
: error_message(NULL),
code(code),
num_registers(registers) {}
const char* error_message;
Object* code;
int num_registers;
};
static CompilationResult Compile(RegExpCompileData* input,
bool ignore_case,
bool global,
bool multiline,
Handle<String> pattern,
Handle<String> sample_subject,
bool is_ascii, Zone* zone);
static void DotPrint(const char* label, RegExpNode* node, bool ignore_cas
e);
};
class OffsetsVector {
public:
inline OffsetsVector(int num_registers, Isolate* isolate)
: offsets_vector_length_(num_registers) {
if (offsets_vector_length_ > Isolate::kJSRegexpStaticOffsetsVectorSize)
{
vector_ = NewArray<int>(offsets_vector_length_);
} else {
vector_ = isolate->jsregexp_static_offsets_vector();
}
}
inline ~OffsetsVector() {
if (offsets_vector_length_ > Isolate::kJSRegexpStaticOffsetsVectorSize)
{
DeleteArray(vector_);
vector_ = NULL;
}
}
inline int* vector() { return vector_; }
inline int length() { return offsets_vector_length_; }
static const int kStaticOffsetsVectorSize =
Isolate::kJSRegexpStaticOffsetsVectorSize;
private:
static Address static_offsets_vector_address(Isolate* isolate) {
return reinterpret_cast<Address>(isolate->jsregexp_static_offsets_vecto
r());
}
int* vector_;
int offsets_vector_length_;
friend class ExternalReference; struct JSRegExpStatics {
}; JSString *input; /* input string to match (perl $_, GC root)
*/
JSBool multiline; /* whether input contains newlines (perl $*
) */
uint16 parenCount; /* number of valid elements in parens[] */
uint16 moreLength; /* number of allocated elements in morePare
ns */
JSSubString parens[9]; /* last set of parens matched (perl $1, $2)
*/
JSSubString *moreParens; /* null or realloc'd vector for $10, etc. *
/
JSSubString lastMatch; /* last string matched (perl $&) */
JSSubString lastParen; /* last paren matched (perl $+) */
JSSubString leftContext; /* input to left of last match (perl $`) */
JSSubString rightContext; /* input to right of last match (perl $') *
/
};
/*
* This struct holds a bitmap representation of a class from a regexp.
* There's a list of these referenced by the classList field in the JSRegEx
p
* struct below. The initial state has startIndex set to the offset in the
* original regexp source of the beginning of the class contents. The first
* use of the class converts the source representation into a bitmap.
*
*/
typedef struct RECharSet {
JSPackedBool converted;
JSPackedBool sense;
uint16 length;
union {
uint8 *bits;
struct {
size_t startIndex;
size_t length;
} src;
} u;
} RECharSet;
/*
* This macro is safe because moreParens is guaranteed to be allocated and
big
* enough to hold parenCount, or else be null when parenCount is 0.
*/
#define REGEXP_PAREN_SUBSTRING(res, num)
\
(((jsuint)(num) < (jsuint)(res)->parenCount)
\
? ((jsuint)(num) < 9)
\
? &(res)->parens[num]
\
: &(res)->moreParens[(num) - 9]
\
: &js_EmptySubString)
typedef struct RENode RENode;
struct JSRegExp {
jsrefcount nrefs; /* reference count */
uint16 flags; /* flags, see jsapi.h's JSREG_* defines */
uint16 cloneIndex; /* index in fp->vars or funobj->slots of
cloned regexp object */
size_t parenCount; /* number of parenthesized submatches */
size_t classCount; /* count [...] bitmaps */
RECharSet *classList; /* list of [...] bitmaps */
JSString *source; /* locked source string, sans // */
jsbytecode program[1]; /* regular expression bytecode */
};
extern JSRegExp *
js_NewRegExp(JSContext *cx, JSTokenStream *ts,
JSString *str, uintN flags, JSBool flat);
extern JSRegExp *
js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts,
JSString *str, JSString *opt, JSBool flat);
#define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs)
#define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re)
extern void
js_DestroyRegExp(JSContext *cx, JSRegExp *re);
/*
* Execute re on input str at *indexp, returning null in *rval on mismatch.
* On match, return true if test is true, otherwise return an array object.
* Update *indexp and cx->regExpStatics always on match.
*/
extern JSBool
js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp
,
JSBool test, jsval *rval);
/*
* These two add and remove GC roots, respectively, so their calls must be
* well-ordered.
*/
extern JSBool
js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res);
extern void
js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res);
#define JSVAL_IS_REGEXP(cx, v)
\
(JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) &&
\
OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_RegExpClass)
extern JSClass js_RegExpClass;
extern JSObject *
js_InitRegExpClass(JSContext *cx, JSObject *obj);
/*
* Export js_regexp_toString to the decompiler.
*/
extern JSBool
js_regexp_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval);
/*
* Create, serialize/deserialize, or clone a RegExp object.
*/
extern JSObject *
js_NewRegExpObject(JSContext *cx, JSTokenStream *ts,
jschar *chars, size_t length, uintN flags);
extern JSBool
js_XDRRegExp(JSXDRState *xdr, JSObject **objp);
extern JSObject *
js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent);
/*
* Get and set the per-object (clone or clone-parent) lastIndex slot.
*/
extern JSBool
js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex);
} } // namespace v8::internal extern JSBool
js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex);
#endif // V8_JSREGEXP_H_ #endif /* jsregexp_h___ */
 End of changes. 5 change blocks. 
1694 lines changed or deleted 203 lines changed or added


 keypattern.h   keypattern.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/base/string_data.h" #include "mongo/base/string_data.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/platform/unordered_set.h"
#include "mongo/util/mongoutils/str.h" #include "mongo/util/mongoutils/str.h"
namespace mongo { namespace mongo {
struct FieldInterval; struct FieldInterval;
class FieldRangeSet; class FieldRangeSet;
/** /**
* A BoundList contains intervals specified by inclusive start * A BoundList contains intervals specified by inclusive start
* and end bounds. The intervals should be nonoverlapping and occur in * and end bounds. The intervals should be nonoverlapping and occur in
skipping to change at line 50 skipping to change at line 51
* document key. Document keys are used to store documents in indices and to target * document key. Document keys are used to store documents in indices and to target
* sharded queries. * sharded queries.
* *
* Examples: * Examples:
* { a : 1 } * { a : 1 }
* { a : 1 , b : -1 } * { a : 1 , b : -1 }
* { a : "hashed" } * { a : "hashed" }
*/ */
class KeyPattern { class KeyPattern {
public: public:
KeyPattern( const BSONObj& pattern ): _pattern( pattern ) {} /*
* We are allowing implicit conversion from BSON
*/
KeyPattern( const BSONObj& pattern );
/* /*
* Returns a BSON representation of this KeyPattern. * Returns a BSON representation of this KeyPattern.
*/ */
BSONObj toBSON() const { return _pattern; } BSONObj toBSON() const { return _pattern; }
/* /*
* Returns true if the given fieldname is the name of one element o * Returns true if the given fieldname is the (dotted prefix of the
f the (potentially) ) name of one
* compound key described by this KeyPattern. * element of the (potentially) compound key described by this KeyP
attern.
*/ */
bool hasField( const StringData& fieldname ) const { return _patter bool hasField( const StringData& fieldname ) const {
n.hasField( fieldname ); } return _prefixes.find( fieldname ) != _prefixes.end();
}
/* /*
* Gets the element of this pattern corresponding to the given fiel dname. * Gets the element of this pattern corresponding to the given fiel dname.
* Returns eoo if none exists. * Returns eoo if none exists.
*/ */
BSONElement getField( const char* fieldname ) const { return _patte rn[ fieldname ]; } BSONElement getField( const char* fieldname ) const { return _patte rn[ fieldname ]; }
/* /*
* Returns true if the key described by this KeyPattern is a prefix of * Returns true if the key described by this KeyPattern is a prefix of
* the (potentially) compound key described by 'other' * the (potentially) compound key described by 'other'
skipping to change at line 162 skipping to change at line 168
* *
* The queryConstraints should be defined for all the fields in thi s keypattern * The queryConstraints should be defined for all the fields in thi s keypattern
* (i.e. the value of frsp->matchPossibleForSingleKeyFRS(_pattern) should be true, * (i.e. the value of frsp->matchPossibleForSingleKeyFRS(_pattern) should be true,
* otherwise this function could throw). * otherwise this function could throw).
* *
*/ */
BoundList keyBounds( const FieldRangeSet& queryConstraints ) const; BoundList keyBounds( const FieldRangeSet& queryConstraints ) const;
private: private:
BSONObj _pattern; BSONObj _pattern;
// Each field in the '_pattern' may be itself a dotted field. We st
ore all the prefixes
// of each field here. For instance, if a pattern is { 'a.b.c': 1,
x: 1 }, we'll store
// here 'a', 'a.b', 'a.b.c', and 'x'.
//
// Since we're indexing into '_pattern's field names, it must stay
constant after
// constructed.
struct PrefixHasher {
size_t operator()( const StringData& strData ) const {
size_t result = 0;
const char* p = strData.rawData();
for (size_t len = strData.size(); len > 0; len-- ) {
result = ( result * 131 ) + *p++;
}
return result;
}
};
unordered_set<StringData, PrefixHasher> _prefixes;
bool isAscending( const BSONElement& fieldExpression ) const { bool isAscending( const BSONElement& fieldExpression ) const {
return ( fieldExpression.isNumber() && fieldExpression.numberI nt() == 1 ); return ( fieldExpression.isNumber() && fieldExpression.numberI nt() == 1 );
} }
bool isDescending( const BSONElement& fieldExpression ) const { bool isDescending( const BSONElement& fieldExpression ) const {
return ( fieldExpression.isNumber() && fieldExpression.numberI nt() == -1 ); return ( fieldExpression.isNumber() && fieldExpression.numberI nt() == -1 );
} }
bool isHashed( const BSONElement& fieldExpression ) const { bool isHashed( const BSONElement& fieldExpression ) const {
return mongoutils::str::equals( fieldExpression.valuestrsafe() , "hashed" ); return mongoutils::str::equals( fieldExpression.valuestrsafe() , "hashed" );
} }
/* Takes a list of intervals corresponding to constraints on a give n field /* Takes a list of intervals corresponding to constraints on a give n field
* in this keypattern, and transforms them into a list of bounds * in this keypattern, and transforms them into a list of bounds
* based on the expression for 'field' * based on the expression for 'field'
*/ */
BoundList _transformFieldBounds( const vector<FieldInterval>& oldIn tervals , BoundList _transformFieldBounds( const vector<FieldInterval>& oldIn tervals ,
const BSONElement& field ) const; const BSONElement& field ) const;
 End of changes. 7 change blocks. 
6 lines changed or deleted 36 lines changed or added


 log.h   log.h 
skipping to change at line 42 skipping to change at line 42
#include "mongo/util/exit_code.h" #include "mongo/util/exit_code.h"
#ifndef _WIN32 #ifndef _WIN32
#include <syslog.h> #include <syslog.h>
#endif #endif
namespace mongo { namespace mongo {
enum ExitCode; enum ExitCode;
enum LogLevel { LL_DEBUG , LL_INFO , LL_NOTICE , LL_WARNING , LL_ERROR // using negative numbers so these are always less than ::mongo::loglev
, LL_SEVERE }; el (see MONGO_LOG)
enum LogLevel { LL_DEBUG=-1000 , LL_INFO , LL_NOTICE , LL_WARNING , LL
_ERROR , LL_SEVERE };
inline const char * logLevelToString( LogLevel l ) { inline const char * logLevelToString( LogLevel l ) {
switch ( l ) { switch ( l ) {
case LL_DEBUG: case LL_DEBUG:
case LL_INFO: case LL_INFO:
case LL_NOTICE: case LL_NOTICE:
return ""; return "";
case LL_WARNING: case LL_WARNING:
return "warning" ; return "warning" ;
case LL_ERROR: case LL_ERROR:
skipping to change at line 353 skipping to change at line 354
void indentInc(){ indent++; } void indentInc(){ indent++; }
void indentDec(){ indent--; } void indentDec(){ indent--; }
int getIndent() const { return indent; } int getIndent() const { return indent; }
// Replace any pre-existing function for appending context informat ion to log lines with // Replace any pre-existing function for appending context informat ion to log lines with
// "contextFn". Returns Status::OK on first call, and ErrorCodes:: AlreadyInitialized if // "contextFn". Returns Status::OK on first call, and ErrorCodes:: AlreadyInitialized if
// called more than once. Returns ErrorCodes::BadValue if contextF n is NULL. // called more than once. Returns ErrorCodes::BadValue if contextF n is NULL.
static Status registerExtraLogContextFn(ExtraLogContextFn contextFn ); static Status registerExtraLogContextFn(ExtraLogContextFn contextFn );
private: private:
static boost::thread_specific_ptr<Logstream> tsp;
Logstream() { Logstream() {
indent = 0; indent = 0;
_init(); _init();
} }
void _init() { void _init() {
ss.str(""); ss.str("");
logLevel = LL_INFO; logLevel = LL_INFO;
} }
public: public:
skipping to change at line 401 skipping to change at line 401
set tlogLevel to -1 to suppress tlog() output in a test program. */ set tlogLevel to -1 to suppress tlog() output in a test program. */
Nullstream& tlog( int level = 0 ); Nullstream& tlog( int level = 0 );
// log if debug build or if at a certain level // log if debug build or if at a certain level
inline Nullstream& dlog( int level ) { inline Nullstream& dlog( int level ) {
if ( level <= logLevel || DEBUG_BUILD ) if ( level <= logLevel || DEBUG_BUILD )
return Logstream::get().prolog(); return Logstream::get().prolog();
return nullstream; return nullstream;
} }
#define MONGO_LOG(requiredLevel) \ #define MONGO_LOG(level) \
( MONGO_likely( ::mongo::logLevel < (requiredLevel) ) ) \ ( MONGO_likely( ::mongo::logLevel < (level) ) ) \
? ::mongo::log() : ::mongo::log() ? ::mongo::nullstream : ::mongo::logWithLevel(level)
#define LOG MONGO_LOG #define LOG MONGO_LOG
inline Nullstream& log() { inline Nullstream& log() {
return Logstream::get().prolog(); return Logstream::get().prolog();
} }
// Use MONGO_LOG() instead of this
inline Nullstream& logWithLevel( int level ) {
if ( level > logLevel )
return nullstream;
return Logstream::get().prolog();
}
inline Nullstream& logWithLevel( LogLevel l ) {
return Logstream::get().prolog().setLogLevel( l );
}
inline Nullstream& logWithLevel( const LabeledLevel& ll ) {
Nullstream& stream = logWithLevel( ll.getLevel() );
if( ll.getLabel() != "" )
stream << "[" << ll.getLabel() << "] ";
return stream;
}
inline Nullstream& error() { inline Nullstream& error() {
return MONGO_LOG( LL_ERROR ); return logWithLevel( LL_ERROR );
} }
inline Nullstream& warning() { inline Nullstream& warning() {
return MONGO_LOG( LL_WARNING ); return logWithLevel( LL_WARNING );
} }
/* default impl returns "" -- mongod overrides */ /* default impl returns "" -- mongod overrides */
extern const char * (*getcurns)(); extern const char * (*getcurns)();
inline Nullstream& problem( int level = 0 ) { inline Nullstream& problem( int level = 0 ) {
if ( level > logLevel ) if ( level > logLevel )
return nullstream; return nullstream;
Logstream& l = Logstream::get().prolog(); Logstream& l = Logstream::get().prolog();
l << ' ' << getcurns() << ' '; l << ' ' << getcurns() << ' ';
 End of changes. 6 change blocks. 
8 lines changed or deleted 27 lines changed or added


 macros.h   macros.h 
skipping to change at line 13 skipping to change at line 13
// Various Google-specific macros. // Various Google-specific macros.
// //
// This code is compiled directly on many platforms, including client // This code is compiled directly on many platforms, including client
// platforms like Windows, Mac, and embedded systems. Before making // platforms like Windows, Mac, and embedded systems. Before making
// any changes here, make sure that you're not breaking any platforms. // any changes here, make sure that you're not breaking any platforms.
// //
#ifndef BASE_MACROS_H_ #ifndef BASE_MACROS_H_
#define BASE_MACROS_H_ #define BASE_MACROS_H_
#include "base/definer.h" // For OS_WINDOWS
#include <stddef.h> // For size_t #include <stddef.h> // For size_t
// We use our own local version of type traits while we're waiting // We use our own local version of type traits while we're waiting
// for TR1 type traits to be standardized. Define some macros so that // for TR1 type traits to be standardized. Define some macros so that
// most google3 code doesn't have to work with type traits directly. // most google3 code doesn't have to work with type traits directly.
#include "type_traits.h" #include "type_traits.h"
// The swigged version of an abstract class must be concrete if any methods // The swigged version of an abstract class must be concrete if any methods
// return objects of the abstract type. We keep it abstract in C++ and // return objects of the abstract type. We keep it abstract in C++ and
// concrete for swig. // concrete for swig.
 End of changes. 1 change blocks. 
0 lines changed or deleted 2 lines changed or added


 matcher.h   matcher.h 
skipping to change at line 25 skipping to change at line 25
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public Licen se * You should have received a copy of the GNU Affero General Public Licen se
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include "jsobj.h" #include "jsobj.h"
#include "pcrecpp.h" #include "pcrecpp.h"
#include "mongo/db/geo/geoparser.h" #include "mongo/db/geo/geoquery.h"
namespace mongo { namespace mongo {
class Cursor; class Cursor;
class CoveredIndexMatcher; class CoveredIndexMatcher;
class ElementMatcher; class ElementMatcher;
class Matcher; class Matcher;
class FieldRangeVector; class FieldRangeVector;
class RegexMatcher { class RegexMatcher {
skipping to change at line 53 skipping to change at line 53
const char *_fieldName; const char *_fieldName;
const char *_regex; const char *_regex;
const char *_flags; const char *_flags;
string _prefix; string _prefix;
shared_ptr< pcrecpp::RE > _re; shared_ptr< pcrecpp::RE > _re;
bool _isNot; bool _isNot;
RegexMatcher() : _isNot() {} RegexMatcher() : _isNot() {}
}; };
class GeoMatcher { struct GeoMatcher {
private:
GeoMatcher(const string& field, bool isNot) : _isBox(false), _isCir
cle(false),
_isPolygon(false), _f
ieldName(field),
_isNot(isNot) {}
bool _isBox;
Box _box;
bool _isCircle;
Point _center;
double _radius;
bool _isPolygon;
Polygon _polygon;
string _fieldName;
bool _isNot;
public: public:
const string& getFieldName() const { return _fieldName; } GeoMatcher(GeoQuery query, bool negated) : geoQuery(query), isNot(n
egated) {}
static GeoMatcher makeBoxMatcher(const string& field, const BSONObj
&obj, bool isNot) {
GeoMatcher m(field, isNot);
m._isBox = true;
GeoParser::parseLegacyBox(obj, &m._box);
return m;
}
static GeoMatcher makeCircleMatcher(const string& field, const BSON
Obj &obj, bool isNot) {
GeoMatcher m(field, isNot);
m._isCircle = true;
GeoParser::parseLegacyCenter(obj, &m._center, &m._radius);
return m;
}
static GeoMatcher makePolygonMatcher(const string& field, const BSO string getField() const { return geoQuery.getField(); }
NObj &obj, bool isNot) {
GeoMatcher m(field, isNot);
m._isPolygon = true;
GeoParser::parseLegacyPolygon(obj, &m._polygon);
return m;
}
bool containsPoint(Point p) const {
bool ret;
if (_isBox) {
ret = _box.inside(p, 0);
} else if (_isCircle) {
ret = distance(p, _center) <= _radius;
} else if (_isPolygon) {
ret = _polygon.contains(p);
} else {
ret = false;
}
return _isNot ? !ret : ret;
}
string toString() const {
stringstream ss;
if (_isBox) {
ss << "GeoMatcher Box: " << _box.toString();
} else if (_isCircle) {
ss << "GeoMatcher Circle @ " << _center.toString() << " r =
" << _radius;
} else {
ss << "GeoMatcher UNKNOWN";
}
return ss.str();
}
static bool pointFrom(const BSONObj o, Point *p) { bool matches(const GeometryContainer &container) const {
if (!GeoParser::isLegacyPoint(o)) { return false; } bool satisfied = geoQuery.satisfiesPredicate(container);
GeoParser::parseLegacyPoint(o, p); if (isNot) { return !satisfied; }
return true; else { return satisfied; }
} }
GeoQuery geoQuery;
bool isNot;
}; };
struct element_lt { struct element_lt {
bool operator()(const BSONElement& l, const BSONElement& r) const { bool operator()(const BSONElement& l, const BSONElement& r) const {
int x = (int) l.canonicalType() - (int) r.canonicalType(); int x = (int) l.canonicalType() - (int) r.canonicalType();
if ( x < 0 ) return true; if ( x < 0 ) return true;
else if ( x > 0 ) return false; else if ( x > 0 ) return false;
return compareElementValues(l,r) < 0; return compareElementValues(l,r) < 0;
} }
}; };
skipping to change at line 224 skipping to change at line 165
bool _elemMatchKeyRequested; bool _elemMatchKeyRequested;
bool _elemMatchKeyFound; bool _elemMatchKeyFound;
string _elemMatchKey; string _elemMatchKey;
}; };
/* Match BSON objects against a query pattern. /* Match BSON objects against a query pattern.
e.g. e.g.
db.foo.find( { a : 3 } ); db.foo.find( { a : 3 } );
{ a : 3 } is the pattern object. See wiki documentation for full in fo. { a : 3 } is the pattern object. See manual for full info.
GT/LT: GT/LT:
{ a : { $gt : 3 } } { a : { $gt : 3 } }
Not equal: Not equal:
{ a : { $ne : 3 } } { a : { $ne : 3 } }
TODO: we should rewrite the matcher to be more an AST style. TODO: we should rewrite the matcher to be more an AST style.
*/ */
class Matcher : boost::noncopyable { class Matcher : boost::noncopyable {
int matchesDotted( int matchesDotted(
 End of changes. 7 change blocks. 
76 lines changed or deleted 12 lines changed or added


 misc.h   misc.h 
skipping to change at line 26 skipping to change at line 26
* 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 <limits> #include <limits>
#include <string> #include <string>
#include "mongo/platform/cstdint.h"
#include "mongo/util/assert_util.h" #include "mongo/util/assert_util.h"
namespace mongo { namespace mongo {
inline void time_t_to_String(time_t t, char *buf) { inline void time_t_to_String(time_t t, char *buf) {
#if defined(_WIN32) #if defined(_WIN32)
ctime_s(buf, 32, &t); ctime_s(buf, 32, &t);
#else #else
ctime_r(&t, buf); ctime_r(&t, buf);
#endif #endif
skipping to change at line 100 skipping to change at line 101
char buf[64]; char buf[64];
time_t_to_String(toTimeT(), buf); time_t_to_String(toTimeT(), buf);
return buf; return buf;
} }
time_t toTimeT() const { time_t toTimeT() const {
// cant use uassert from bson/util // cant use uassert from bson/util
verify((long long)millis >= 0); // TODO when millis is signed, delete verify((long long)millis >= 0); // TODO when millis is signed, delete
verify(((long long)millis/1000) < (std::numeric_limits<time_t>: :max)()); verify(((long long)millis/1000) < (std::numeric_limits<time_t>: :max)());
return millis / 1000; 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. 
0 lines changed or deleted 4 lines changed or added


 mock_dbclient_cursor.h   mock_dbclient_cursor.h 
skipping to change at line 35 skipping to change at line 35
/** /**
* Simple adapter class for mongo::DBClientMockCursor to mongo::DBClien tCursor. * Simple adapter class for mongo::DBClientMockCursor to mongo::DBClien tCursor.
* Only supports more and next, the behavior of other operations are un defined. * Only supports more and next, the behavior of other operations are un defined.
*/ */
class MockDBClientCursor: public mongo::DBClientCursor { class MockDBClientCursor: public mongo::DBClientCursor {
public: public:
MockDBClientCursor(mongo::DBClientBase* client, MockDBClientCursor(mongo::DBClientBase* client,
const mongo::BSONArray& mockCollection); const mongo::BSONArray& mockCollection);
bool more(); bool more();
/**
* Note: has the same contract as DBClientCursor - returned BSONObj
will
* become invalid when this cursor is destroyed.
*/
mongo::BSONObj next(); mongo::BSONObj next();
private: private:
boost::scoped_ptr<mongo::DBClientMockCursor> _cursor; boost::scoped_ptr<mongo::DBClientMockCursor> _cursor;
mongo::BSONObj _resultSet; mongo::BSONObj _resultSet;
}; };
} }
 End of changes. 1 change blocks. 
0 lines changed or deleted 6 lines changed or added


 mock_remote_db_server.h   mock_remote_db_server.h 
skipping to change at line 195 skipping to change at line 195
}; };
/** /**
* Checks whether the instance of the server is still up. * Checks whether the instance of the server is still up.
* *
* @throws mongo::SocketException if this server is down * @throws mongo::SocketException if this server is down
*/ */
void checkIfUp(InstanceID id) const; void checkIfUp(InstanceID id) const;
typedef unordered_map<std::string, boost::shared_ptr<CircularBSONIt erator> > CmdToReplyObj; typedef unordered_map<std::string, boost::shared_ptr<CircularBSONIt erator> > CmdToReplyObj;
typedef unordered_map<std::string, mongo::BSONArrayBuilder*> MockDa taMgr; typedef unordered_map<std::string, vector<BSONObj> > MockDataMgr;
bool _isRunning; bool _isRunning;
const std::string _hostAndPort; const std::string _hostAndPort;
long long _delayMilliSec; long long _delayMilliSec;
// //
// Mock replies // Mock replies
// //
CmdToReplyObj _cmdMap; CmdToReplyObj _cmdMap;
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 mr.h   mr.h 
skipping to change at line 123 skipping to change at line 123
public: public:
JSReducer( const BSONElement& code ) : _func( "_reduce" , code ) {} JSReducer( const BSONElement& code ) : _func( "_reduce" , code ) {}
virtual void init( State * state ); virtual void init( State * state );
virtual BSONObj reduce( const BSONList& tuples ); virtual BSONObj reduce( const BSONList& tuples );
virtual BSONObj finalReduce( const BSONList& tuples , Finalizer * finalizer ); virtual BSONObj finalReduce( const BSONList& tuples , Finalizer * finalizer );
private: private:
/** /**
* result in "return" * result in "__returnValue"
* @param key OUT * @param key OUT
* @param endSizeEstimate OUT * @param endSizeEstimate OUT
*/ */
void _reduce( const BSONList& values , BSONObj& key , int& endS izeEstimate ); void _reduce( const BSONList& values , BSONObj& key , int& endS izeEstimate );
JSFunction _func; JSFunction _func;
}; };
class JSFinalizer : public Finalizer { class JSFinalizer : public Finalizer {
public: public:
skipping to change at line 270 skipping to change at line 270
void prepTempCollection(); void prepTempCollection();
void finalReduce( BSONList& values ); void finalReduce( BSONList& values );
void finalReduce( CurOp * op , ProgressMeterHolder& pm ); void finalReduce( CurOp * op , ProgressMeterHolder& pm );
// ------- cleanup/data positioning ---------- // ------- cleanup/data positioning ----------
/** /**
* Clean up the temporary and incremental collections
*/
void dropTempCollections();
/**
@return number objects in collection @return number objects in collection
*/ */
long long postProcessCollection( CurOp* op , ProgressMeterHolde r& pm ); long long postProcessCollection( CurOp* op , ProgressMeterHolde r& pm );
long long postProcessCollectionNonAtomic( CurOp* op , ProgressM eterHolder& pm ); long long postProcessCollectionNonAtomic( CurOp* op , ProgressM eterHolder& pm );
/** /**
* if INMEMORY will append * if INMEMORY will append
* may also append stats or anything else it likes * may also append stats or anything else it likes
*/ */
void appendResults( BSONObjBuilder& b ); void appendResults( BSONObjBuilder& b );
skipping to change at line 307 skipping to change at line 312
long long numEmits() const { if (_jsMode) return _scope->getNum berLongLong("_emitCt"); return _numEmits; } long long numEmits() const { if (_jsMode) return _scope->getNum berLongLong("_emitCt"); return _numEmits; }
long long numReduces() const { if (_jsMode) return _scope->getN umberLongLong("_redCt"); return _config.reducer->numReduces; } long long numReduces() const { if (_jsMode) return _scope->getN umberLongLong("_redCt"); return _config.reducer->numReduces; }
long long numInMemKeys() const { if (_jsMode) return _scope->ge tNumberLongLong("_keyCt"); return _temp->size(); } long long numInMemKeys() const { if (_jsMode) return _scope->ge tNumberLongLong("_keyCt"); return _temp->size(); }
bool jsMode() {return _jsMode;} bool jsMode() {return _jsMode;}
void switchMode(bool jsMode); void switchMode(bool jsMode);
void bailFromJS(); void bailFromJS();
const Config& _config; const Config& _config;
DBDirectClient _db; DBDirectClient _db;
bool _useIncremental; // use an incremental collection
protected: protected:
void _add( InMemory* im , const BSONObj& a , long& size ); void _add( InMemory* im , const BSONObj& a , long& size );
scoped_ptr<Scope> _scope; scoped_ptr<Scope> _scope;
bool _onDisk; // if the end result of this map reduce is disk o r not bool _onDisk; // if the end result of this map reduce is disk o r not
scoped_ptr<InMemory> _temp; scoped_ptr<InMemory> _temp;
long _size; // bytes in _temp long _size; // bytes in _temp
 End of changes. 3 change blocks. 
1 lines changed or deleted 7 lines changed or added


 namespace_details-inl.h   namespace_details-inl.h 
skipping to change at line 95 skipping to change at line 95
// @return offset in indexes[] // @return offset in indexes[]
inline int NamespaceDetails::findIndexByName(const char *name) { inline int NamespaceDetails::findIndexByName(const char *name) {
IndexIterator i = ii(); IndexIterator i = ii();
while( i.more() ) { while( i.more() ) {
if ( strcmp(i.next().info.obj().getStringField("name"),name) == 0 ) if ( strcmp(i.next().info.obj().getStringField("name"),name) == 0 )
return i.pos()-1; return i.pos()-1;
} }
return -1; return -1;
} }
inline NamespaceDetails::IndexIterator::IndexIterator(NamespaceDetails inline NamespaceDetails::IndexIterator::IndexIterator(NamespaceDetails
*_d) { *_d,
bool includeBackg
roundInProgress) {
d = _d; d = _d;
i = 0; i = 0;
n = d->nIndexes; n = includeBackgroundInProgress ? d->getTotalIndexCount() : d->nInd exes;
} }
} }
 End of changes. 2 change blocks. 
3 lines changed or deleted 5 lines changed or added


 namespace_details.h   namespace_details.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 "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_set.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/mongommf.h" #include "mongo/db/mongommf.h"
#include "mongo/db/namespace.h" #include "mongo/db/namespace.h"
#include "mongo/db/namespacestring.h" #include "mongo/db/namespacestring.h"
#include "mongo/db/queryoptimizercursor.h" #include "mongo/db/queryoptimizercursor.h"
#include "mongo/db/querypattern.h" #include "mongo/db/querypattern.h"
#include "mongo/platform/unordered_map.h" #include "mongo/platform/unordered_map.h"
#include "mongo/util/hashtab.h" #include "mongo/util/hashtab.h"
namespace mongo { namespace mongo {
skipping to change at line 209 skipping to change at line 210
class IndexIterator { class IndexIterator {
public: public:
int pos() { return i; } // note this is the next one to come int pos() { return i; } // note this is the next one to come
bool more() { return i < n; } bool more() { return i < n; }
IndexDetails& next() { return d->idx(i++); } IndexDetails& next() { return d->idx(i++); }
private: private:
friend class NamespaceDetails; friend class NamespaceDetails;
int i, n; int i, n;
NamespaceDetails *d; NamespaceDetails *d;
IndexIterator(NamespaceDetails *_d); IndexIterator(NamespaceDetails *_d, bool includeBackgroundInPro gress);
}; };
IndexIterator ii() { return IndexIterator(this); } IndexIterator ii( bool includeBackgroundInProgress = false ) {
return IndexIterator(this, includeBackgroundInProgress);
}
/* hackish - find our index # in the indexes array */ /* hackish - find our index # in the indexes array */
int idxNo(const IndexDetails& idx); int idxNo(const IndexDetails& idx);
/* multikey indexes are indexes where there are more than one key i n the index /* multikey indexes are indexes where there are more than one key i n the index
for a single document. see multikey in wiki. for a single document. see multikey in docs.
for these, we have to do some dedup work on queries. for these, we have to do some dedup work on queries.
*/ */
bool isMultikey(int i) const { return (multiKeyIndexBits & (((unsig ned long long) 1) << i)) != 0; } bool isMultikey(int i) const { return (multiKeyIndexBits & (((unsig ned long long) 1) << i)) != 0; }
void setIndexIsMultikey(const char *thisns, int i, bool multikey = true); void setIndexIsMultikey(const char *thisns, int i, bool multikey = true);
/** /**
* This fetches the IndexDetails for the next empty index slot. The caller must populate * This fetches the IndexDetails for the next empty index slot. The caller must populate
* returned object. This handles allocating extra index space, if necessary. * returned object. This handles allocating extra index space, if necessary.
*/ */
IndexDetails& getNextIndexDetails(const char* thisns); IndexDetails& getNextIndexDetails(const char* thisns);
skipping to change at line 533 skipping to change at line 536
* It is possible no cursor is returned if the sort is not supporte d by an index. Clients are responsible * It is possible no cursor is returned if the sort is not supporte d by an index. Clients are responsible
* for checking this if they are not sure an index for a sort exist s, and defaulting to a non-sort if * for checking this if they are not sure an index for a sort exist s, and defaulting to a non-sort if
* no suitable indices exist. * no suitable indices exist.
*/ */
static shared_ptr<Cursor> bestGuessCursor( const char *ns, const BS ONObj &query, const BSONObj &sort ); static shared_ptr<Cursor> bestGuessCursor( const char *ns, const BS ONObj &query, const BSONObj &sort );
/* indexKeys() cache ---------------------------------------------- ------ */ /* indexKeys() cache ---------------------------------------------- ------ */
/* assumed to be in write lock for this */ /* assumed to be in write lock for this */
private: private:
bool _keysComputed; bool _keysComputed;
set<string> _indexKeys; IndexPathSet _indexedPaths;
void computeIndexKeys(); void computeIndexKeys();
public: public:
/* get set of index keys for this namespace. handy to quickly chec k if a given /* get set of index keys for this namespace. handy to quickly chec k if a given
field is indexed (Note it might be a secondary component of a co mpound index.) field is indexed (Note it might be a secondary component of a co mpound index.)
*/ */
set<string>& indexKeys() { const IndexPathSet& indexKeys() {
DEV Lock::assertWriteLocked(_ns); DEV Lock::assertWriteLocked(_ns);
if ( !_keysComputed ) if ( !_keysComputed )
computeIndexKeys(); computeIndexKeys();
return _indexKeys; return _indexedPaths;
} }
/* IndexSpec caching */ /* IndexSpec caching */
private: private:
map<const IndexDetails*,IndexSpec> _indexSpecs; map<const IndexDetails*,IndexSpec> _indexSpecs;
static SimpleMutex _isMutex; static SimpleMutex _isMutex;
public: public:
const IndexSpec& getIndexSpec( const IndexDetails * details ) { const IndexSpec& getIndexSpec( const IndexDetails * details ) {
IndexSpec& spec = _indexSpecs[details]; IndexSpec& spec = _indexSpecs[details];
if ( ! spec._finishedInit ) { if ( ! spec._finishedInit ) {
 End of changes. 7 change blocks. 
6 lines changed or deleted 9 lines changed or added


 namespacestring.h   namespacestring.h 
skipping to change at line 72 skipping to change at line 72
bool operator!=( const string& nsIn ) const { return nsIn != ns(); } bool operator!=( const string& nsIn ) const { return nsIn != ns(); }
bool operator!=( const char* nsIn ) const { return (string)nsIn != ns(); } bool operator!=( const char* nsIn ) const { return (string)nsIn != ns(); }
bool operator!=( const NamespaceString& nsIn ) const { return nsIn. db != db || nsIn.coll != coll; } bool operator!=( const NamespaceString& nsIn ) const { return nsIn. db != db || nsIn.coll != coll; }
size_t size() const { return ns().size(); } size_t size() const { return ns().size(); }
string toString() const { return ns(); } string toString() const { return ns(); }
/** /**
* @return true if ns is 'normal'. $ used for collections holding * @return true if ns is 'normal'. A "$" is used for namespaces ho
index data, which do not contain BSON objects in their records. lding index data,
* special case for the local.oplog.$main ns -- naming it as such w * which do not contain BSON objects in their records. ("oplog.$mai
as a mistake. n" is the exception)
*/ */
static bool normal(const char* ns) { static bool normal(const char* ns) {
const char *p = strchr(ns, '$'); const char *p = strchr(ns, '$');
if( p == 0 ) if( p == 0 )
return true; return true;
return strcmp( ns, "local.oplog.$main" ) == 0; return oplog(ns);
}
/**
* @return true if the ns is an oplog one, otherwise false.
*/
static bool oplog(const char* ns) {
return StringData(ns) == StringData("local.oplog.rs") || String
Data(ns) == StringData("local.oplog.$main");
} }
static bool special(const char *ns) { static bool special(const char *ns) {
return !normal(ns) || strstr(ns, ".system."); return !normal(ns) || strstr(ns, ".system.");
} }
/** /**
* samples: * samples:
* good: * good:
* foo * foo
 End of changes. 2 change blocks. 
5 lines changed or deleted 13 lines changed or added


 oid.h   oid.h 
skipping to change at line 150 skipping to change at line 150
static unsigned ourPid(); static unsigned ourPid();
static void foldInPid(MachineAndPid& x); static void foldInPid(MachineAndPid& x);
static MachineAndPid genMachineAndPid(); static MachineAndPid genMachineAndPid();
}; };
#pragma pack() #pragma pack()
std::ostream& operator<<( std::ostream &s, const OID &o ); std::ostream& operator<<( std::ostream &s, const OID &o );
inline StringBuilder& operator<< (StringBuilder& s, const OID& o) { ret urn (s << o.str()); } inline StringBuilder& operator<< (StringBuilder& s, const OID& o) { ret urn (s << o.str()); }
/** Formatting mode for generating JSON from BSON. /** Formatting mode for generating JSON from BSON.
See <http://mongodb.onconfluence.com/display/DOCS/Mongo+Extended+JS ON> See <http://dochub.mongodb.org/core/mongodbextendedjson>
for details. for details.
*/ */
enum JsonStringFormat { enum JsonStringFormat {
/** strict RFC format */ /** strict RFC format */
Strict, Strict,
/** 10gen format, which is close to JS format. This form is unders tandable by /** 10gen format, which is close to JS format. This form is unders tandable by
javascript running inside the Mongo server via eval() */ javascript running inside the Mongo server via eval() */
TenGen, TenGen,
/** Javascript JSON compatible */ /** Javascript JSON compatible */
JS JS
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 oplogreader.h   oplogreader.h 
skipping to change at line 108 skipping to change at line 108
bool more() { bool more() {
uassert( 15910, "Doesn't have cursor for reading oplog", cursor .get() ); uassert( 15910, "Doesn't have cursor for reading oplog", cursor .get() );
return cursor->more(); return cursor->more();
} }
bool moreInCurrentBatch() { bool moreInCurrentBatch() {
uassert( 15911, "Doesn't have cursor for reading oplog", cursor .get() ); uassert( 15911, "Doesn't have cursor for reading oplog", cursor .get() );
return cursor->moreInCurrentBatch(); return cursor->moreInCurrentBatch();
} }
int currentBatchMessageSize() {
if( NULL == cursor->getMessage() )
return 0;
return cursor->getMessage()->size();
}
/* old mongod's can't do the await flag... */ /* old mongod's can't do the await flag... */
bool awaitCapable() { bool awaitCapable() {
return cursor->hasResultFlag(ResultFlag_AwaitCapable); return cursor->hasResultFlag(ResultFlag_AwaitCapable);
} }
int getTailingQueryOptions() const { return _tailingQueryOptions; } int getTailingQueryOptions() const { return _tailingQueryOptions; }
void setTailingQueryOptions( int tailingQueryOptions ) { _tailingQu eryOptions = tailingQueryOptions; } void setTailingQueryOptions( int tailingQueryOptions ) { _tailingQu eryOptions = tailingQueryOptions; }
void peek(vector<BSONObj>& v, int n) { void peek(vector<BSONObj>& v, int n) {
if( cursor.get() ) if( cursor.get() )
 End of changes. 1 change blocks. 
0 lines changed or deleted 6 lines changed or added


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


 pdfile.h   pdfile.h 
skipping to change at line 36 skipping to change at line 36
#pragma once #pragma once
#include "mongo/db/client.h" #include "mongo/db/client.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/mongommf.h"
#include "mongo/db/namespace-inl.h" #include "mongo/db/namespace-inl.h"
#include "mongo/db/namespace_details-inl.h" #include "mongo/db/namespace_details-inl.h"
#include "mongo/db/namespacestring.h" #include "mongo/db/namespacestring.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 {
// pdfile versions
const int PDFILE_VERSION = 4;
const int PDFILE_VERSION_MINOR = 5;
class Cursor; class Cursor;
class DataFileHeader; class DataFileHeader;
class Extent; class Extent;
class OpDebug; class OpDebug;
class Record; class Record;
struct SortPhaseOne; struct SortPhaseOne;
void dropDatabase(const std::string& db); void dropDatabase(const std::string& db);
bool repairDatabase(string db, string &errmsg, bool preserveClonedFiles OnFailure = false, bool backupOriginalFiles = false); bool repairDatabase(string db, string &errmsg, bool preserveClonedFiles OnFailure = false, bool backupOriginalFiles = false);
skipping to change at line 466 skipping to change at line 463
int versionMinor; int versionMinor;
int fileLength; int fileLength;
DiskLoc unused; /* unused is the portion of the file that doesn't b elong to any allocated extents. -1 = no more */ DiskLoc unused; /* unused is the portion of the file that doesn't b elong to any allocated extents. -1 = no more */
int unusedLength; int unusedLength;
char reserved[8192 - 4*4 - 8]; char reserved[8192 - 4*4 - 8];
char data[4]; // first extent starts here char data[4]; // first extent starts here
enum { HeaderSize = 8192 }; enum { HeaderSize = 8192 };
bool isCurrentVersion() const { return ( version == PDFILE_VERSION bool isCurrentVersion() const {
) && ( versionMinor == PDFILE_VERSION_MINOR ); } 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; } bool uninitialized() const { return version == 0; }
void init(int fileno, int filelength, const char* filename) { void init(int fileno, int filelength, const char* filename) {
if ( uninitialized() ) { if ( uninitialized() ) {
DEV log() << "datafileheader::init initializing " << filena me << " n:" << fileno << endl; DEV log() << "datafileheader::init initializing " << filena me << " n:" << fileno << endl;
if( !(filelength > 32768 ) ) { if( !(filelength > 32768 ) ) {
massert(13640, str::stream() << "DataFileHeader looks c orrupt at file open filelength:" << filelength << " fileno:" << fileno, fal se); massert(13640, str::stream() << "DataFileHeader looks c orrupt at file open filelength:" << filelength << " fileno:" << fileno, fal se);
} }
skipping to change at line 497 skipping to change at line 498
::abort(); ::abort();
**/ **/
} }
} }
getDur().createdFile(filename, filelength); getDur().createdFile(filename, filelength);
verify( HeaderSize == 8192 ); verify( HeaderSize == 8192 );
DataFileHeader *h = getDur().writing(this); DataFileHeader *h = getDur().writing(this);
h->fileLength = filelength; h->fileLength = filelength;
h->version = PDFILE_VERSION; h->version = PDFILE_VERSION;
h->versionMinor = PDFILE_VERSION_MINOR; h->versionMinor = PDFILE_VERSION_MINOR_22_AND_OLDER; // All dbs start like this
h->unused.set( fileno, HeaderSize ); h->unused.set( fileno, HeaderSize );
verify( (data-(char*)this) == HeaderSize ); verify( (data-(char*)this) == HeaderSize );
h->unusedLength = fileLength - HeaderSize - 16; h->unusedLength = fileLength - HeaderSize - 16;
} }
} }
bool isEmpty() const { bool isEmpty() const {
return uninitialized() || ( unusedLength == fileLength - Header Size - 16 ); return uninitialized() || ( unusedLength == fileLength - Header Size - 16 );
} }
}; };
 End of changes. 4 change blocks. 
7 lines changed or deleted 9 lines changed or added


 query.h   query.h 
skipping to change at line 37 skipping to change at line 37
#include "../../s/d_chunk_manager.h" #include "../../s/d_chunk_manager.h"
// struct QueryOptions, QueryResult, QueryResultFlags in: // struct QueryOptions, QueryResult, QueryResultFlags in:
namespace mongo { namespace mongo {
class ParsedQuery; class ParsedQuery;
class QueryOptimizerCursor; class QueryOptimizerCursor;
class QueryPlanSummary; class QueryPlanSummary;
QueryResult* processGetMore(const char *ns, int ntoreturn, long long cu /**
rsorid , CurOp& op, int pass, bool& exhaust); * Return a batch of results from a client OP_GET_MORE request.
* 'cursorid' - The id of the cursor producing results.
* 'isCursorAuthorized' - Set to true after a cursor with id 'cursorid'
is authorized for use.
*/
QueryResult* processGetMore(const char* ns,
int ntoreturn,
long long cursorid,
CurOp& op,
int pass,
bool& exhaust,
bool* isCursorAuthorized);
string runQuery(Message& m, QueryMessage& q, CurOp& curop, Message &res ult); string runQuery(Message& m, QueryMessage& q, CurOp& curop, Message &res ult);
/** Exception indicating that a query should be retried from the beginn ing. */ /** Exception indicating that a query should be retried from the beginn ing. */
class QueryRetryException : public DBException { class QueryRetryException : public DBException {
public: public:
QueryRetryException() : DBException( "query retry exception" , 1608 3 ) { QueryRetryException() : DBException( "query retry exception" , 1608 3 ) {
return; return;
massert( 16083, "reserve 16083", true ); // Reserve 16083. massert( 16083, "reserve 16083", true ); // Reserve 16083.
} }
 End of changes. 1 change blocks. 
2 lines changed or deleted 13 lines changed or added


 queryutil.h   queryutil.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 "jsobj.h" #include "jsobj.h"
#include "indexkey.h" #include "indexkey.h"
#include "projection.h" #include "projection.h"
#include "mongo/client/dbclientinterface.h"
namespace mongo { namespace mongo {
extern const int MaxBytesToReturnToClientAtOnce; extern const int MaxBytesToReturnToClientAtOnce;
//maximum number of intervals produced by $in queries. //maximum number of intervals produced by $in queries.
static const unsigned MAX_IN_COMBINATIONS = 4000000; static const unsigned MAX_IN_COMBINATIONS = 4000000;
/* This is for languages whose "objects" are not well ordered (JSON is well ordered). /* This is for languages whose "objects" are not well ordered (JSON is well ordered).
[ { a : ... } , { b : ... } ] -> { a : ..., b : ... } [ { a : ... } , { b : ... } ] -> { a : ..., b : ... }
skipping to change at line 158 skipping to change at line 159
if ( e.isABSONObj() ) { if ( e.isABSONObj() ) {
_filter = e.embeddedObject(); _filter = e.embeddedObject();
_initTop( q ); _initTop( q );
} }
else { else {
_filter = q; _filter = q;
} }
_filter = _filter.getOwned(); _filter = _filter.getOwned();
_hasReadPref = q.hasField("$readPreference"); _hasReadPref = q.hasField(Query::ReadPrefField.name());
} }
void _reset() { void _reset() {
_wantMore = true; _wantMore = true;
_explain = false; _explain = false;
_snapshot = false; _snapshot = false;
_returnKey = false; _returnKey = false;
_showDiskLoc = false; _showDiskLoc = false;
_maxScan = 0; _maxScan = 0;
} }
 End of changes. 2 change blocks. 
1 lines changed or deleted 2 lines changed or added


 queue.h   queue.h 
skipping to change at line 37 skipping to change at line 37
#include "mongo/util/timer.h" #include "mongo/util/timer.h"
namespace mongo { namespace mongo {
template <typename T> template <typename T>
size_t _getSizeDefault(const T& t) { size_t _getSizeDefault(const T& t) {
return 1; return 1;
} }
/** /**
* Simple blocking queue with optional max size. * Simple blocking queue with optional max size (by count or custom siz
* A custom sizing function can optionally be given. By default, size ing function).
is calculated as * A custom sizing function can optionally be given. By default the ge
* _queue.size(). tSize function
* returns 1 for each item, resulting in size equaling the number of it
ems queued.
*/ */
template<typename T> template<typename T>
class BlockingQueue : boost::noncopyable { class BlockingQueue : boost::noncopyable {
typedef size_t (*getSizeFunc)(const T& t); typedef size_t (*getSizeFunc)(const T& t);
public: public:
BlockingQueue() : BlockingQueue() :
_lock("BlockingQueue"), _lock("BlockingQueue"),
_maxSize(std::numeric_limits<std::size_t>::max()), _maxSize(std::numeric_limits<std::size_t>::max()),
_currentSize(0), _currentSize(0),
_getSize(&_getSizeDefault) {} _getSize(&_getSizeDefault) {}
skipping to change at line 77 skipping to change at line 77
_queue.push( t ); _queue.push( t );
_currentSize += tSize; _currentSize += tSize;
_cvNoLongerEmpty.notify_one(); _cvNoLongerEmpty.notify_one();
} }
bool empty() const { bool empty() const {
scoped_lock l( _lock ); scoped_lock l( _lock );
return _queue.empty(); return _queue.empty();
} }
/**
* The size as measured by the size function. Default to counting e
ach item
*/
size_t size() const { size_t size() const {
scoped_lock l( _lock ); scoped_lock l( _lock );
return _currentSize; return _currentSize;
} }
/**
* The max size for this queue
*/
size_t maxSize() const {
return _maxSize;
}
/**
* The number/count of items in the queue ( _queue.size() )
*/
int count() const {
scoped_lock l( _lock );
return _queue.size();
}
void clear() { void clear() {
scoped_lock l(_lock); scoped_lock l(_lock);
_queue = std::queue<T>(); _queue = std::queue<T>();
_currentSize = 0; _currentSize = 0;
} }
bool tryPop( T & t ) { bool tryPop( T & t ) {
scoped_lock l( _lock ); scoped_lock l( _lock );
if ( _queue.empty() ) if ( _queue.empty() )
return false; return false;
 End of changes. 3 change blocks. 
4 lines changed or deleted 25 lines changed or added


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


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


 rs.h   rs.h 
skipping to change at line 491 skipping to change at line 491
// this is called from within a writelock in logOpRS // this is called from within a writelock in logOpRS
unsigned selfId() const { return _id; } unsigned selfId() const { return _id; }
Manager *mgr; Manager *mgr;
GhostSync *ghost; GhostSync *ghost;
/** /**
* This forces a secondary to go into recovering state and stay the re * This forces a secondary to go into recovering state and stay the re
* until this is called again, passing in "false". Multiple thread s can * until this is called again, passing in "false". Multiple thread s can
* call this and it will leave maintenance mode once all of the cal lers * call this and it will leave maintenance mode once all of the cal lers
* have called it again, passing in false. * have called it again, passing in false.
*/ */
void setMaintenanceMode(const bool inc); bool setMaintenanceMode(const bool inc);
private: private:
Member* head() const { return _members.head(); } Member* head() const { return _members.head(); }
public: public:
const Member* findById(unsigned id) const; const Member* findById(unsigned id) const;
Member* findByName(const std::string& hostname) const; 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;
skipping to change at line 546 skipping to change at line 546
} }
IndexPrefetchConfig getIndexPrefetchConfig() { IndexPrefetchConfig getIndexPrefetchConfig() {
return _indexPrefetchConfig; return _indexPrefetchConfig;
} }
static const int replWriterThreadCount; static const int replWriterThreadCount;
static const int replPrefetcherThreadCount; static const int replPrefetcherThreadCount;
threadpool::ThreadPool& getPrefetchPool() { return _prefetcherPool; } threadpool::ThreadPool& getPrefetchPool() { return _prefetcherPool; }
threadpool::ThreadPool& getWriterPool() { return _writerPool; } threadpool::ThreadPool& getWriterPool() { return _writerPool; }
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;
/** /**
* 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 (if no minValid is set, thi * set as the last step in initial sync. At the beginning of initi
s indicates that initial al sync, _initialSyncFlag
* sync is necessary). It is also used during "normal" sync: the la * is appended onto minValid to indicate that initial sync was star
st op in each batch is ted but has not yet
* used to set minValid, to indicate that we are in a consistent st * completed.
ate when the batch has * minValid is also used during "normal" sync: the last op in each
* been fully applied. batch is used to set
* minValid, to indicate that we are in a consistent state when the
batch has been fully
* applied.
*/ */
static void setMinValid(BSONObj obj); static void setMinValid(BSONObj obj);
static OpTime getMinValid(); static OpTime getMinValid();
static void clearInitialSyncFlag();
static bool getInitialSyncFlag();
static void setInitialSyncFlag();
int oplogVersion; int oplogVersion;
private: private:
IndexPrefetchConfig _indexPrefetchConfig; IndexPrefetchConfig _indexPrefetchConfig;
static const char* _initialSyncFlagString;
static const BSONObj _initialSyncFlag;
}; };
class ReplSet : public ReplSetImpl { class ReplSet : public ReplSetImpl {
public: public:
static ReplSet* make(ReplSetCmdline& replSetCmdline); static ReplSet* make(ReplSetCmdline& replSetCmdline);
virtual ~ReplSet() {} virtual ~ReplSet() {}
// for the replSetStepDown command // for the replSetStepDown command
bool stepDown(int secs) { return _stepDown(secs); } bool stepDown(int secs) { return _stepDown(secs); }
 End of changes. 5 change blocks. 
8 lines changed or deleted 19 lines changed or added


 s2cellid.h   s2cellid.h 
skipping to change at line 243 skipping to change at line 243
// These methods guarantee that FromToken(ToToken(x)) == x even when // These methods guarantee that FromToken(ToToken(x)) == x even when
// "x" is an invalid cell id. All tokens are alphanumeric strings. // "x" is an invalid cell id. All tokens are alphanumeric strings.
// FromToken() returns S2CellId::None() for malformed inputs. // FromToken() returns S2CellId::None() for malformed inputs.
string ToToken() const; string ToToken() const;
static S2CellId FromToken(string const& token); static S2CellId FromToken(string const& token);
// Creates a debug human readable string. Used for << and available for d irect // Creates a debug human readable string. Used for << and available for d irect
// usage as well. // usage as well.
string ToString() const; string ToString() const;
string toString() const { return ToString(); } string toString() const { return ToString(); }
string slowToString() const;
static S2CellId FromString(const string& str);
// Return the four cells that are adjacent across the cell's four edges. // Return the four cells that are adjacent across the cell's four edges.
// Neighbors are returned in the order defined by S2Cell::GetEdge. All // Neighbors are returned in the order defined by S2Cell::GetEdge. All
// neighbors are guaranteed to be distinct. // neighbors are guaranteed to be distinct.
void GetEdgeNeighbors(S2CellId neighbors[4]) const; void GetEdgeNeighbors(S2CellId neighbors[4]) const;
// Return the neighbors of closest vertex to this cell at the given level , // Return the neighbors of closest vertex to this cell at the given level ,
// by appending them to "output". Normally there are four neighbors, but // by appending them to "output". Normally there are four neighbors, but
// the closest vertex may only have three neighbors if it is one of the 8 // the closest vertex may only have three neighbors if it is one of the 8
// cube vertices. // cube vertices.
 End of changes. 1 change blocks. 
0 lines changed or deleted 2 lines changed or added


 s2common.h   s2common.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 "mongo/db/diskloc.h"
#include "mongo/db/geo/geoparser.h" #include "mongo/db/geo/geoparser.h"
#include "third_party/s2/s2.h" #include "third_party/s2/s2.h"
#include "third_party/s2/s2regioncoverer.h" #include "third_party/s2/s2regioncoverer.h"
#include "third_party/s2/s2cell.h" #include "third_party/s2/s2cell.h"
#include "third_party/s2/s2polyline.h" #include "third_party/s2/s2polyline.h"
#include "third_party/s2/s2polygon.h" #include "third_party/s2/s2polygon.h"
#include "third_party/s2/s2regioncoverer.h" #include "third_party/s2/s2regioncoverer.h"
#pragma once #pragma once
namespace mongo { namespace mongo {
// This is used by both s2cursor and s2nearcursor. // This is used by both s2cursor and s2nearcursor.
class S2SearchUtil { class S2SearchUtil {
public: public:
// Given a coverer, region, and field name, generate a BSONObj that we can pass to a // Given a coverer, region, and field name, generate a BSONObj that we can pass to a
// FieldRangeSet so that we only examine the keys that the provided region may intersect. // FieldRangeSet so that we only examine the keys that the provided region may intersect.
static BSONObj coverAsBSON(const vector<S2CellId> &cover, const str ing& field, static BSONObj coverAsBSON(const vector<S2CellId> &cover, const str ing& field,
const int coarsestIndexedLevel); const int coarsestIndexedLevel);
}; static void setCoverLimitsBasedOnArea(double area, S2RegionCoverer
*coverer, int coarsestIndexedLevel);
// Used for passing geo data from the newCursor entry point to the S2Cu
rsor class.
struct QueryGeometry {
QueryGeometry(const string& f) : field(f), predicate(INTERSECT) {}
enum Predicate {
WITHIN,
INTERSECT,
};
// Name of the field in the query.
string field;
// Only one of these should be non-NULL. S2Region is a superclass
but it only supports
// testing against S2Cells. We need the most specific class we can
get.
// Owned by S2Cursor.
shared_ptr<S2Cell> cell;
shared_ptr<S2Polyline> line;
shared_ptr<S2Polygon> polygon;
Predicate predicate;
string toString() const;
bool satisfiesPredicate(const BSONObj &obj);
// Does this QueryGeometry intersect the provided data? Sadly ther
e is no common good way
// to check this, so we do different things for all query/data pair
s.
bool intersects(const S2Cell& otherPoint);
bool intersects(const S2Polyline& otherLine);
bool intersects(const S2Polygon& otherPolygon);
// And, within.
bool isWithin(const S2Cell& otherPoint);
bool isWithin(const S2Polyline& otherLine);
bool isWithin(const S2Polygon& otherPolygon);
// One region is not NULL and this returns it.
const S2Region& getRegion() const;
// Get the centroid, boring if we're a point, interesting if we're
not.
S2Point getCentroid() const;
// Try to parse the provided object into the right place.
bool parseFrom(const BSONObj &obj);
}; };
struct S2IndexingParams { struct S2IndexingParams {
static const double kRadiusOfEarthInMeters;
// Since we take the cartesian product when we generate keys for an insert, // Since we take the cartesian product when we generate keys for an insert,
// we need a cap. // we need a cap.
size_t maxKeysPerInsert; size_t maxKeysPerInsert;
// This is really an advisory parameter that we pass to the cover g enerator. The // This is really an advisory parameter that we pass to the cover g enerator. The
// finest/coarsest index level determine the required # of cells. // finest/coarsest index level determine the required # of cells.
int maxCellsInCovering; int maxCellsInCovering;
// What's the finest grained level that we'll index? When we query for a point // What's the finest grained level that we'll index? When we query for a point
// we start at that -- we index nothing finer than this. // we start at that -- we index nothing finer than this.
int finestIndexedLevel; int finestIndexedLevel;
// And, what's the coarsest? When we search in larger coverings we know we // And, what's the coarsest? When we search in larger coverings we know we
 End of changes. 3 change blocks. 
46 lines changed or deleted 5 lines changed or added


 s2cursor.h   s2cursor.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/>.
*/ */
#include <vector> #include <vector>
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/commands.h" #include "mongo/db/commands.h"
#include "mongo/db/cursor.h" #include "mongo/db/cursor.h"
#include "mongo/db/diskloc.h" #include "mongo/db/diskloc.h"
#include "mongo/db/matcher.h" #include "mongo/db/matcher.h"
#include "mongo/db/queryutil.h" #include "mongo/db/queryutil.h"
#include "mongo/db/geo/geoquery.h"
#include "mongo/db/geo/s2common.h" #include "mongo/db/geo/s2common.h"
namespace mongo { namespace mongo {
class BtreeCursor; class BtreeCursor;
class S2Cursor : public Cursor { class S2Cursor : public Cursor {
public: public:
S2Cursor(const BSONObj &keyPattern, const IndexDetails* details, co nst BSONObj &query, S2Cursor(const BSONObj &keyPattern, const IndexDetails* details, co nst BSONObj &query,
const vector<QueryGeometry> &regions, const S2IndexingPara const vector<GeoQuery> &regions, const S2IndexingParams &p
ms &params, arams);
int numWanted);
virtual ~S2Cursor(); virtual ~S2Cursor();
virtual CoveredIndexMatcher *matcher() const; virtual CoveredIndexMatcher *matcher() const;
virtual bool supportYields() { return true; } virtual bool supportYields() { return true; }
virtual bool supportGetMore() { return true; } virtual bool supportGetMore() { return true; }
virtual bool isMultiKey() const { return true; } virtual bool isMultiKey() const { return true; }
virtual bool autoDedup() const { return false; } virtual bool autoDedup() const { return false; }
virtual bool modifiedKeys() const { return true; } virtual bool modifiedKeys() const { return true; }
virtual bool getsetdup(DiskLoc loc) { return false; } virtual bool getsetdup(DiskLoc loc) { return false; }
virtual string toString() { return "S2Cursor"; } virtual string toString() { return "S2Cursor"; }
skipping to change at line 68 skipping to change at line 68
// It's kind of a monstrous object. Thanks, FieldRangeSet, for doi ng all the work // It's kind of a monstrous object. Thanks, FieldRangeSet, for doi ng all the work
// for us. // for us.
// Returns false if the FRS object would be empty. // Returns false if the FRS object would be empty.
bool makeFRSObject(BSONObj *out); bool makeFRSObject(BSONObj *out);
// Need this to make a FieldRangeSet. // Need this to make a FieldRangeSet.
const IndexDetails *_details; const IndexDetails *_details;
// The query with the geo stuff taken out. We use this with a matc her. // The query with the geo stuff taken out. We use this with a matc her.
BSONObj _filteredQuery; BSONObj _filteredQuery;
// What geo regions are we looking for? // What geo regions are we looking for?
vector<QueryGeometry> _fields; vector<GeoQuery> _fields;
// We use this for matching non-GEO stuff. // We use this for matching non-GEO stuff.
shared_ptr<CoveredIndexMatcher> _matcher; shared_ptr<CoveredIndexMatcher> _matcher;
// How were the keys created? We need this to search for the right stuff. // How were the keys created? We need this to search for the right stuff.
S2IndexingParams _params; S2IndexingParams _params;
// How many things did we scan/look at? Not sure exactly how this
is defined.
long long _nscanned;
// We have to pass this to the FieldRangeVector ctor (in modified f orm). // We have to pass this to the FieldRangeVector ctor (in modified f orm).
BSONObj _keyPattern; BSONObj _keyPattern;
// How many docs do we want to return? Starts with the # the user
requests
// and goes down.
int _numToReturn;
// What have we checked so we don't repeat it and waste time? // What have we checked so we don't repeat it and waste time?
set<DiskLoc> _seen; set<DiskLoc> _seen;
// This really does all the work/points into the btree. // This really does all the work/points into the btree.
scoped_ptr<BtreeCursor> _btreeCursor; scoped_ptr<BtreeCursor> _btreeCursor;
// Stat counters/debug information goes below.
// How many items did we look at in the btree?
long long _nscanned;
// How many did we try to match?
long long _matchTested;
// How many did we geo-test?
long long _geoTested;
// How many cells were in our cover?
long long _cellsInCover;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 6 change blocks. 
11 lines changed or deleted 14 lines changed or added


 s2index.h   s2index.h 
skipping to change at line 18 skipping to change at line 18
* 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/>.
*/ */
namespace mongo { namespace mongo {
bool run2DSphereGeoNear(const IndexDetails &id, BSONObj& cmdObj, string // We need cmdObj and parsedArgs so we can print a useful error msg.
& errmsg, bool run2DSphereGeoNear(const IndexDetails &id, BSONObj& cmdObj,
const GeoNearArguments &parsedArgs, string& err
msg,
BSONObjBuilder& result); BSONObjBuilder& result);
} // namespace mongo } // namespace mongo
 End of changes. 1 change blocks. 
2 lines changed or deleted 4 lines changed or added


 s2nearcursor.h   s2nearcursor.h 
skipping to change at line 26 skipping to change at line 26
#include <vector> #include <vector>
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/commands.h" #include "mongo/db/commands.h"
#include "mongo/db/btreecursor.h" #include "mongo/db/btreecursor.h"
#include "mongo/db/cursor.h" #include "mongo/db/cursor.h"
#include "mongo/db/diskloc.h" #include "mongo/db/diskloc.h"
#include "mongo/db/matcher.h" #include "mongo/db/matcher.h"
#include "mongo/db/queryutil.h" #include "mongo/db/queryutil.h"
#include "mongo/db/geo/s2common.h" #include "mongo/db/geo/s2common.h"
#include "mongo/db/geo/geoquery.h"
#include "mongo/platform/unordered_set.h"
#include "third_party/s2/s2cap.h"
#include "third_party/s2/s2regionintersection.h"
namespace mongo { namespace mongo {
class S2NearCursor : public Cursor { class S2NearCursor : public Cursor {
public: public:
S2NearCursor(const BSONObj &keyPattern, const IndexDetails* details , const BSONObj &query, S2NearCursor(const BSONObj &keyPattern, const IndexDetails* details , const BSONObj &query,
const vector<QueryGeometry> &regions, const S2Indexing const NearQuery &nearQuery, const vector<GeoQuery> &in
Params &params, dexedGeoRegions,
int numWanted, double maxDistance); const S2IndexingParams &params);
virtual ~S2NearCursor(); virtual ~S2NearCursor();
virtual CoveredIndexMatcher *matcher() const; virtual CoveredIndexMatcher *matcher() const;
virtual bool supportYields() { return true; } virtual bool supportYields() { return true; }
virtual bool supportGetMore() { return true; } virtual bool supportGetMore() { return true; }
virtual bool isMultiKey() const { return true; } virtual bool isMultiKey() const { return true; }
virtual bool autoDedup() const { return false; } virtual bool autoDedup() const { return false; }
virtual bool modifiedKeys() const { return true; } virtual bool modifiedKeys() const { return true; }
virtual bool getsetdup(DiskLoc loc) { return false; } virtual bool getsetdup(DiskLoc loc) { return false; }
virtual string toString() { return "S2NearCursor"; } virtual string toString() { return "S2NearCursor"; }
skipping to change at line 81 skipping to change at line 85
// Make the object that describes all keys that are within our curr ent search annulus. // Make the object that describes all keys that are within our curr ent search annulus.
BSONObj makeFRSObject(); BSONObj makeFRSObject();
// Fill _results with all of the results in the annulus defined by _innerRadius and // Fill _results with all of the results in the annulus defined by _innerRadius and
// _outerRadius. If no results are found, grow the annulus and rep eat until success (or // _outerRadius. If no results are found, grow the annulus and rep eat until success (or
// until the edge of the world). // until the edge of the world).
void fillResults(); void fillResults();
// Grow _innerRadius and _outerRadius by _radiusIncrement, capping _outerRadius at halfway // Grow _innerRadius and _outerRadius by _radiusIncrement, capping _outerRadius at halfway
// around the world (pi * _params.radius). // around the world (pi * _params.radius).
void nextAnnulus(); void nextAnnulus();
double distanceBetween(const QueryGeometry &field, const BSONObj &o bj); double distanceTo(const BSONObj &obj);
// Need this to make a FieldRangeSet. // Need this to make a FieldRangeSet.
const IndexDetails *_details; const IndexDetails *_details;
// How we need/use the query: // How we need/use the query:
// Matcher: Can have geo fields in it, but only with $within. // Matcher: Can have geo fields in it, but only with $within.
// This only really happens (right now) from geoNear comma nd. // This only really happens (right now) from geoNear comma nd.
// We assume the caller takes care of this in the right wa y. // We assume the caller takes care of this in the right wa y.
// FRS: No geo fields allowed! // FRS: No geo fields allowed!
// So, on that note: the query with the geo stuff taken out, used b y makeFRSObject(). // So, on that note: the query with the geo stuff taken out, used b y makeFRSObject().
BSONObj _filteredQuery; BSONObj _filteredQuery;
// The GeoQuery for the point we're doing near searching from.
NearQuery _nearQuery;
// What geo regions are we looking for? // What geo regions are we looking for?
vector<QueryGeometry> _fields; vector<GeoQuery> _indexedGeoFields;
// We use this for matching non-GEO stuff. // We use this for matching non-GEO stuff.
shared_ptr<CoveredIndexMatcher> _matcher; shared_ptr<CoveredIndexMatcher> _matcher;
// How were the keys created? We need this to search for the right stuff. // How were the keys created? We need this to search for the right stuff.
S2IndexingParams _params; S2IndexingParams _params;
// How many things did we scan/look at? Not sure exactly how this
is defined.
long long _nscanned;
// We have to pass this to the FieldRangeVector ctor (in modified f orm). // We have to pass this to the FieldRangeVector ctor (in modified f orm).
BSONObj _keyPattern; BSONObj _keyPattern;
// We also pass this to the FieldRangeVector ctor. // We also pass this to the FieldRangeVector ctor.
IndexSpec _specForFRV; IndexSpec _specForFRV;
// How many docs do we want to return? Starts with the # the user
requests and goes down.
int _numToReturn;
// Geo-related variables. // Geo-related variables.
// What's the max distance (arc length) we're willing to look for r esults? // What's the max distance (arc length) we're willing to look for r esults?
double _maxDistance; double _maxDistance;
// We compute an annulus of results and cache it here. // We compute an annulus of results and cache it here.
priority_queue<Result> _results; priority_queue<Result> _results;
// These radii define the annulus. // These radii define the annulus we're currently looking at.
double _innerRadius; double _innerRadius;
double _outerRadius; double _outerRadius;
// When we search the next annulus, what to adjust our radius by? Grows when we search an // When we search the next annulus, what to adjust our radius by? Grows when we search an
// annulus and find no results. // annulus and find no results.
double _radiusIncrement; double _radiusIncrement;
set<DiskLoc> _returned; // What have we returned already?
unordered_set<DiskLoc, DiskLoc::Hasher> _returned;
struct Stats {
Stats() : _nscanned(0), _matchTested(0), _geoMatchTested(0), _n
umShells(0),
_keyGeoSkip(0), _returnSkip(0), _btreeDups(0), _inAnn
ulusTested(0),
_numReturned(0) {}
// Stat counters/debug information goes below.
// How many items did we look at in the btree?
long long _nscanned;
// How many did we try to match?
long long _matchTested;
// How many did we geo-test?
long long _geoMatchTested;
// How many search shells did we use?
long long _numShells;
// How many did we skip due to key-geo check?
long long _keyGeoSkip;
long long _returnSkip;
long long _btreeDups;
long long _inAnnulusTested;
long long _numReturned;
};
Stats _stats;
// The S2 machinery that represents the search annulus
S2Cap _innerCap;
S2Cap _outerCap;
S2RegionIntersection _annulus;
// This is the "array index" of the key field that is the near fiel
d. We use this to do
// cheap is-this-doc-in-the-annulus testing.
int _nearFieldIndex;
// The max distance we've returned so far.
double _returnedDistance;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 9 change blocks. 
13 lines changed or deleted 50 lines changed or added


 sasl_client_authenticate.h   sasl_client_authenticate.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 "mongo/base/status.h" #include "mongo/base/status.h"
#include "mongo/bson/bsontypes.h" #include "mongo/bson/bsontypes.h"
#include "mongo/client/dbclientinterface.h" #include "mongo/client/dbclientinterface.h"
struct Gsasl;
namespace mongo { namespace mongo {
class BSONObj; class BSONObj;
/** /**
* Attempts to authenticate "client" using the SASL protocol. * Attempts to authenticate "client" using the SASL protocol.
* *
* Requires an initialized instance of the "gsasl" library, as the firs * Do not use directly in client code. Use the DBClientWithCommands::a
t uth(const BSONObj&)
* parameter. * method, instead.
*
* Test against NULL for availability. Client driver must be compiled
with SASL support _and_
* client application must have successfully executed mongo::runGlobalI
nitializersOrDie() or its
* ilk to make this functionality available.
* *
* The "saslParameters" BSONObj should be initialized with zero or more of the * The "saslParameters" BSONObj should be initialized with zero or more of the
* fields below. Which fields are required depends on the mechanism. Consult the * fields below. Which fields are required depends on the mechanism. Consult the
* libgsasl documentation. * libgsasl documentation.
* *
* "mechanism": The string name of the sasl mechanism to use. Mand atory. * "mechanism": The string name of the sasl mechanism to use. Mand atory.
* "autoAuthorize": Truthy values tell the server to automatically acquire privileges on * "autoAuthorize": Truthy values tell the server to automatically acquire privileges on
* all resources after successful authentication, which is the default. Falsey values * all resources after successful authentication, which is the default. Falsey values
* instruct the server to await separate privilege-acquisition commands. * instruct the server to await separate privilege-acquisition commands.
* "user": The string name of the principal to authenticate, GSASL_ AUTHID. * "user": The string name of the principal to authenticate, GSASL_ AUTHID.
* "userSource": The database target of the auth command, which ide ntifies the location * "userSource": The database target of the auth command, which ide ntifies the location
* of the credential information for the principal. May be "$s asl" if credential * of the credential information for the principal. May be "$e xternal" if credential
* information is stored outside of the mongo cluster. * information is stored outside of the mongo cluster.
* "pwd": The password data, GSASL_PASSWORD. * "pwd": The password data, GSASL_PASSWORD.
* "serviceName": The GSSAPI service name to use. Defaults to "mon godb". * "serviceName": The GSSAPI service name to use. Defaults to "mon godb".
* "serviceHostname": The GSSAPI hostname to use. Defaults to the name of the remote host. * "serviceHostname": The GSSAPI hostname to use. Defaults to the name of the remote host.
* *
* Other fields in saslParameters are silently ignored. * Other fields in saslParameters are silently ignored.
* *
* "sessionHook" is a pointer to optional data, which may be used by th e gsasl_callback * "sessionHook" is a pointer to optional data, which may be used by th e gsasl_callback
* previously set on "gsasl". The session hook is set on an underlying Gsasl_session using * previously set on "gsasl". The session hook is set on an underlying Gsasl_session using
* gsasl_session_hook_set, and may be accessed by callbacks using gsasl _session_hook_get. * gsasl_session_hook_set, and may be accessed by callbacks using gsasl _session_hook_get.
* See the gsasl documentation. * See the gsasl documentation.
* *
* Returns an OK status on success, and ErrorCodes::AuthenticationFaile d if authentication is * Returns an OK status on success, and ErrorCodes::AuthenticationFaile d if authentication is
* rejected. Other failures, all of which are tantamount to authentica tion failure, may also be * rejected. Other failures, all of which are tantamount to authentica tion failure, may also be
* returned. * returned.
*/ */
Status saslClientAuthenticate(Gsasl *gsasl, extern Status (*saslClientAuthenticate)(DBClientWithCommands* client,
DBClientWithCommands* client, const BSONObj& saslParameters,
const BSONObj& saslParameters, void* sessionHook);
void* sessionHook);
/** /**
* Extracts the payload field from "cmdObj", and store it into "*payloa d". * Extracts the payload field from "cmdObj", and store it into "*payloa d".
* *
* Sets "*type" to the BSONType of the payload field in cmdObj. * Sets "*type" to the BSONType of the payload field in cmdObj.
* *
* If the type of the payload field is String, the contents base64 deco des and * If the type of the payload field is String, the contents base64 deco des and
* stores into "*payload". If the type is BinData, the contents are st ored directly * stores into "*payload". If the type is BinData, the contents are st ored directly
* into "*payload". In all other cases, returns * into "*payload". In all other cases, returns
*/ */
skipping to change at line 120 skipping to change at line 121
extern const char* const saslCommandPasswordFieldName; extern const char* const saslCommandPasswordFieldName;
/// Field containing sasl payloads passed to and from the server. /// Field containing sasl payloads passed to and from the server.
extern const char* const saslCommandPayloadFieldName; extern const char* const saslCommandPayloadFieldName;
/// Field containing the string identifier of the principal to authenti cate in /// Field containing the string identifier of the principal to authenti cate in
/// saslClientAuthenticate(). /// saslClientAuthenticate().
extern const char* const saslCommandPrincipalFieldName; extern const char* const saslCommandPrincipalFieldName;
/// Field containing the string identifier of the database containing c redential information, /// Field containing the string identifier of the database containing c redential information,
/// or "$sasl" if the credential information is stored outside of the m ongo cluster. /// or "$external" if the credential information is stored outside of t he mongo cluster.
extern const char* const saslCommandPrincipalSourceFieldName; extern const char* const saslCommandPrincipalSourceFieldName;
/// Field overriding the FQDN of the hostname hosting the mongodb srevi ce in /// Field overriding the FQDN of the hostname hosting the mongodb srevi ce in
/// saslClientAuthenticate(). /// saslClientAuthenticate().
extern const char* const saslCommandServiceHostnameFieldName; extern const char* const saslCommandServiceHostnameFieldName;
/// Field overriding the name of the mongodb service saslClientAuthenti cate(). /// Field overriding the name of the mongodb service saslClientAuthenti cate().
extern const char* const saslCommandServiceNameFieldName; extern const char* const saslCommandServiceNameFieldName;
/// Default database against which sasl authentication commands should run. /// Default database against which sasl authentication commands should run.
extern const char* const saslDefaultDBName; extern const char* const saslDefaultDBName;
/// Default sasl service name, "mongodb". /// Default sasl service name, "mongodb".
extern const char* const saslDefaultServiceName; extern const char* const saslDefaultServiceName;
// Field whose value should be set to true if the field in saslCommandP
asswordFieldName needs to
// be digested.
extern const char* const saslCommandDigestPasswordFieldName;
} }
 End of changes. 6 change blocks. 
11 lines changed or deleted 19 lines changed or added


 scanandorder.h   scanandorder.h 
skipping to change at line 37 skipping to change at line 37
namespace mongo { namespace mongo {
static const int ScanAndOrderMemoryLimitExceededAssertionCode = 10128; static const int ScanAndOrderMemoryLimitExceededAssertionCode = 10128;
class KeyType : boost::noncopyable { class KeyType : boost::noncopyable {
public: public:
IndexSpec _spec; IndexSpec _spec;
FieldRangeVector _keyCutter; FieldRangeVector _keyCutter;
public: public:
KeyType(const BSONObj &pattern, const FieldRangeSet &frs): KeyType(const BSONObj &pattern, const FieldRangeSet &frs):
_spec((verify(!pattern.isEmpty()),pattern)), _spec(pattern, BSONObj(), IndexSpec::NoPlugins),
_keyCutter(frs, _spec, 1) { _keyCutter(frs, _spec, 1) {
verify(!pattern.isEmpty());
} }
/** /**
* @return first key of the object that would be encountered while * @return first key of the object that would be encountered while
* scanning an index with keySpec 'pattern' using constraints 'frs' , or * scanning an index with keySpec 'pattern' using constraints 'frs' , or
* BSONObj() if no such key. * BSONObj() if no such key.
*/ */
BSONObj getKeyFromObject(const BSONObj &o) const { BSONObj getKeyFromObject(const BSONObj &o) const {
return _keyCutter.firstMatch(o); return _keyCutter.firstMatch(o);
} }
 End of changes. 2 change blocks. 
1 lines changed or deleted 2 lines changed or added


 server_parameters.h   server_parameters.h 
skipping to change at line 39 skipping to change at line 39
class ServerParameterSet; class ServerParameterSet;
/** /**
* Lets you make server level settings easily configurable. * Lets you make server level settings easily configurable.
* Hooks into (set|get)Paramter, as well as command line processing * Hooks into (set|get)Paramter, as well as command line processing
*/ */
class ServerParameter { class ServerParameter {
public: public:
typedef std::map< std::string, ServerParameter* > Map; typedef std::map< std::string, ServerParameter* > Map;
ServerParameter( ServerParameterSet* sps, const std::string& name,
bool allowedToChangeAtStartup, bool allowedToChang
eAtRuntime );
ServerParameter( ServerParameterSet* sps, const std::string& name ) ; ServerParameter( ServerParameterSet* sps, const std::string& name ) ;
virtual ~ServerParameter(); virtual ~ServerParameter();
std::string name() const { return _name; } std::string name() const { return _name; }
/** /**
* @return if you can set on command line or config file * @return if you can set on command line or config file
*/ */
virtual bool allowedToChangeAtStartup() const { return true; } bool allowedToChangeAtStartup() const { return _allowedToChangeAtSt artup; }
/** /**
* @param if you can use (get|set)Parameter * @param if you can use (get|set)Parameter
*/ */
virtual bool allowedToChangeAtRuntime() const { return true; } bool allowedToChangeAtRuntime() const { return _allowedToChangeAtRu ntime; }
virtual void append( BSONObjBuilder& b, const string& name ) = 0; virtual void append( BSONObjBuilder& b, const string& name ) = 0;
virtual Status set( const BSONElement& newValueElement ) = 0; virtual Status set( const BSONElement& newValueElement ) = 0;
virtual Status setFromString( const string& str ) = 0; virtual Status setFromString( const string& str ) = 0;
private: private:
string _name; string _name;
bool _allowedToChangeAtStartup;
bool _allowedToChangeAtRuntime;
}; };
class ServerParameterSet { class ServerParameterSet {
public: public:
typedef std::map< std::string, ServerParameter* > Map; typedef std::map< std::string, ServerParameter* > Map;
void add( ServerParameter* sp ); void add( ServerParameter* sp );
const Map& getMap() const { return _map; } const Map& getMap() const { return _map; }
static ServerParameterSet* getGlobal(); static ServerParameterSet* getGlobal();
private: private:
Map _map; Map _map;
}; };
/**
* Implementation of ServerParameter for reading and writing a server p
arameter with a given
* name and type into a specific C++ variable.
*/
template<typename T> template<typename T>
class ExportedServerParameter : public ServerParameter { class ExportedServerParameter : public ServerParameter {
public: public:
ExportedServerParameter( ServerParameterSet* sps, const std::string
& name, T* value ) /**
: ServerParameter( sps, name ), _value( value ) {} * Construct an ExportedServerParameter in parameter set "sps", nam
ed "name", whose storage
* is at "value".
*
* If allowedToChangeAtStartup is true, the parameter may be set at
the command line,
* e.g. via the --setParameter switch. If allowedToChangeAtRuntime
is true, the parameter
* may be set at runtime, e.g. via the setParameter command.
*/
ExportedServerParameter( ServerParameterSet* sps, const std::string
& name, T* value,
bool allowedToChangeAtStartup, bool allowe
dToChangeAtRuntime)
: ServerParameter( sps, name, allowedToChangeAtStartup, allowed
ToChangeAtRuntime ),
_value( value ) {}
virtual ~ExportedServerParameter() {} virtual ~ExportedServerParameter() {}
virtual void append( BSONObjBuilder& b, const string& name ) { virtual void append( BSONObjBuilder& b, const string& name ) {
b.append( name, *_value ); b.append( name, *_value );
} }
virtual Status set( const BSONElement& newValueElement ); virtual Status set( const BSONElement& newValueElement );
virtual Status set( const T& newValue ); virtual Status set( const T& newValue );
virtual const T& get() const { return *_value; } virtual const T& get() const { return *_value; }
virtual Status setFromString( const string& str ); virtual Status setFromString( const string& str );
protected: protected:
virtual Status validate( const T& potentialNewValue ){ return Statu s::OK(); } virtual Status validate( const T& potentialNewValue ){ return Statu s::OK(); }
T* _value; // owned elsewhere T* _value; // owned elsewhere
}; };
}
#define MONGO_EXPORT_SERVER_PARAMETER_IMPL( NAME, TYPE, INITIAL_VALUE, \
CHANGE_AT_STARTUP, CHANGE_AT_RU
NTIME ) \
TYPE NAME = INITIAL_VALUE; \
ExportedServerParameter<TYPE> _##NAME(\
ServerParameterSet::getGlobal(), #NAME, &NAME, CHANGE_AT_STARTU
P, CHANGE_AT_RUNTIME )
/**
* Create a global variable of type "TYPE" named "NAME" with the given INIT
IAL_VALUE. The
* value may be set at startup or at runtime.
*/
#define MONGO_EXPORT_SERVER_PARAMETER( NAME, TYPE, INITIAL_VALUE ) \ #define MONGO_EXPORT_SERVER_PARAMETER( NAME, TYPE, INITIAL_VALUE ) \
TYPE NAME = INITIAL_VALUE; \ MONGO_EXPORT_SERVER_PARAMETER_IMPL( NAME, TYPE, INITIAL_VALUE, true, tr
ExportedServerParameter<TYPE> _##NAME( ServerParameterSet::getGlobal(), ue )
#NAME, &NAME )
} /**
* Like MONGO_EXPORT_SERVER_PARAMETER, but the value may only be set at sta
rtup.
*/
#define MONGO_EXPORT_STARTUP_SERVER_PARAMETER( NAME, TYPE, INITIAL_VALUE )
\
MONGO_EXPORT_SERVER_PARAMETER_IMPL( NAME, TYPE, INITIAL_VALUE, true, fa
lse )
/**
* Like MONGO_EXPORT_SERVER_PARAMETER, but the value may only be set at run
time.
*/
#define MONGO_EXPORT_RUNTIME_SERVER_PARAMETER( NAME, TYPE, INITIAL_VALUE )
\
MONGO_EXPORT_SERVER_PARAMETER_IMPL( NAME, TYPE, INITIAL_VALUE, false, t
rue )
#include "server_parameters_inline.h" #include "server_parameters_inline.h"
 End of changes. 10 change blocks. 
9 lines changed or deleted 64 lines changed or added


 shapes.h   shapes.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/jsobj.h" #include "mongo/db/jsobj.h"
namespace mongo { namespace mongo {
// TODO(hk): move these distance things to something like geomath.h
struct Point; struct Point;
double distance(const Point& p1, const Point &p2); double distance(const Point& p1, const Point &p2);
bool distanceWithin(const Point &p1, const Point &p2, double radius); bool distanceWithin(const Point &p1, const Point &p2, double radius);
void checkEarthBounds(const Point &p); void checkEarthBounds(const Point &p);
double spheredist_rad(const Point& p1, const Point& p2); double spheredist_rad(const Point& p1, const Point& p2);
double spheredist_deg(const Point& p1, const Point& p2); double spheredist_deg(const Point& p1, const Point& p2);
struct Point { struct Point {
Point(); Point();
Point(double x, double y); Point(double x, double y);
explicit Point(const BSONElement& e); explicit Point(const BSONElement& e);
explicit Point(const BSONObj& o); explicit Point(const BSONObj& o);
string toString() const; string toString() const;
double x; double x;
double y; double y;
}; };
struct Circle {
Circle();
Circle(double radius, Point center);
double radius;
Point center;
};
class Box { class Box {
public: public:
Box(); Box();
Box(double x, double y, double size); Box(double x, double y, double size);
Box(Point min, Point max); Box(Point min, Point max);
BSONArray toBSON() const; BSONArray toBSON() const;
string toString() const; string toString() const;
bool between(double min, double max, double val, double fudge = 0) const; bool between(double min, double max, double val, double fudge = 0) const;
bool onBoundary(double bound, double val, double fudge = 0) const; bool onBoundary(double bound, double val, double fudge = 0) const;
// TODO(hk) comment
bool mid(double amin, double amax, double bmin, double bmax, bool m in, double* res) const; bool mid(double amin, double amax, double bmin, double bmax, bool m in, double* res) const;
// TODO(hk): What is the return here? comment
double intersects(const Box& other) const; double intersects(const Box& other) const;
double area() const; double area() const;
double maxDim() const; double maxDim() const;
Point center() const; Point center() const;
void truncate(double min, double max); void truncate(double min, double max);
void fudge(double error); void fudge(double error);
bool onBoundary(Point p, double fudge = 0); bool onBoundary(Point p, double fudge = 0);
bool inside(Point p, double fudge = 0) const; bool inside(Point p, double fudge = 0) const;
bool inside(double x, double y, double fudge = 0) const; bool inside(double x, double y, double fudge = 0) const;
bool contains(const Box& other, double fudge = 0); bool contains(const Box& other, double fudge = 0);
// TODO(hk): This could be private and Polygon could be our friend,
or we could
// have getters/setters (lots of code change).
Point _min; Point _min;
Point _max; Point _max;
}; };
class Polygon { class Polygon {
public: public:
Polygon(); Polygon();
Polygon(vector<Point> points); Polygon(vector<Point> points);
void add(Point p); void add(Point p);
 End of changes. 5 change blocks. 
7 lines changed or deleted 8 lines changed or added


 shard.h   shard.h 
skipping to change at line 186 skipping to change at line 186
ShardStatus( const Shard& shard , const BSONObj& obj ); ShardStatus( const Shard& shard , const BSONObj& obj );
friend ostream& operator << (ostream& out, const ShardStatus& s) { friend ostream& operator << (ostream& out, const ShardStatus& s) {
out << s.toString(); out << s.toString();
return out; return out;
} }
string toString() const { string toString() const {
stringstream ss; stringstream ss;
ss << "shard: " << _shard << " mapped: " << _mapped << " writeL ss << "shard: " << _shard
ock: " << _writeLock; << " mapped: " << _mapped
<< " writeLock: " << _writeLock
<< " version: " << _mongoVersion;
return ss.str(); return ss.str();
} }
bool operator<( const ShardStatus& other ) const { bool operator<( const ShardStatus& other ) const {
return _mapped < other._mapped; return _mapped < other._mapped;
} }
Shard shard() const { Shard shard() const {
return _shard; return _shard;
} }
long long mapped() const { long long mapped() const {
return _mapped; return _mapped;
} }
bool hasOpsQueued() const { bool hasOpsQueued() const {
return _hasOpsQueued; return _hasOpsQueued;
} }
string mongoVersion() const {
return _mongoVersion;
}
private: private:
Shard _shard; Shard _shard;
long long _mapped; long long _mapped;
bool _hasOpsQueued; // true if 'writebacks' are pending bool _hasOpsQueued; // true if 'writebacks' are pending
double _writeLock; double _writeLock;
string _mongoVersion;
}; };
class ChunkManager; class ChunkManager;
typedef shared_ptr<const ChunkManager> ChunkManagerPtr; typedef shared_ptr<const ChunkManager> ChunkManagerPtr;
class ShardConnection : public AScopedConnection { class ShardConnection : public AScopedConnection {
public: public:
ShardConnection( const Shard * s , const string& ns, ChunkManagerPt r manager = ChunkManagerPtr() ); ShardConnection( const Shard * s , const string& ns, ChunkManagerPt r manager = ChunkManagerPtr() );
ShardConnection( const Shard& s , const string& ns, ChunkManagerPtr manager = ChunkManagerPtr() ); ShardConnection( const Shard& s , const string& ns, ChunkManagerPtr manager = ChunkManagerPtr() );
ShardConnection( const string& addr , const string& ns, ChunkManage rPtr manager = ChunkManagerPtr() ); ShardConnection( const string& addr , const string& ns, ChunkManage rPtr manager = ChunkManagerPtr() );
 End of changes. 3 change blocks. 
2 lines changed or deleted 9 lines changed or added


 ssl_manager.h   ssl_manager.h 
skipping to change at line 33 skipping to change at line 33
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
namespace mongo { namespace mongo {
class SSLParams { class SSLParams {
public: public:
SSLParams(const std::string& pemfile, SSLParams(const std::string& pemfile,
const std::string& pempwd, const std::string& pempwd,
const std::string& cafile = "", const std::string& cafile = "",
const std::string& crlfile = "", const std::string& crlfile = "",
bool forceCertificateValidation = false) : bool weakCertificateValidation = false,
bool fipsMode = false) :
pemfile(pemfile), pemfile(pemfile),
pempwd(pempwd), pempwd(pempwd),
cafile(cafile), cafile(cafile),
crlfile(crlfile), crlfile(crlfile),
forceCertificateValidation(forceCertificateValidation) {}; weakCertificateValidation(weakCertificateValidation),
fipsMode(fipsMode) {};
std::string pemfile; std::string pemfile;
std::string pempwd; std::string pempwd;
std::string cafile; std::string cafile;
std::string crlfile; std::string crlfile;
bool forceCertificateValidation; bool weakCertificateValidation;
bool fipsMode;
}; };
class SSLManager { class SSLManager {
MONGO_DISALLOW_COPYING(SSLManager); MONGO_DISALLOW_COPYING(SSLManager);
public: public:
explicit SSLManager(const SSLParams& params); explicit SSLManager(const SSLParams& params);
/** /**
* Initiates a TLS connection. * Initiates a TLS connection.
* Throws SocketException on failure. * Throws SocketException on failure.
skipping to change at line 73 skipping to change at line 76
*/ */
SSL* accept(int fd); SSL* accept(int fd);
/** /**
* Fetches a peer certificate and validates it if it exists * Fetches a peer certificate and validates it if it exists
* Throws SocketException on failure * Throws SocketException on failure
*/ */
void validatePeerCertificate(const SSL* ssl); void validatePeerCertificate(const SSL* ssl);
/** /**
* Cleans up SSL thread local memory; use at thread exit
* to avoid memory leaks
*/
static void cleanupThreadLocals();
/**
* Callbacks for SSL functions * Callbacks for SSL functions
*/ */
static int password_cb( char *buf,int num, int rwflag,void *userdat a ); static int password_cb( char *buf,int num, int rwflag,void *userdat a );
static int verify_cb(int ok, X509_STORE_CTX *ctx); static int verify_cb(int ok, X509_STORE_CTX *ctx);
private: private:
SSL_CTX* _context; SSL_CTX* _context;
std::string _password; std::string _password;
bool _validateCertificates; bool _validateCertificates;
bool _forceValidation; bool _weakValidation;
/** /**
* creates an SSL context to be used for this file descriptor. * creates an SSL context to be used for this file descriptor.
* caller must SSL_free it. * caller must SSL_free it.
*/ */
SSL* _secure(int fd); SSL* _secure(int fd);
/** /**
* Fetches the error text for an error code, in a thread-safe manne r. * Fetches the error text for an error code, in a thread-safe manne r.
*/ */
std::string _getSSLErrorMessage(int code); std::string _getSSLErrorMessage(int code);
skipping to change at line 113 skipping to change at line 122
/* /*
* Set up SSL for certificate validation by loading a CA * Set up SSL for certificate validation by loading a CA
*/ */
bool _setupCA(const std::string& caFile); bool _setupCA(const std::string& caFile);
/* /*
* Import a certificate revocation list into our SSL context * Import a certificate revocation list into our SSL context
* for use with validating certificates * for use with validating certificates
*/ */
bool _setupCRL(const std::string& crlFile); bool _setupCRL(const std::string& crlFile);
/*
* Activate FIPS 140-2 mode, if the server started with a command l
ine
* parameter.
*/
void _setupFIPS();
/*
* Wrapper for SSL_Connect() that handles SSL_ERROR_WANT_READ,
* see SERVER-7940
*/
int _ssl_connect(SSL* ssl);
/*
* Initialize the SSL Library.
* This function can be called multiple times; it ensures it only
* does the SSL initialization once per process.
*/
void _initializeSSL(const SSLParams& params);
}; };
} }
#endif #endif
 End of changes. 6 change blocks. 
4 lines changed or deleted 33 lines changed or added


 string_data-inl.h   string_data-inl.h 
skipping to change at line 64 skipping to change at line 64
return true; return true;
} }
inline void StringData::copyTo( char* dest, bool includeEndingNull ) co nst { inline void StringData::copyTo( char* dest, bool includeEndingNull ) co nst {
memcpy( dest, _data, size() ); memcpy( dest, _data, size() );
if ( includeEndingNull ) if ( includeEndingNull )
dest[size()] = 0; dest[size()] = 0;
} }
inline size_t StringData::find( char c ) const { inline size_t StringData::find( char c, size_t fromPos ) const {
const void* x = memchr( _data, c, size() ); if ( fromPos >= size() )
return string::npos;
const void* x = memchr( _data + fromPos, c, _size - fromPos );
if ( x == 0 ) if ( x == 0 )
return string::npos; return string::npos;
return static_cast<size_t>( static_cast<const char*>(x) - _data ); return static_cast<size_t>( static_cast<const char*>(x) - _data );
} }
inline size_t StringData::find( const StringData& needle ) const { inline size_t StringData::find( const StringData& needle ) const {
size_t mx = size(); size_t mx = size();
size_t needleSize = needle.size(); size_t needleSize = needle.size();
if ( needleSize == 0 ) if ( needleSize == 0 )
 End of changes. 1 change blocks. 
2 lines changed or deleted 5 lines changed or added


 string_data.h   string_data.h 
skipping to change at line 59 skipping to change at line 59
/** /**
* Constructs a StringData, for the case where the length of string is not known. 'c' * Constructs a StringData, for the case where the length of string is not known. 'c'
* must be a pointer to a null-terminated string. * must be a pointer to a null-terminated string.
*/ */
StringData( const char* c ) StringData( const char* c )
: _data(c), _size((c == NULL) ? 0 : string::npos) {} : _data(c), _size((c == NULL) ? 0 : string::npos) {}
/** /**
* Constructs a StringData explicitly, for the case where the lengt h of the string is * Constructs a StringData explicitly, for the case where the lengt h of the string is
* already known. 'c' must be a pointer to a null-terminated string , and strlenOfc must * already known. 'c' must be a pointer to a null-terminated string , and len must
* be the length that strlen(c) would return, a.k.a the index of th e terminator in c. * be the length that strlen(c) would return, a.k.a the index of th e terminator in c.
*/ */
StringData( const char* c, size_t len ) StringData( const char* c, size_t len )
: _data(c), _size(len) {} : _data(c), _size(len) {}
/** Constructs a StringData, for the case of a string. */ /** Constructs a StringData, for the case of a string. */
StringData( const std::string& s ) StringData( const std::string& s )
: _data(s.c_str()), _size(s.size()) {} : _data(s.c_str()), _size(s.size()) {}
/** /**
skipping to change at line 99 skipping to change at line 99
bool equalCaseInsensitive( const StringData& other ) const; bool equalCaseInsensitive( const StringData& other ) const;
void copyTo( char* dest, bool includeEndingNull ) const; void copyTo( char* dest, bool includeEndingNull ) const;
StringData substr( size_t pos, size_t n = std::numeric_limits<size_ t>::max() ) const; StringData substr( size_t pos, size_t n = std::numeric_limits<size_ t>::max() ) const;
// //
// finders // finders
// //
size_t find( char c ) const; size_t find( char c , size_t fromPos = 0 ) const;
size_t find( const StringData& needle ) const; size_t find( const StringData& needle ) const;
/** /**
* Returns true if 'prefix' is a substring of this instance, anchor ed at position 0. * Returns true if 'prefix' is a substring of this instance, anchor ed at position 0.
*/ */
bool startsWith( const StringData& prefix ) const; bool startsWith( const StringData& prefix ) const;
/** /**
* Returns true if 'suffix' is a substring of this instance, anchor ed at the end. * Returns true if 'suffix' is a substring of this instance, anchor ed at the end.
*/ */
bool endsWith( const StringData& suffix ) const; bool endsWith( const StringData& suffix ) const;
// //
// accessors // accessors
// //
/** /**
* this is not guaranteed to be null-terminated, * Get the pointer to the first byte of StringData. This is not gu
* if you use this without all using size(), you are likely doing s aranteed to be
omething wrong * null-terminated, so if using this without checking size(), you a
re likely doing
* something wrong.
*/ */
const char* rawData() const { return _data; } const char* rawData() const { return _data; }
size_t size() const { fillSize(); return _size; } size_t size() const { fillSize(); return _size; }
bool empty() const { return size() == 0; } bool empty() const { return size() == 0; }
string toString() const { return string(_data, size()); } string toString() const { return string(_data, size()); }
char operator[] ( unsigned pos ) const { return _data[pos]; } char operator[] ( unsigned pos ) const { return _data[pos]; }
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)
 End of changes. 3 change blocks. 
5 lines changed or deleted 7 lines changed or added


 syncclusterconnection.h   syncclusterconnection.h 
skipping to change at line 110 skipping to change at line 110
int wtimeout=0); int wtimeout=0);
virtual BSONObj getLastErrorDetailed(bool fsync=false, bool j=false , int w=0, int wtimeout=0); virtual BSONObj getLastErrorDetailed(bool fsync=false, bool j=false , int w=0, int wtimeout=0);
virtual bool callRead( Message& toSend , Message& response ); virtual bool callRead( Message& toSend , Message& response );
virtual ConnectionString::ConnectionType type() const { return Conn ectionString::SYNC; } virtual ConnectionString::ConnectionType type() const { return Conn ectionString::SYNC; }
void setAllSoTimeouts( double socketTimeout ); void setAllSoTimeouts( double socketTimeout );
double getSoTimeout() const { return _socketTimeout; } double getSoTimeout() const { return _socketTimeout; }
virtual bool auth(const string &dbname, const string &username, con
st string &password_text, string& errmsg, bool digestPassword, Auth::Level*
level=NULL);
virtual bool lazySupported() const { return false; } virtual bool lazySupported() const { return false; }
protected:
virtual void _auth(const BSONObj& params);
private: private:
SyncClusterConnection( SyncClusterConnection& prev, double socketTi meout = 0 ); SyncClusterConnection( SyncClusterConnection& prev, double socketTi meout = 0 );
string _toString() const; string _toString() const;
bool _commandOnActive(const string &dbname, const BSONObj& cmd, BSO NObj &info, int options=0); bool _commandOnActive(const string &dbname, const BSONObj& cmd, BSO NObj &info, int options=0);
auto_ptr<DBClientCursor> _queryOnActive(const string &ns, Query que ry, int nToReturn, int nToSkip, auto_ptr<DBClientCursor> _queryOnActive(const string &ns, Query que ry, int nToReturn, int nToSkip,
const BSONObj *fieldsToRetu rn, int queryOptions, int batchSize ); const BSONObj *fieldsToRetu rn, int queryOptions, int batchSize );
int _lockType( const string& name ); int _lockType( const string& name );
void _checkLast(); void _checkLast();
void _connect( const std::string& host ); void _connect( const std::string& host );
 End of changes. 2 change blocks. 
4 lines changed or deleted 4 lines changed or added


 targetver.h   targetver.h 
skipping to change at line 18 skipping to change at line 18
* 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
#ifndef _WIN32_WINNT // Allow use of features specific to Window #ifdef _WIN32
s Vista or later. #ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to #if defined _WIN64
target other versions of Windows. // For 64 bit Windows we require at least Windows Vista or Windows Server 2
008.
#define _WIN32_WINNT 0x0600
#else
// For 32 bit Windows we allow Windows XP as well. See platform/atomic_intr
insics_win32.h for
// an example of where this makes a difference.
#define _WIN32_WINNT 0x0502
#endif
#endif
#endif #endif
 End of changes. 1 change blocks. 
4 lines changed or deleted 13 lines changed or added


 timer_stats.h   timer_stats.h 
skipping to change at line 55 skipping to change at line 55
long long _num; long long _num;
long long _totalMillis; long long _totalMillis;
}; };
/** /**
* Holds an instance of a Timer such that we the time is recorded * Holds an instance of a Timer such that we the time is recorded
* when the TimerHolder goes out of scope * when the TimerHolder goes out of scope
*/ */
class TimerHolder { class TimerHolder {
public: public:
/** Destructor will record to TimerStats */
TimerHolder( TimerStats* stats ); TimerHolder( TimerStats* stats );
/** Will record stats if recordMillis hasn't (based on _recorded) */
~TimerHolder(); ~TimerHolder();
/** /**
* returns elapsed millis from internal timer * returns elapsed millis from internal timer
*/ */
int millis() const { return _t.millis(); } int millis() const { return _t.millis(); }
/** /**
* records the time in the TimerStats and marks that we've * records the time in the TimerStats and marks that we've
* already recorded so the destructor doesn't * already recorded so the destructor doesn't
 End of changes. 2 change blocks. 
0 lines changed or deleted 2 lines changed or added


 tool.h   tool.h 
skipping to change at line 105 skipping to change at line 105
virtual void printHelp(ostream &out); virtual void printHelp(ostream &out);
virtual void printExtraHelp( ostream & out ) {} virtual void printExtraHelp( ostream & out ) {}
virtual void printExtraHelpAfter( ostream & out ) {} virtual void printExtraHelpAfter( ostream & out ) {}
virtual void printVersion(ostream &out); virtual void printVersion(ostream &out);
protected: protected:
mongo::DBClientBase &conn( bool slaveIfPaired = false ); mongo::DBClientBase &conn( bool slaveIfPaired = false );
void auth( string db = "", Auth::Level * level = NULL);
string _name; string _name;
string _db; string _db;
string _coll; string _coll;
string _fileName; string _fileName;
string _username; string _username;
string _password; string _password;
string _authenticationDatabase;
string _authenticationMechanism;
bool _usesstdout; bool _usesstdout;
bool _noconnection; bool _noconnection;
bool _autoreconnect; bool _autoreconnect;
void addFieldOptions(); void addFieldOptions();
void needFields(); void needFields();
vector<string> _fields; vector<string> _fields;
BSONObj _fieldsObj; BSONObj _fieldsObj;
skipping to change at line 140 skipping to change at line 141
mongo::DBClientBase * _conn; mongo::DBClientBase * _conn;
mongo::DBClientBase * _slaveConn; mongo::DBClientBase * _slaveConn;
bool _paired; bool _paired;
boost::program_options::options_description * _options; boost::program_options::options_description * _options;
boost::program_options::options_description * _hidden_options; boost::program_options::options_description * _hidden_options;
boost::program_options::positional_options_description _positonalOp tions; boost::program_options::positional_options_description _positonalOp tions;
boost::program_options::variables_map _params; boost::program_options::variables_map _params;
private:
void auth();
}; };
class BSONTool : public Tool { class BSONTool : public Tool {
bool _objcheck; bool _objcheck;
auto_ptr<Matcher> _matcher; auto_ptr<Matcher> _matcher;
public: public:
BSONTool( const char * name , DBAccess access=ALL, bool objcheck = true ); BSONTool( const char * name , DBAccess access=ALL, bool objcheck = true );
virtual int doRun() = 0; virtual int doRun() = 0;
 End of changes. 3 change blocks. 
1 lines changed or deleted 4 lines changed or added


 type_changelog.h   type_changelog.h 
skipping to change at line 36 skipping to change at line 36
/** /**
* This class represents the layout and contents of documents contained in the * This class represents the layout and contents of documents contained in the
* config.changelog collection. All manipulation of documents coming fr om that * config.changelog collection. All manipulation of documents coming fr om that
* collection should be done with this class. * collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before. * // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* BSONObj query = QUERY(ChangelogType::changeID("host.local-2012-1 * BSONObj query = QUERY(ChangelogType::exampleField("exampleFieldN
1-21T19:14:10-8")) ame"));
* logEntryDoc = conn->findOne(ChangelogType::ConfigNS, query); * exampleDoc = conn->findOne(ChangelogType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* ChangelogType logEntry; * ChangelogType exampleType;
* logEntry.fromBSON(logEntryDoc); * string errMsg;
* if (! logEntry.isValid()) { * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
* // Can't use 'logEntry'. Take action. isValid(&errMsg)) {
* // Can't use 'exampleType'. Take action.
* } * }
* // use 'logEntry' * // use 'exampleType'
* *
*/ */
class ChangelogType { class ChangelogType {
MONGO_DISALLOW_COPYING(ChangelogType); MONGO_DISALLOW_COPYING(ChangelogType);
public: public:
// //
// schema declarations // schema declarations
// //
// Name of the collection in the config server. // Name of the changelog collection in the config server.
static const std::string ConfigNS; static const std::string ConfigNS;
// Field names and types in the changelog type. // Field names and types in the changelog collection type.
static BSONField<std::string> changeID; // id for this change " static const BSONField<std::string> changeID;
<hostname>-<current_time>-<increment>" static const BSONField<std::string> server;
static BSONField<std::string> server; // hostname of server t static const BSONField<std::string> clientAddr;
hat we are making the change on. Does not include port. static const BSONField<Date_t> time;
static BSONField<std::string> clientAddr; // hostname:port of the static const BSONField<std::string> what;
client that made this change static const BSONField<std::string> ns;
static BSONField<Date_t> time; // time this change was static const BSONField<BSONObj> details;
made
static BSONField<std::string> what; // description of the c
hange
static BSONField<std::string> ns; // database or collecti
on this change applies to
static BSONField<BSONObj> details; // A BSONObj containing
extra information about some operations
// //
// changelog type methods // changelog type methods
// //
ChangelogType(); ChangelogType();
~ChangelogType(); ~ChangelogType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
skipping to change at line 90 skipping to change at line 90
/** /**
* Returns the BSON representation of the entry. * Returns the BSON representation of the entry.
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(BSONObj source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clears the internal state. * Clears the internal state.
*/ */
void clear(); void clear();
/** /**
* Copies all the fields present in 'this' to 'other'. * Copies all the fields present in 'this' to 'other'.
*/ */
void cloneTo(ChangelogType* other); void cloneTo(ChangelogType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors // individual field accessors
// //
void setChangeID(const StringData& changeID) { _changeID = changeID // Mandatory Fields
.toString(); } void setChangeID(const StringData& changeID) {
const std::string& getChangeID() const { return _changeID; } _changeID = changeID.toString();
_isChangeIDSet = true;
}
void setServer(const StringData& server) { _server = server.toStrin void unsetChangeID() { _isChangeIDSet = false; }
g(); }
const std::string& getServer() const { return _server; }
void setClientAddr(const StringData& clientAddr) { _clientAddr = cl bool isChangeIDSet() const { return _isChangeIDSet; }
ientAddr.toString(); }
const std::string& getClientAddr() const { return _clientAddr; }
void setTime(const Date_t& time) { _time = time; } // Calling get*() methods when the member is not set results in und
Date_t getTime() const { return _time; } efined behavior
const std::string& getChangeID() const {
dassert(_isChangeIDSet);
return _changeID;
}
void setWhat(const StringData& what) { _what = what.toString(); } void setServer(const StringData& server) {
const std::string& getWhat() const { return _what; } _server = server.toString();
_isServerSet = true;
}
void setNS(const StringData& ns) { _ns = ns.toString(); } void unsetServer() { _isServerSet = false; }
const std::string& getNS() const { return _ns; }
void setDetails(const BSONObj details) { _details = details.getOwne bool isServerSet() const { return _isServerSet; }
d(); }
BSONObj getDetails() const { return _details; } // Calling get*() methods when the member is not set results in und
efined behavior
const std::string& getServer() const {
dassert(_isServerSet);
return _server;
}
void setClientAddr(const StringData& clientAddr) {
_clientAddr = clientAddr.toString();
_isClientAddrSet = true;
}
void unsetClientAddr() { _isClientAddrSet = false; }
bool isClientAddrSet() const { return _isClientAddrSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string& getClientAddr() const {
dassert(_isClientAddrSet);
return _clientAddr;
}
void setTime(const Date_t time) {
_time = time;
_isTimeSet = true;
}
void unsetTime() { _isTimeSet = false; }
bool isTimeSet() const { return _isTimeSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const Date_t getTime() const {
dassert(_isTimeSet);
return _time;
}
void setWhat(const StringData& what) {
_what = what.toString();
_isWhatSet = true;
}
void unsetWhat() { _isWhatSet = false; }
bool isWhatSet() const { return _isWhatSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string& getWhat() const {
dassert(_isWhatSet);
return _what;
}
void setNS(const StringData& ns) {
_ns = ns.toString();
_isNsSet = true;
}
void unsetNS() { _isNsSet = false; }
bool isNSSet() const { return _isNsSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string& getNS() const {
dassert(_isNsSet);
return _ns;
}
void setDetails(const BSONObj& details) {
_details = details.getOwned();
_isDetailsSet = true;
}
void unsetDetails() { _isDetailsSet = false; }
bool isDetailsSet() const { return _isDetailsSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const BSONObj getDetails() const {
dassert(_isDetailsSet);
return _details;
}
// Optional Fields
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
std::string _changeID; // (M) id for this change "<hostname>-<cur std::string _changeID; // (M) id for this change "<hostname>-<
rent_time>-<increment>" current_time>-<increment>"
std::string _server; // (M) hostname of server that we are maki bool _isChangeIDSet;
ng the change on. Does not include port. std::string _server; // (M) hostname of server that we are mak
std::string _clientAddr; // (M) hostname:port of the client that ma ing the change on. Does not include port.
de this change bool _isServerSet;
Date_t _time; // (M) time this change was made std::string _clientAddr; // (M) hostname:port of the client th
std::string _what; // (M) description of the change at made this change
std::string _ns; // (M) database or collection this change bool _isClientAddrSet;
applies to Date_t _time; // (M) time this change was made
BSONObj _details; // (M) A BSONObj containing extra informat bool _isTimeSet;
ion about some operations std::string _what; // (M) description of the change
bool _isWhatSet;
std::string _ns; // (M) database or collection this change app
lies to
bool _isNsSet;
BSONObj _details; // (M) A BSONObj containing extra informatio
n about some operations
bool _isDetailsSet;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 15 change blocks. 
56 lines changed or deleted 147 lines changed or added


 type_chunk.h   type_chunk.h 
skipping to change at line 37 skipping to change at line 37
/** /**
* This class represents the layout and contents of documents contained in the * This class represents the layout and contents of documents contained in the
* config.chunks collection. All manipulation of documents coming from that * config.chunks collection. All manipulation of documents coming from that
* collection should be done with this class. * collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before. * // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* unique_ptr<DbClientCursor> cursor; * BSONObj query = QUERY(ChunkType::exampleField("exampleFieldName"
* BSONObj query = QUERY(ChunkType::ns("mydb.mycoll")); ));
* cursor.reset(conn->query(ChunkType::ConfigNS, query, ...)); * exampleDoc = conn->findOne(ChunkType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* while (cursor->more()) { * ChunkType exampleType;
* chunkDoc = cursor->next(); * string errMsg;
* ChunkType chunk; * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
* chunk.fromBSON(dbDoc); isValid(&errMsg)) {
* if (! chunk.isValid()) { * // Can't use 'exampleType'. Take action.
* // Can't use 'chunk'. Take action.
* }
* // use 'chunk'
* } * }
* // use 'exampleType'
*
*/ */
class ChunkType { class ChunkType {
MONGO_DISALLOW_COPYING(ChunkType); MONGO_DISALLOW_COPYING(ChunkType);
public: public:
// //
// schema declarations // schema declarations
// //
// Name of the chunk collection in the config server. // Name of the chunks collection in the config server.
static const std::string ConfigNS; static const std::string ConfigNS;
// Field names and types in the chunk collection type. // Field names and types in the chunks collection type.
static BSONField<std::string> name; // chunk's id static const BSONField<std::string> name;
static BSONField<std::string> ns; // namespace this chunk is static const BSONField<std::string> ns;
in static const BSONField<BSONObj> min;
static BSONField<BSONObj> min; // first key of the chunk, static const BSONField<BSONObj> max;
including static const BSONField<BSONArray> version;
static BSONField<BSONObj> max; // last key of the chunk, n static const BSONField<std::string> shard;
on-including static const BSONField<bool> jumbo;
static BSONField<BSONArray> version; // [Date_t, OID] static const BSONField<Date_t> DEPRECATED_lastmod;
static BSONField<std::string> shard; // home of this chunk static const BSONField<OID> DEPRECATED_epoch;
static BSONField<bool> jumbo; // too big to move?
// Transition to new format, 2.2 -> 2.4
// 2.2 can read both lastmod + lastmodEpoch format and 2.4 [ lastmo
d, OID ] formats.
static BSONField<Date_t> DEPRECATED_lastmod; // major | minor vers
ions
static BSONField<OID> DEPRECATED_epoch; // OID, to disambigua
te collection incarnations
// //
// chunk type methods // chunks type methods
// //
ChunkType(); ChunkType();
~ChunkType(); ~ChunkType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
* representations. Otherwise returns false and fills in the option al 'errMsg' string. * representations. Otherwise returns false and fills in the option al 'errMsg' string.
*/ */
bool isValid(std::string* errMsg) const; bool isValid(std::string* errMsg) const;
/** /**
* Returns the BSON representation of the entry. * Returns the BSON representation of the entry.
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(BSONObj source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clears the internal state. * Clears the internal state.
*/ */
void clear(); void clear();
/** /**
* Copies all the fields present in 'this' to 'other'. * Copies all the fields present in 'this' to 'other'.
*/ */
void cloneTo(ChunkType* other) const; void cloneTo(ChunkType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors // individual field accessors
// //
// Mandatory Fields
void setName(const StringData& name) { void setName(const StringData& name) {
_name = name.toString(); _name = name.toString();
_isNameSet = true;
} }
const std::string& getName() const { void unsetName() { _isNameSet = false; }
bool isNameSet() const { return _isNameSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string getName() const {
dassert(_isNameSet);
return _name; return _name;
} }
void setNS(const StringData& ns) { void setNS(const StringData& ns) {
_ns = ns.toString(); _ns = ns.toString();
_isNsSet = true;
} }
const std::string& getNS() const { void unsetNS() { _isNsSet = false; }
bool isNSSet() const { return _isNsSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string getNS() const {
dassert(_isNsSet);
return _ns; return _ns;
} }
void setMin(const BSONObj& min) { void setMin(const BSONObj& min) {
_min = min.getOwned(); _min = min.getOwned();
_isMinSet = true;
} }
BSONObj getMin() const { void unsetMin() { _isMinSet = false; }
bool isMinSet() const { return _isMinSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const BSONObj getMin() const {
dassert(_isMinSet);
return _min; return _min;
} }
void setMax(const BSONObj& max) { void setMax(const BSONObj& max) {
_max = max.getOwned(); _max = max.getOwned();
_isMaxSet = true;
} }
BSONObj getMax() const { void unsetMax() { _isMaxSet = false; }
bool isMaxSet() const { return _isMaxSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const BSONObj getMax() const {
dassert(_isMaxSet);
return _max; return _max;
} }
void setVersion(const ChunkVersion& version) { void setVersion(const ChunkVersion& version) {
_version = version; _version = version;
_isVersionSet = true;
} }
void unsetVersion() { _isVersionSet = false; }
bool isVersionSet() const { return _isVersionSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const ChunkVersion& getVersion() const { const ChunkVersion& getVersion() const {
dassert(_isVersionSet);
return _version; return _version;
} }
void setShard(const StringData& shard) { void setShard(const StringData& shard) {
_shard = shard.toString(); _shard = shard.toString();
_isShardSet = true;
} }
const std::string& getShard() const { void unsetShard() { _isShardSet = false; }
bool isShardSet() const { return _isShardSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string getShard() const {
dassert(_isShardSet);
return _shard; return _shard;
} }
// Optional Fields
void setJumbo(bool jumbo) { void setJumbo(bool jumbo) {
_jumbo = jumbo; _jumbo = jumbo;
_isJumboSet = true;
}
void unsetJumbo() { _isJumboSet = false; }
bool isJumboSet() const {
return _isJumboSet || jumbo.hasDefault();
} }
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
bool getJumbo() const { bool getJumbo() const {
return _jumbo; if (_isJumboSet) {
return _jumbo;
} else {
dassert(jumbo.hasDefault());
return jumbo.getDefault();
}
} }
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
string _name; // (M) chunk's id std::string _name; // (M) chunk's id
string _ns; // (M) collection this chunk is in bool _isNameSet;
BSONObj _min; // (M) first key of the range, inclusive std::string _ns; // (M) collection this chunk is in
BSONObj _max; // (M) last key of the range, non-inclusive bool _isNsSet;
ChunkVersion _version; // (M) version of this chunk BSONObj _min; // (M) first key of the range, inclusive
string _shard; // (M) shard this chunk lives in bool _isMinSet;
bool _jumbo; // (O) too big to move? BSONObj _max; // (M) last key of the range, non-inclusive
bool _isMaxSet;
ChunkVersion _version; // (M) version of this chunk
bool _isVersionSet;
std::string _shard; // (M) shard this chunk lives in
bool _isShardSet;
bool _jumbo; // (O) too big to move?
bool _isJumboSet;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 26 change blocks. 
46 lines changed or deleted 108 lines changed or added


 type_collection.h   type_collection.h 
skipping to change at line 36 skipping to change at line 36
/** /**
* This class represents the layout and contents of documents contained in the * This class represents the layout and contents of documents contained in the
* config.collections collection. All manipulation of documents coming from that * config.collections collection. All manipulation of documents coming from that
* collection should be done with this class. * collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before. * // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* BSONObj query = QUERY(CollectionType::ns("db.coll") << * BSONObj query = QUERY(CollectionType::exampleField("exampleField
* CollectionType::unique(true)); Name"));
* collDoc = conn->findOne(CollectionType::ConfigNS, query); * exampleDoc = conn->findOne(CollectionType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* CollectionType coll; * CollectionType exampleType;
* coll.fromBSON(collDoc); * string errMsg;
* if (! coll.isValid()) { * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
* // Can't use 'coll'. Take action. isValid(&errMsg)) {
* // Can't use 'exampleType'. Take action.
* } * }
* if (coll.isDropped()) { * // use 'exampleType'
* // Coll doesn't exist, Take action.
* }
*
* // use 'coll'
* *
*/ */
class CollectionType { class CollectionType {
MONGO_DISALLOW_COPYING(CollectionType); MONGO_DISALLOW_COPYING(CollectionType);
public: public:
// //
// schema declarations // schema declarations
// //
// Name of the collection in the config server. // Name of the collections collection in the config server.
static const std::string ConfigNS; static const std::string ConfigNS;
// Field names and types in the collection type. // Field names and types in the collections collection type.
static BSONField<std::string> ns; // collection's namespace static const BSONField<std::string> ns;
static BSONField<std::string> primary; // primary db when not shard static const BSONField<std::string> primary;
ed static const BSONField<BSONObj> keyPattern;
static BSONField<BSONObj> keyPattern; // sharding key, if sharded static const BSONField<bool> unique;
static BSONField<bool> unique; // sharding key unique? static const BSONField<Date_t> updatedAt;
static BSONField<Date_t> updatedAt; // when collection was creat static const BSONField<bool> noBalance;
ed static const BSONField<OID> epoch;
static BSONField<bool> noBalance; // true if balancing is disa static const BSONField<bool> dropped;
bled static const BSONField<OID> DEPRECATED_lastmodEpoch;
static BSONField<OID> epoch; // disambiguate ns (drop/rec static const BSONField<Date_t> DEPRECATED_lastmod;
reate)
// To-be-deprecated, not yet
static BSONField<bool> dropped; // true if we should ignore
this collection entry
// Deprecated fields should only be used in parseBSON calls. Expose
d here for testing only.
static BSONField<OID> DEPRECATED_lastmodEpoch;
static BSONField<Date_t> DEPRECATED_lastmod;
// //
// collection type methods // collections type methods
// //
CollectionType(); CollectionType();
~CollectionType(); ~CollectionType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
* representations. Otherwise returns false and fills in the option al 'errMsg' string. * representations. Otherwise returns false and fills in the option al 'errMsg' string.
*/ */
bool isValid(std::string* errMsg) const; bool isValid(std::string* errMsg) const;
/** /**
* Returns the BSON representation of the entry. * Returns the BSON representation of the entry.
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(BSONObj source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clears the internal state. * Clears the internal state.
*/ */
void clear(); void clear();
/** /**
* Copies all the fields present in 'this' to 'other'. * Copies all the fields present in 'this' to 'other'.
*/ */
void cloneTo(CollectionType* other) const; void cloneTo(CollectionType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors // individual field accessors
// //
void setNS(const StringData& ns) { _ns = ns.toString(); } // Mandatory Fields
const std::string& getNS() const { return _ns; } void setNS(const StringData& ns) {
_ns = ns.toString();
void setPrimary(const StringData& name) { _primary = name.toString( _isNsSet = true;
); } }
const std::string& getPrimary() const { return _primary; }
void unsetNS() { _isNsSet = false; }
void setKeyPattern(const BSONObj keyPattern) { _keyPattern = keyPat
tern.getOwned(); } bool isNSSet() const { return _isNsSet; }
BSONObj getKeyPattern() const { return _keyPattern; }
// Calling get*() methods when the member is not set results in und
void setUnique(bool unique) { _unique = unique; } efined behavior
bool isUnique() const { return _unique; } const std::string getNS() const {
dassert(_isNsSet);
void setUpdatedAt(const Date_t& time) { _updatedAt = time; } return _ns;
Date_t getUpdatedAt() const { return _updatedAt; } }
void setNoBalance(bool noBalance) { _noBalance = noBalance; } void setUpdatedAt(const Date_t updatedAt) {
bool getNoBalance() const { return _noBalance; } _updatedAt = updatedAt;
_isUpdatedAtSet = true;
void setEpoch(OID oid) { _epoch = oid; } }
OID getEpoch() const { return _epoch; }
void unsetUpdatedAt() { _isUpdatedAtSet = false; }
void setDropped(bool dropped) { _dropped = dropped; }
bool isDropped() const { return _dropped; } bool isUpdatedAtSet() const { return _isUpdatedAtSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const Date_t getUpdatedAt() const {
dassert(_isUpdatedAtSet);
return _updatedAt;
}
void setEpoch(const OID epoch) {
_epoch = epoch;
_isEpochSet = true;
}
void unsetEpoch() { _isEpochSet = false; }
bool isEpochSet() const { return _isEpochSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const OID getEpoch() const {
dassert(_isEpochSet);
return _epoch;
}
// Optional Fields
void setPrimary(StringData& primary) {
_primary = primary.toString();
_isPrimarySet = true;
}
void unsetPrimary() { _isPrimarySet = false; }
bool isPrimarySet() const {
return _isPrimarySet || primary.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
std::string getPrimary() const {
if (_isPrimarySet) {
return _primary;
} else {
dassert(primary.hasDefault());
return primary.getDefault();
}
}
void setKeyPattern(BSONObj& keyPattern) {
_keyPattern = keyPattern.getOwned();
_isKeyPatternSet = true;
}
void unsetKeyPattern() { _isKeyPatternSet = false; }
bool isKeyPatternSet() const {
return _isKeyPatternSet || keyPattern.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
BSONObj getKeyPattern() const {
if (_isKeyPatternSet) {
return _keyPattern;
} else {
dassert(keyPattern.hasDefault());
return keyPattern.getDefault();
}
}
void setUnique(bool unique) {
_unique = unique;
_isUniqueSet = true;
}
void unsetUnique() { _isUniqueSet = false; }
bool isUniqueSet() const {
return _isUniqueSet || unique.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
bool getUnique() const {
if (_isUniqueSet) {
return _unique;
} else {
dassert(unique.hasDefault());
return unique.getDefault();
}
}
void setNoBalance(bool noBalance) {
_noBalance = noBalance;
_isNoBalanceSet = true;
}
void unsetNoBalance() { _isNoBalanceSet = false; }
bool isNoBalanceSet() const {
return _isNoBalanceSet || noBalance.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
bool getNoBalance() const {
if (_isNoBalanceSet) {
return _noBalance;
} else {
dassert(noBalance.hasDefault());
return noBalance.getDefault();
}
}
void setDropped(bool dropped) {
_dropped = dropped;
_isDroppedSet = true;
}
void unsetDropped() { _isDroppedSet = false; }
bool isDroppedSet() const {
return _isDroppedSet || dropped.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
bool getDropped() const {
if (_isDroppedSet) {
return _dropped;
} else {
dassert(dropped.hasDefault());
return dropped.getDefault();
}
}
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
std::string _ns; // (M) namespace std::string _ns; // (M) namespace
std::string _primary; // (S) either/or with _keyPattern bool _isNsSet;
BSONObj _keyPattern; // (S) sharding pattern if sharded std::string _primary; // (O) either/or with _keyPattern
bool _unique; // (S) mandatory if sharded, index is unique bool _isPrimarySet;
Date_t _updatedAt; // (M) last updated time BSONObj _keyPattern; // (O) sharding pattern if sharded
bool _noBalance; // (S) optional if sharded, disable balancin bool _isKeyPatternSet;
g bool _unique; // (O) mandatory if sharded, index is unique
OID _epoch; // (M) disambiguates collection incarnations bool _isUniqueSet;
bool _dropped; // (O) if true, ignore this entry Date_t _updatedAt; // (M) last updated time
bool _isUpdatedAtSet;
bool _noBalance; // (O) optional if sharded, disable balancing
bool _isNoBalanceSet;
OID _epoch; // (M) disambiguates collection incarnations
bool _isEpochSet;
bool _dropped; // (O) if true, ignore this entry
bool _isDroppedSet;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 9 change blocks. 
69 lines changed or deleted 199 lines changed or added


 type_config_version.h   type_config_version.h 
skipping to change at line 28 skipping to change at line 28
#include <string> #include <string>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/base/string_data.h" #include "mongo/base/string_data.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
namespace mongo { namespace mongo {
/** /**
* This class represents the layout and contents of the single document * This class represents the layout and contents of documents contained
contained in the in the
* config.version collection. All manipulation of this document should * config.version collection. All manipulation of documents coming from
be done using this class. that
* collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* BSONObj query = QUERY(); * BSONObj query = QUERY(VersionType::exampleField("exampleFieldNam
* versionDoc = conn->findOne(VersionType::ConfigNS, query); e"));
* exampleDoc = conn->findOne(VersionType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* VersionType versionInfo; * VersionType exampleType;
* if (!versionInfo.parseBSON(versionDoc)) { * string errMsg;
* // Can't parse document, take action * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
isValid(&errMsg)) {
* // Can't use 'exampleType'. Take action.
* } * }
* if (!versionInfo.isValid()) { * // use 'exampleType'
* // Can't use version, take action.
* }
* // use 'versionInfo'
* *
*/ */
class VersionType { class VersionType {
MONGO_DISALLOW_COPYING(VersionType); MONGO_DISALLOW_COPYING(VersionType);
public: public:
// Name of the versions collection in the config schema //
static const string ConfigNS; // schema declarations
//
// Name of the version collection in the config server.
static const std::string ConfigNS;
// Field names and types of the version document // Field names and types in the version collection type.
static const BSONField<int> minCompatibleVersion; static const BSONField<int> minCompatibleVersion;
static const BSONField<int> currentVersion; static const BSONField<int> currentVersion;
static const BSONField<BSONArray> excludingMongoVersions; static const BSONField<BSONArray> excludingMongoVersions;
static const BSONField<OID> clusterId; static const BSONField<OID> clusterId;
static const BSONField<int> version_DEPRECATED;
static const BSONField<OID> upgradeId; static const BSONField<OID> upgradeId;
static const BSONField<BSONObj> upgradeState; static const BSONField<BSONObj> upgradeState;
// Transition to new format v2.2->v2.4 //
// We eventually will not use version, minVersion and maxVersion in // version type methods
stead //
static const BSONField<int> version_DEPRECATED;
VersionType(); VersionType();
~VersionType(); ~VersionType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
* representations. Otherwise returns false and fills in the option al 'errMsg' string. * representations. Otherwise returns false and fills in the option al 'errMsg' string.
*/ */
bool isValid(std::string* errMsg) const; bool isValid(std::string* errMsg) const;
skipping to change at line 88 skipping to change at line 93
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(const BSONObj& source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clones to another version entry * Clears the internal state.
*/ */
void cloneTo(VersionType* other) const; void clear();
/** /**
* Clears the internal state. * Copies all the fields present in 'this' to 'other'.
*/ */
void clear(); void cloneTo(VersionType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors and helpers // individual field accessors
//
OID getClusterId() const;
void setClusterId(const OID& clusterId);
int getMinCompatibleVersion() const;
void setMinCompatibleVersion(int version);
int getCurrentVersion() const;
void setCurrentVersion(int version);
//
// Range exclusions
//
// The type knows very little about these ranges, mostly because it
's impossible right now
// to do generic BSON parsing of more complex types without templat
e magick. All
// interpretation of versions happens in the upgrade code.
// //
const BSONArray& getExcludedRanges() const { return _excludes; } // Mandatory Fields
void setExcludedRanges(const BSONArray& excludes) { _excludes = exc void setMinCompatibleVersion(const int minCompatibleVersion) {
ludes; } _minCompatibleVersion = minCompatibleVersion;
_isMinCompatibleVersionSet = true;
OID getUpgradeId() const; }
void setUpgradeId(const OID& upgradeId);
void unsetMinCompatibleVersion() { _isMinCompatibleVersionSet = fal
BSONObj getUpgradeState() const; se; }
void setUpgradeState(const BSONObj& upgradeState);
bool isMinCompatibleVersionSet() const { return _isMinCompatibleVer
sionSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const int getMinCompatibleVersion() const {
dassert(_isMinCompatibleVersionSet);
return _minCompatibleVersion;
}
void setCurrentVersion(const int currentVersion) {
_currentVersion = currentVersion;
_isCurrentVersionSet = true;
}
void unsetCurrentVersion() { _isCurrentVersionSet = false; }
bool isCurrentVersionSet() const { return _isCurrentVersionSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const int getCurrentVersion() const {
dassert(_isCurrentVersionSet);
return _currentVersion;
}
void setExcludingMongoVersions(const BSONArray& excludingMongoVersi
ons) {
_excludingMongoVersions = excludingMongoVersions;
_isExcludingMongoVersionsSet = true;
}
void unsetExcludingMongoVersions() { _isExcludingMongoVersionsSet =
false; }
bool isExcludingMongoVersionsSet() const {
return _isExcludingMongoVersionsSet || excludingMongoVersions.h
asDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
const BSONArray getExcludingMongoVersions() const {
if (_isExcludingMongoVersionsSet) {
return _excludingMongoVersions;
} else {
dassert(excludingMongoVersions.hasDefault());
return excludingMongoVersions.getDefault();
}
}
void setClusterId(const OID clusterId) {
_clusterId = clusterId;
_isClusterIdSet = true;
}
void unsetClusterId() { _isClusterIdSet = false; }
bool isClusterIdSet() const { return _isClusterIdSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const OID getClusterId() const {
dassert(_isClusterIdSet);
return _clusterId;
}
// Optional Fields
void setUpgradeId(OID upgradeId) {
_upgradeId = upgradeId;
_isUpgradeIdSet = true;
}
void unsetUpgradeId() { _isUpgradeIdSet = false; }
bool isUpgradeIdSet() const {
return _isUpgradeIdSet || upgradeId.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
OID getUpgradeId() const {
if (_isUpgradeIdSet) {
return _upgradeId;
} else {
dassert(upgradeId.hasDefault());
return upgradeId.getDefault();
}
}
void setUpgradeState(const BSONObj& upgradeState) {
_upgradeState = upgradeState.getOwned();
_isUpgradeStateSet = true;
}
void unsetUpgradeState() { _isUpgradeStateSet = false; }
bool isUpgradeStateSet() const {
return _isUpgradeStateSet || upgradeState.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
BSONObj getUpgradeState() const {
if (_isUpgradeStateSet) {
return _upgradeState;
} else {
dassert(upgradeState.hasDefault());
return upgradeState.getDefault();
}
}
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
int _minVersion; // (M) minimum compatible version int _minCompatibleVersion; // (M) minimum compatible version
int _currentVersion; // (M) current version bool _isMinCompatibleVersionSet;
OID _clusterId; // (M) clusterId int _currentVersion; // (M) current version
BSONArray _excludes; // (O) mongodb versions excluded from the clus bool _isCurrentVersionSet;
ter BSONArray _excludingMongoVersions; // (O) range of disallowed
OID _upgradeId; // (O) upgrade id of current or last upgrade versions to upgrade to
BSONObj _upgradeState; // (S) upgrade state of current or last upgr bool _isExcludingMongoVersionsSet;
ade OID _clusterId; // (M) clusterId
bool _isClusterIdSet;
OID _upgradeId; // (O) upgrade id of current or last upgrade
bool _isUpgradeIdSet;
BSONObj _upgradeState; // (O) upgrade state of current or last
upgrade
bool _isUpgradeStateSet;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 17 change blocks. 
62 lines changed or deleted 167 lines changed or added


 type_database.h   type_database.h 
skipping to change at line 29 skipping to change at line 29
#include <string> #include <string>
#include "mongo/base/disallow_copying.h" #include "mongo/base/disallow_copying.h"
#include "mongo/base/string_data.h" #include "mongo/base/string_data.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
namespace mongo { namespace mongo {
/** /**
* This class represents the layout and contents of documents contained in the * This class represents the layout and contents of documents contained in the
* config.database collection. All manipulation of documents coming fro m that * config.databases collection. All manipulation of documents coming fr om that
* collection should be done with this class. * collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before. * // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* BSONObj query = QUERY(DatabaseType::name("mydb")); * BSONObj query = QUERY(DatabaseType::exampleField("exampleFieldNa
* dbDoc = conn->findOne(DatbaseType::ConfigNS, query); me"));
* exampleDoc = conn->findOne(DatabaseType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* DatabaseType db; * DatabaseType exampleType;
* string errMsg; * string errMsg;
* if (!db.parseBSON(dbDoc, &errMsg) || !db.isValid(&errMsg)) { * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
* // Can't use 'db'. Take action. isValid(&errMsg)) {
* // Can't use 'exampleType'. Take action.
* } * }
* // use 'db' * // use 'exampleType'
* *
*/ */
class DatabaseType { class DatabaseType {
MONGO_DISALLOW_COPYING(DatabaseType); MONGO_DISALLOW_COPYING(DatabaseType);
public: public:
// //
// schema declarations // schema declarations
// //
// Name of the database collection in the config server. // Name of the databases collection in the config server.
static const std::string ConfigNS; static const std::string ConfigNS;
// Field names and types in the database collection type. // Field names and types in the databases collection type.
static BSONField<std::string> name; // database's name static const BSONField<std::string> name;
static BSONField<std::string> primary; // primary shard for the da static const BSONField<std::string> primary;
tabase static const BSONField<bool> draining;
static BSONField<bool> draining; // is the database being re static const BSONField<bool> DEPRECATED_partitioned;
moved? static const BSONField<std::string> DEPRECATED_name;
static const BSONField<bool> DEPRECATED_sharded;
// This field was last used in 2.2 series (version 3).
static BSONField<bool> DEPRECATED_partitioned;
// These fields were last used in 1.4 series (version 2).
static BSONField<std::string> DEPRECATED_name;
static BSONField<bool> DEPRECATED_sharded;
// //
// database type methods // databases type methods
// //
DatabaseType(); DatabaseType();
~DatabaseType(); ~DatabaseType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
* representations. Otherwise returns false and fills in the option al 'errMsg' string. * representations. Otherwise returns false and fills in the option al 'errMsg' string.
*/ */
bool isValid(std::string* errMsg) const; bool isValid(std::string* errMsg) const;
/** /**
* Returns the BSON representation of the entry. * Returns the BSON representation of the entry.
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(BSONObj source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clears the internal state. * Clears the internal state.
*/ */
void clear(); void clear();
/** /**
* Copies all the fields present in 'this' to 'other'. * Copies all the fields present in 'this' to 'other'.
*/ */
void cloneTo(DatabaseType* other) const; void cloneTo(DatabaseType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors // individual field accessors
// //
void setName(const StringData& name) { _name = name.toString(); } // Mandatory Fields
const std::string& getName() const { return _name; } void setName(const StringData& name) {
_name = name.toString();
void setPrimary(const StringData& shard) { _primary = shard.toStrin _isNameSet = true;
g(); } }
const std::string& getPrimary() const { return _primary; }
void unsetName() { _isNameSet = false; }
void setDraining(bool draining) { _draining = draining; }
bool getDraining() const { return _draining; } bool isNameSet() const { return _isNameSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string& getName() const {
dassert(_isNameSet);
return _name;
}
void setPrimary(const StringData& primary) {
_primary = primary.toString();
_isPrimarySet = true;
}
void unsetPrimary() { _isPrimarySet = false; }
bool isPrimarySet() const { return _isPrimarySet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string& getPrimary() const {
dassert(_isPrimarySet);
return _primary;
}
// Optional Fields
void setDraining(bool draining) {
_draining = draining;
_isDrainingSet = true;
}
void unsetDraining() { _isDrainingSet = false; }
bool isDrainingSet() const {
return _isDrainingSet || draining.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
bool getDraining() const {
if (_isDrainingSet) {
return _draining;
} else {
dassert(draining.hasDefault());
return draining.getDefault();
}
}
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
string _name; // (M) database name std::string _name; // (M) database name
string _primary; // (M) primary shard for the database bool _isNameSet;
bool _draining; // (O) is this database about to be deleted? std::string _primary; // (M) primary shard for the database
bool _isPrimarySet;
bool _draining; // (O) is this database about to be deleted?
bool _isDrainingSet;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 11 change blocks. 
35 lines changed or deleted 81 lines changed or added


 type_lockpings.h   type_lockpings.h 
skipping to change at line 36 skipping to change at line 36
/** /**
* This class represents the layout and contents of documents contained in the * This class represents the layout and contents of documents contained in the
* config.lockpings collection. All manipulation of documents coming fr om that * config.lockpings collection. All manipulation of documents coming fr om that
* collection should be done with this class. * collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before. * // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* unique_ptr<DbClientCursor> cursor; * BSONObj query = QUERY(LockpingsType::exampleField("exampleFieldN
* BSONObj query = QUERY(LockpingsType::name("localhost:27017")); ame"));
* cursor.reset(conn->query(LockpingsType::ConfigNS, query, ...)); * exampleDoc = conn->findOne(LockpingsType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* while (cursor->more()) { * LockpingsType exampleType;
* lockPingDoc = cursor->next(); * string errMsg;
* LockpingsType lockPing; * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
* lockPing.fromBSON(lockPingDoc); isValid(&errMsg)) {
* if (! lockPing.isValid()) { * // Can't use 'exampleType'. Take action.
* // Can't use 'lockPing'. Take action.
* }
* // use 'lockPing'
* } * }
* // use 'exampleType'
*
*/ */
class LockpingsType { class LockpingsType {
MONGO_DISALLOW_COPYING(LockpingsType); MONGO_DISALLOW_COPYING(LockpingsType);
public: public:
// //
// schema declarations // schema declarations
// //
// Name of the lockpings collection in the config server. // Name of the lockpings collection in the config server.
static const std::string ConfigNS; static const std::string ConfigNS;
// Field names and types in the lockpings collection type. // Field names and types in the lockpings collection type.
static BSONField<string> process; // string describing the process static const BSONField<std::string> process;
holding the lock static const BSONField<Date_t> ping;
static BSONField<Date_t> ping; // last time the holding process
updated this document
// //
// lockpings type methods // lockpings type methods
// //
LockpingsType(); LockpingsType();
~LockpingsType(); ~LockpingsType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
skipping to change at line 89 skipping to change at line 85
/** /**
* Returns the BSON representation of the entry. * Returns the BSON representation of the entry.
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(BSONObj source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clears the internal state. * Clears the internal state.
*/ */
void clear(); void clear();
/** /**
* Copies all the fields present in 'this' to 'other'. * Copies all the fields present in 'this' to 'other'.
*/ */
void cloneTo(LockpingsType* other); void cloneTo(LockpingsType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors // individual field accessors
// //
void setProcess(const StringData& process) { _process = process.toS // Mandatory Fields
tring(); } void setProcess(const StringData& process) {
const std::string& getProcess() const { return _process; } _process = process.toString();
_isProcessSet = true;
}
void unsetProcess() { _isProcessSet = false; }
bool isProcessSet() const { return _isProcessSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string& getProcess() const {
dassert(_isProcessSet);
return _process;
}
void setPing(const Date_t ping) {
_ping = ping;
_isPingSet = true;
}
void unsetPing() { _isPingSet = false; }
bool isPingSet() const { return _isPingSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const Date_t getPing() const {
dassert(_isPingSet);
return _ping;
}
void setPing(const Date_t& time) { _ping = time; } // Optional Fields
Date_t getPing() const { return _ping; }
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
std::string _process; // (M) string describing the process holding std::string _process; // (M) string describing the process hol
the lock ding the lock
Date_t _ping; // (M) last time the holding process updated bool _isProcessSet;
this document Date_t _ping; // (M) last time the holding process updated thi
s document
bool _isPingSet;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 11 change blocks. 
27 lines changed or deleted 53 lines changed or added


 type_locks.h   type_locks.h 
skipping to change at line 36 skipping to change at line 36
/** /**
* This class represents the layout and contents of documents contained in the * This class represents the layout and contents of documents contained in the
* config.locks collection. All manipulation of documents coming from t hat * config.locks collection. All manipulation of documents coming from t hat
* collection should be done with this class. * collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before. * // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* BSONObj query = QUERY(LocksType::name("balancer")); * BSONObj query = QUERY(LocksType::exampleField("exampleFieldName"
* lockDoc = conn->findOne(LocksType::ConfigNS, query); ));
* exampleDoc = conn->findOne(LocksType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* LocksType lock; * LocksType exampleType;
* lock.fromBSON(lockDoc); * string errMsg;
* if (! lock.isValid()) { * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
* // Can't use 'lock'. Take action. isValid(&errMsg)) {
* // Can't use 'exampleType'. Take action.
* } * }
* // use 'lock' * // use 'exampleType'
* *
*/ */
class LocksType { class LocksType {
MONGO_DISALLOW_COPYING(LocksType); MONGO_DISALLOW_COPYING(LocksType);
public: public:
// //
// schema declarations // schema declarations
// //
// Name of the collection in the config server. // Name of the locks collection in the config server.
static const std::string ConfigNS; static const std::string ConfigNS;
static BSONField<std::string> name; // name of the lock // Field names and types in the locks collection type.
static BSONField<int> state; // 0: Unlocked static const BSONField<std::string> name;
// 1: Locks in contention static const BSONField<int> state;
// 2: Lock held static const BSONField<std::string> process;
static BSONField<std::string> process; // the process field cont static const BSONField<OID> lockID;
ains the (unique) static const BSONField<std::string> who;
// identifier for the ins static const BSONField<std::string> why;
tance of mongod/mongos
// which has requested th
e lock
static BSONField<OID> lockID; // a unique identifier fo
r the instance of the
// lock itself. Allows fo
r safe cleanup after
// network partitioning
static BSONField<std::string> who; // a note about why the l
ock is held, or which
// subcomponent is holdin
g it
static BSONField<std::string> why; // a human readable descr
iption of the purpose of
// the lock
// //
// collection type methods // locks type methods
// //
LocksType(); LocksType();
~LocksType(); ~LocksType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
* representations. Otherwise returns false and fills in the option al 'errMsg' string. * representations. Otherwise returns false and fills in the option al 'errMsg' string.
*/ */
bool isValid(std::string* errMsg) const; bool isValid(std::string* errMsg) const;
/** /**
* Returns the BSON representation of the entry. * Returns the BSON representation of the entry.
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(BSONObj source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clears the internal state. * Clears the internal state.
*/ */
void clear(); void clear();
/** /**
* Copies all the fields present in 'this' to 'other'. * Copies all the fields present in 'this' to 'other'.
*/ */
void cloneTo(LocksType* other); void cloneTo(LocksType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors // individual field accessors
// //
void setName(const StringData& name) { _name = name.toString(); } // Mandatory Fields
const std::string& getName() const { return _name; } void setName(const StringData& name) {
_name = name.toString();
_isNameSet = true;
}
void unsetName() { _isNameSet = false; }
bool isNameSet() const { return _isNameSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string getName() const {
dassert(_isNameSet);
return _name;
}
void setState(const int state) {
_state = state;
_isStateSet = true;
}
void unsetState() { _isStateSet = false; }
void setState(int state) { _state = state; } bool isStateSet() const { return _isStateSet; }
int getState() const { return _state; }
void setProcess(const StringData& process) { // Calling get*() methods when the member is not set results in und
efined behavior
const int getState() const {
dassert(_isStateSet);
return _state;
}
// Optional Fields
void setProcess(StringData& process) {
_process = process.toString(); _process = process.toString();
_isProcessSet = true;
}
void unsetProcess() { _isProcessSet = false; }
bool isProcessSet() const {
return _isProcessSet || process.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
std::string getProcess() const {
if (_isProcessSet) {
return _process;
} else {
dassert(process.hasDefault());
return process.getDefault();
}
}
void setLockID(OID lockID) {
_lockID = lockID;
_isLockIDSet = true;
}
void unsetLockID() { _isLockIDSet = false; }
bool isLockIDSet() const {
return _isLockIDSet || lockID.hasDefault();
} }
const std::string& getProcess() const { return _process; }
void setLockID(OID lockID) { _lockID = lockID; } // Calling get*() methods when the member is not set and has no def
OID getLockID() const { return _lockID; } ault results in undefined
// behavior
OID getLockID() const {
if (_isLockIDSet) {
return _lockID;
} else {
dassert(lockID.hasDefault());
return lockID.getDefault();
}
}
void setWho(StringData& who) {
_who = who.toString();
_isWhoSet = true;
}
void setWho(const StringData& who) { _who = who.toString(); } void unsetWho() { _isWhoSet = false; }
const std::string& getWho() const { return _who; }
bool isWhoSet() const {
return _isWhoSet || who.hasDefault();
}
void setWhy(const StringData& why) { _why = why.toString(); } // Calling get*() methods when the member is not set and has no def
const std::string& getWhy() const { return _why; } ault results in undefined
// behavior
std::string getWho() const {
if (_isWhoSet) {
return _who;
} else {
dassert(who.hasDefault());
return who.getDefault();
}
}
void setWhy(StringData& why) {
_why = why.toString();
_isWhySet = true;
}
void unsetWhy() { _isWhySet = false; }
bool isWhySet() const {
return _isWhySet || why.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
std::string getWhy() const {
if (_isWhySet) {
return _why;
} else {
dassert(why.hasDefault());
return why.getDefault();
}
}
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
std::string _name; // (M) name of the lock std::string _name; // (M) name of the lock
int _state; // (M) 0: Unlocked | 1: Locks in contention | bool _isNameSet;
2: Lock held int _state; // (M) 0: Unlocked | 1: Locks in contention | 2: L
std::string _process; // (S) optional if unlocked. contains the (u ock held
nique) identifier bool _isStateSet;
// for the instance of mongod/mongos which ha std::string _process; // (O) optional if unlocked. contains t
s requested the lock he (unique) identifier
OID _lockID; // (S) optional if unlocked. a unique identi bool _isProcessSet;
fier for the instance OID _lockID; // (O) optional if unlocked. a unique identifier
// of the lock itself. Allows for safe cleanu for the instance
p after network bool _isLockIDSet;
// partitioning std::string _who; // (O) optional if unlocked. a note about w
std::string _who; // (S) optional if unlocked. a note about wh hy the lock is held,
y the lock is held, bool _isWhoSet;
// or which subcomponent is holding it std::string _why; // (O) optional if unlocked. a human readab
std::string _why; // (S) optional if unlocked. a human readabl le description of the
e description of the bool _isWhySet;
// purpose of the lock
}; };
} // namespace mongo } // namespace mongo
 End of changes. 17 change blocks. 
63 lines changed or deleted 152 lines changed or added


 type_mongos.h   type_mongos.h 
skipping to change at line 36 skipping to change at line 36
/** /**
* This class represents the layout and contents of documents contained in the * This class represents the layout and contents of documents contained in the
* config.mongos collection. All manipulation of documents coming from that * config.mongos collection. All manipulation of documents coming from that
* collection should be done with this class. * collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before. * // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* unique_ptr<DbClientCursor> cursor; * BSONObj query = QUERY(MongosType::exampleField("exampleFieldName
* BSONObj query = QUERY(MongosType::name("localhost:27017")); "));
* cursor.reset(conn->query(MongosType::ConfigNS, query, ...)); * exampleDoc = conn->findOne(MongosType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* while (cursor->more()) { * MongosType exampleType;
* mongosDoc = cursor->next(); * string errMsg;
* MongosType mongos; * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
* mongos.fromBSON(mongosDoc); isValid(&errMsg)) {
* if (! mongos.isValid()) { * // Can't use 'exampleType'. Take action.
* // Can't use 'mongos'. Take action.
* }
* // use 'mongos'
* } * }
* // use 'exampleType'
*
*/ */
class MongosType { class MongosType {
MONGO_DISALLOW_COPYING(MongosType); MONGO_DISALLOW_COPYING(MongosType);
public: public:
// //
// schema declarations // schema declarations
// //
// Name of the mongos collection in the config server. // Name of the mongos collection in the config server.
static const std::string ConfigNS; static const std::string ConfigNS;
// Field names and types in the mongos collection type. // Field names and types in the mongos collection type.
static BSONField<string> name; // "host:port" for this mongos static const BSONField<std::string> name;
static BSONField<Date_t> ping; // last time it was seen alive static const BSONField<Date_t> ping;
static BSONField<int> up; // uptime at the last ping static const BSONField<int> up;
static BSONField<bool> waiting; // for testing purposes static const BSONField<bool> waiting;
static BSONField<string> mongoVersion; // version of mongos static const BSONField<std::string> mongoVersion;
static BSONField<int> configVersion; // config version of mongos static const BSONField<int> configVersion;
// //
// mongos type methods // mongos type methods
// //
MongosType(); MongosType();
~MongosType(); ~MongosType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
skipping to change at line 93 skipping to change at line 89
/** /**
* Returns the BSON representation of the entry. * Returns the BSON representation of the entry.
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(BSONObj source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clears the internal state. * Clears the internal state.
*/ */
void clear(); void clear();
/** /**
* Copies all the fields present in 'this' to 'other'. * Copies all the fields present in 'this' to 'other'.
*/ */
void cloneTo(MongosType* other) const; void cloneTo(MongosType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors // individual field accessors
// //
void setName(const StringData& name) { _name = name.toString(); } // Mandatory Fields
const std::string& getName() const { return _name; } void setName(const StringData& name) {
_name = name.toString();
void setPing(const Date_t& time) { _ping = time; } _isNameSet = true;
Date_t getPing() const { return _ping; } }
void setUp(int up) { _up = up; } void unsetName() { _isNameSet = false; }
int getUp() const { return _up; }
bool isNameSet() const { return _isNameSet; }
void setWaiting(bool waiting) { _waiting = waiting; }
bool getWaiting() const { return _waiting; } // Calling get*() methods when the member is not set results in und
efined behavior
void setMongoVersion(const std::string& mongoVersion) { _mongoVersi const std::string& getName() const {
on = mongoVersion; } dassert(_isNameSet);
const std::string getMongoVersion() const { return _mongoVersion; } return _name;
}
void setConfigVersion(int configVersion) { _configVersion = configV
ersion; } void setPing(const Date_t ping) {
int getConfigVersion() const { return _configVersion; } _ping = ping;
_isPingSet = true;
}
void unsetPing() { _isPingSet = false; }
bool isPingSet() const { return _isPingSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const Date_t getPing() const {
dassert(_isPingSet);
return _ping;
}
void setUp(const int up) {
_up = up;
_isUpSet = true;
}
void unsetUp() { _isUpSet = false; }
bool isUpSet() const { return _isUpSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const int getUp() const {
dassert(_isUpSet);
return _up;
}
void setWaiting(const bool waiting) {
_waiting = waiting;
_isWaitingSet = true;
}
void unsetWaiting() { _isWaitingSet = false; }
bool isWaitingSet() const { return _isWaitingSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const bool getWaiting() const {
dassert(_isWaitingSet);
return _waiting;
}
// Optional Fields
void setMongoVersion(const StringData& mongoVersion) {
_mongoVersion = mongoVersion.toString();
_isMongoVersionSet = true;
}
void unsetMongoVersion() { _isMongoVersionSet = false; }
bool isMongoVersionSet() const {
return _isMongoVersionSet || mongoVersion.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
std::string getMongoVersion() const {
if (_isMongoVersionSet) {
return _mongoVersion;
} else {
dassert(mongoVersion.hasDefault());
return mongoVersion.getDefault();
}
}
void setConfigVersion(const int configVersion) {
_configVersion = configVersion;
_isConfigVersionSet = true;
}
void unsetConfigVersion() { _isConfigVersionSet = false; }
bool isConfigVersionSet() const {
return _isConfigVersionSet || configVersion.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
int getConfigVersion() const {
if (_isConfigVersionSet) {
return _configVersion;
} else {
dassert(configVersion.hasDefault());
return configVersion.getDefault();
}
}
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
string _name; // (M) "host:port" for this mongos std::string _name; // (M) "host:port" for this mongos
Date_t _ping; // (M) last time it was seen alive bool _isNameSet;
int _up; // (M) uptime at the last ping Date_t _ping; // (M) last time it was seen alive
bool _waiting; // (M) for testing purposes bool _isPingSet;
string _mongoVersion; // (M) the mongodb version of the ping int _up; // (M) uptime at the last ping
ing mongos bool _isUpSet;
int _configVersion; // (M) the config version of the pingi bool _waiting; // (M) for testing purposes
ng mongos bool _isWaitingSet;
std::string _mongoVersion; // (O) the mongodb version of the p
inging mongos
bool _isMongoVersionSet;
int _configVersion; // (O) the config version of the pinging m
ongos
bool _isConfigVersionSet;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 9 change blocks. 
46 lines changed or deleted 141 lines changed or added


 type_settings.h   type_settings.h 
skipping to change at line 36 skipping to change at line 36
/** /**
* This class represents the layout and contents of documents contained in the * This class represents the layout and contents of documents contained in the
* config.settings collection. All manipulation of documents coming fro m that * config.settings collection. All manipulation of documents coming fro m that
* collection should be done with this class. * collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before. * // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* unique_ptr<DbClientCursor> cursor; * BSONObj query = QUERY(SettingsType::exampleField("exampleFieldNa
* BSONObj query = QUERY(SettingsType::key("balancer")); me"));
* cursor.reset(conn->query(SettingsType::ConfigNS, query, ...)); * exampleDoc = conn->findOne(SettingsType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* while (cursor->more()) { * SettingsType exampleType;
* settingsDoc = cursor->next(); * string errMsg;
* SettingsType settings; * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
* settings.fromBSON(settingsDoc); isValid(&errMsg)) {
* if (! settings.isValid()) { * // Can't use 'exampleType'. Take action.
* // Can't use 'settings'. Take action.
* }
* // use 'settings'
* } * }
* // use 'exampleType'
*
*/ */
class SettingsType { class SettingsType {
MONGO_DISALLOW_COPYING(SettingsType); MONGO_DISALLOW_COPYING(SettingsType);
public: public:
// //
// schema declarations // schema declarations
// //
// Name of the settings collection in the config server. // Name of the settings collection in the config server.
static const std::string ConfigNS; static const std::string ConfigNS;
// Field names and types in the settings collection type. // Field names and types in the settings collection type.
static BSONField<string> key; // key determinin static const BSONField<std::string> key;
g the type of setting static const BSONField<int> chunksize;
// document this static const BSONField<bool> balancerStopped;
is static const BSONField<BSONObj> balancerActiveWindow;
// === chunksize options === static const BSONField<bool> shortBalancerSleep;
static BSONField<int> chunksize; // size of the ch static const BSONField<bool> secondaryThrottle;
unks in our cluster
// === balancer options ===
static BSONField<bool> balancerStopped; // balancer enabl
ed/disabled
static BSONField<BSONObj> balancerActiveWindow; // if present, ac
tiveWindow is an interval
// during the day
when the balancer should
// be active.
// Format: { star
t: "08:00" , stop:
// "19:30" }, str
ftime format is %H:%M
static BSONField<bool> shortBalancerSleep; // controls how l
ong the balancer sleeps
// in some situat
ions
static BSONField<bool> secondaryThrottle; // only migrate c
hunks as fast as at least
// one secondary
can keep up with
// //
// settings type methods // settings type methods
// //
SettingsType(); SettingsType();
~SettingsType(); ~SettingsType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
skipping to change at line 102 skipping to change at line 89
/** /**
* Returns the BSON representation of the entry. * Returns the BSON representation of the entry.
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(BSONObj source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clears the internal state. * Clears the internal state.
*/ */
void clear(); void clear();
/** /**
* Copies all the fields present in 'this' to 'other'. * Copies all the fields present in 'this' to 'other'.
*/ */
void cloneTo(SettingsType* other); void cloneTo(SettingsType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors // individual field accessors
// //
void setKey(const StringData& key) { _key = key.toString(); } // Mandatory Fields
const std::string& getKey() const { return _key; } void setKey(const StringData& key) {
_key = key.toString();
_isKeySet = true;
}
void unsetKey() { _isKeySet = false; }
bool isKeySet() const { return _isKeySet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string getKey() const {
dassert(_isKeySet);
return _key;
}
// Optional Fields
void setChunksize(int chunksize) {
_chunksize = chunksize;
_isChunksizeSet = true;
}
void unsetChunksize() { _isChunksizeSet = false; }
bool isChunksizeSet() const {
return _isChunksizeSet || chunksize.hasDefault();
}
void setChunksize(int chunksize) { _chunksize = chunksize; } // Calling get*() methods when the member is not set and has no def
int getChunksize() const { return _chunksize; } ault results in undefined
// behavior
int getChunksize() const {
if (_isChunksizeSet) {
return _chunksize;
} else {
dassert(chunksize.hasDefault());
return chunksize.getDefault();
}
}
void setBalancerStopped(bool balancerStopped) {
_balancerStopped = balancerStopped;
_isBalancerStoppedSet = true;
}
void setBalancerStopped(bool balancerStopped) { _balancerStopped = void unsetBalancerStopped() { _isBalancerStoppedSet = false; }
balancerStopped; }
bool getBalancerStopped() const { return _balancerStopped; } bool isBalancerStoppedSet() const {
return _isBalancerStoppedSet || balancerStopped.hasDefault();
}
void setBalancerActiveWindow(const BSONObj balancerActiveWindow) { // Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
bool getBalancerStopped() const {
if (_isBalancerStoppedSet) {
return _balancerStopped;
} else {
dassert(balancerStopped.hasDefault());
return balancerStopped.getDefault();
}
}
void setBalancerActiveWindow(BSONObj& balancerActiveWindow) {
_balancerActiveWindow = balancerActiveWindow.getOwned(); _balancerActiveWindow = balancerActiveWindow.getOwned();
_isBalancerActiveWindowSet = true;
}
void unsetBalancerActiveWindow() { _isBalancerActiveWindowSet = fal
se; }
bool isBalancerActiveWindowSet() const {
return _isBalancerActiveWindowSet || balancerActiveWindow.hasDe
fault();
} }
BSONObj getBalancerActiveWindow() const { return _balancerActiveWin dow; }
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
BSONObj getBalancerActiveWindow() const {
if (_isBalancerActiveWindowSet) {
return _balancerActiveWindow;
} else {
dassert(balancerActiveWindow.hasDefault());
return balancerActiveWindow.getDefault();
}
}
void setShortBalancerSleep(bool shortBalancerSleep) { void setShortBalancerSleep(bool shortBalancerSleep) {
_shortBalancerSleep = shortBalancerSleep; _shortBalancerSleep = shortBalancerSleep;
_isShortBalancerSleepSet = true;
}
void unsetShortBalancerSleep() { _isShortBalancerSleepSet = false;
}
bool isShortBalancerSleepSet() const {
return _isShortBalancerSleepSet || shortBalancerSleep.hasDefaul
t();
} }
bool getShortBalancerSleep() const { return _shortBalancerSleep; }
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
bool getShortBalancerSleep() const {
if (_isShortBalancerSleepSet) {
return _shortBalancerSleep;
} else {
dassert(shortBalancerSleep.hasDefault());
return shortBalancerSleep.getDefault();
}
}
void setSecondaryThrottle(bool secondaryThrottle) { void setSecondaryThrottle(bool secondaryThrottle) {
_secondaryThrottle = secondaryThrottle; _secondaryThrottle = secondaryThrottle;
_isSecondaryThrottleSet = true;
}
void unsetSecondaryThrottle() { _isSecondaryThrottleSet = false; }
bool isSecondaryThrottleSet() const {
return _isSecondaryThrottleSet || secondaryThrottle.hasDefault(
);
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
bool getSecondaryThrottle() const {
if (_isSecondaryThrottleSet) {
return _secondaryThrottle;
} else {
dassert(secondaryThrottle.hasDefault());
return secondaryThrottle.getDefault();
}
} }
bool getSecondaryThrottle() const { return _secondaryThrottle; }
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
std::string _key; // (M) key determining the type of o std::string _key; // (M) key determining the type o
ptions to use f options to use
// === chunksize options === bool _isKeySet;
int _chunksize; // (S) size of the chunks in our clu // === chunksize options ===
ster int _chunksize; // (O) size of the chunks in our
// === balancer options === cluster
bool _balancerStopped; // (O) balancer enabled/disabled bool _isChunksizeSet;
BSONObj _balancerActiveWindow; // (O) if present, activeWindow is a // === balancer options ===
n interval bool _balancerStopped; // (O) balancer enabled/disabled
// during the day when the balancer bool _isBalancerStoppedSet;
should
// be active. BSONObj _balancerActiveWindow; // (O) if present, activeWindow i
// Format: { start: "08:00" , stop: s an interval
// "19:30" }, strftime format is %H: bool _isBalancerActiveWindowSet; // during the day when the balance
%M r should
bool _shortBalancerSleep; // (O) controls how long the balance // be active.
r sleeps // Format: { start: "08:00" , stop
// in some situations :
bool _secondaryThrottle; // (O) only migrate chunks as fast a // "19:30" }, strftime format is %
s at least H:%M
// one secondary can keep up with
bool _shortBalancerSleep; // (O) controls how long the bala
ncer sleeps
bool _isShortBalancerSleepSet; // in some situations
bool _secondaryThrottle; // (O) only migrate chunks as fas
t as at least
bool _isSecondaryThrottleSet; // one secondary can keep up with
}; };
} // namespace mongo } // namespace mongo
 End of changes. 21 change blocks. 
73 lines changed or deleted 166 lines changed or added


 type_shard.h   type_shard.h 
skipping to change at line 34 skipping to change at line 34
namespace mongo { namespace mongo {
/** /**
* This class represents the layout and contents of documents contained in the * This class represents the layout and contents of documents contained in the
* config.shards collection. All manipulation of documents coming from that * config.shards collection. All manipulation of documents coming from that
* collection should be done with this class. * collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* BSONObj query = QUERY(ShardType::name("shard0000")); * BSONObj query = QUERY(ShardType::exampleField("exampleFieldName"
* shardDoc = conn->findOne(ShardType::ConfigNS, query); ));
* exampleDoc = conn->findOne(ShardType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* ShardType shard; * ShardType exampleType;
* shard.fromBSON(shardDoc); * string errMsg;
* if (! shard.isValid()) { * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
* // Can't use 'shard'. Take action. isValid(&errMsg)) {
* // Can't use 'exampleType'. Take action.
* } * }
* // use 'shard' * // use 'exampleType'
* *
*/ */
class ShardType { class ShardType {
MONGO_DISALLOW_COPYING(ShardType); MONGO_DISALLOW_COPYING(ShardType);
public: public:
// //
// schema declarations // schema declarations
// //
// Name of the shard collection in the config server. // Name of the shards collection in the config server.
static const std::string ConfigNS; static const std::string ConfigNS;
// Field names and types in the shard collection type. // Field names and types in the shards collection type.
static BSONField<std::string> name; // shard's id static const BSONField<std::string> name;
static BSONField<std::string> host; // connection string for th static const BSONField<std::string> host;
e host(s) static const BSONField<bool> draining;
static BSONField<bool> draining; // is it draining chunks? static const BSONField<long long> maxSize;
static BSONField<long long> maxSize; // max allowed disk space u static const BSONField<BSONArray> tags;
sage
static BSONField<BSONArray> tags; // shard tags
// //
// shard type methods // shards type methods
// //
ShardType(); ShardType();
~ShardType(); ~ShardType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
* representations. Otherwise returns false and fills in the option al 'errMsg' string. * representations. Otherwise returns false and fills in the option al 'errMsg' string.
*/ */
bool isValid(std::string* errMsg) const; bool isValid(std::string* errMsg) const;
/** /**
* Returns the BSON representation of the entry. * Returns the BSON representation of the entry.
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(BSONObj source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clears the internal state. * Clears the internal state.
*/ */
void clear(); void clear();
/** /**
* Copies all the fields present in 'this' to 'other'. * Copies all the fields present in 'this' to 'other'.
*/ */
void cloneTo(ShardType* other) const; void cloneTo(ShardType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors // individual field accessors
// //
void setName(const StringData& name) { _name = name.toString(); } // Mandatory Fields
const std::string& getName() const { return _name; } void setName(const StringData& name) {
_name = name.toString();
void setHost(const StringData& host) { _host = host.toString(); } _isNameSet = true;
const std::string& getHost() const { return _host; } }
void setDraining(bool draining) { _draining = draining; } void unsetName() { _isNameSet = false; }
bool getDraining() const { return _draining; }
bool isNameSet() const { return _isNameSet; }
void setMaxSize(uint64_t maxSize) { _maxSize = maxSize; }
uint64_t getMaxSize() const { return _maxSize; } // Calling get*() methods when the member is not set results in und
efined behavior
void setTags(const BSONArray& tags) { _tags = tags; } const std::string getName() const {
BSONArray getTags() const { return _tags; } dassert(_isNameSet);
return _name;
}
void setHost(const StringData& host) {
_host = host.toString();
_isHostSet = true;
}
void unsetHost() { _isHostSet = false; }
bool isHostSet() const { return _isHostSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string getHost() const {
dassert(_isHostSet);
return _host;
}
// Optional Fields
void setDraining(bool draining) {
_draining = draining;
_isDrainingSet = true;
}
void unsetDraining() { _isDrainingSet = false; }
bool isDrainingSet() const {
return _isDrainingSet || draining.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
bool getDraining() const {
if (_isDrainingSet) {
return _draining;
} else {
dassert(draining.hasDefault());
return draining.getDefault();
}
}
void setMaxSize(long long maxSize) {
_maxSize = maxSize;
_isMaxSizeSet = true;
}
void unsetMaxSize() { _isMaxSizeSet = false; }
bool isMaxSizeSet() const {
return _isMaxSizeSet || maxSize.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
long long getMaxSize() const {
if (_isMaxSizeSet) {
return _maxSize;
} else {
dassert(maxSize.hasDefault());
return maxSize.getDefault();
}
}
void setTags(BSONArray tags) {
_tags = tags;
_isTagsSet = true;
}
void unsetTags() { _isTagsSet = false; }
bool isTagsSet() const {
return _isTagsSet || tags.hasDefault();
}
// Calling get*() methods when the member is not set and has no def
ault results in undefined
// behavior
BSONArray getTags() const {
if (_isTagsSet) {
return _tags;
} else {
dassert(tags.hasDefault());
return tags.getDefault();
}
}
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
std::string _name; // (M) shard's id std::string _name; // (M) shard's id
std::string _host; // (M) connection string for the host(s) bool _isNameSet;
bool _draining; // (O) is it draining chunks? std::string _host; // (M) connection string for the host(s)
long long _maxSize; // (O) maximum allowed disk space in MB bool _isHostSet;
BSONArray _tags; // (O) shard tags bool _draining; // (O) is it draining chunks?
bool _isDrainingSet;
long long _maxSize; // (O) maximum allowed disk space in MB
bool _isMaxSizeSet;
BSONArray _tags; // (O) shard tags
bool _isTagsSet;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 11 change blocks. 
37 lines changed or deleted 129 lines changed or added


 type_tags.h   type_tags.h 
skipping to change at line 36 skipping to change at line 36
/** /**
* This class represents the layout and contents of documents contained in the * This class represents the layout and contents of documents contained in the
* config.tags collection. All manipulation of documents coming from th at * config.tags collection. All manipulation of documents coming from th at
* collection should be done with this class. * collection should be done with this class.
* *
* Usage Example: * Usage Example:
* *
* // Contact the config. 'conn' has been obtained before. * // Contact the config. 'conn' has been obtained before.
* DBClientBase* conn; * DBClientBase* conn;
* unique_ptr<DbClientCursor> cursor; * BSONObj query = QUERY(TagsType::exampleField("exampleFieldName")
* BSONObj query = QUERY(TagsType::ns("mydb.mycoll")); );
* cursor.reset(conn->query(TagsType::ConfigNS, query, ...)); * exampleDoc = conn->findOne(TagsType::ConfigNS, query);
* *
* // Process the response. * // Process the response.
* while (cursor->more()) { * TagsType exampleType;
* tagDoc = cursor->next(); * string errMsg;
* TagsType tag; * if (!exampleType.parseBSON(exampleDoc, &errMsg) || !exampleType.
* tag.fromBSON(dbDoc); isValid(&errMsg)) {
* if (! tag.isValid()) { * // Can't use 'exampleType'. Take action.
* // Can't use 'tag'. Take action.
* }
* // use 'tag'
* } * }
* // use 'exampleType'
*
*/ */
class TagsType { class TagsType {
MONGO_DISALLOW_COPYING(TagsType); MONGO_DISALLOW_COPYING(TagsType);
public: public:
// //
// schema declarations // schema declarations
// //
// Name of the tags collection in the config server. // Name of the tags collection in the config server.
static const std::string ConfigNS; static const std::string ConfigNS;
// Field names and types in the tags collection type. // Field names and types in the tags collection type.
static BSONField<std::string> ns; // namespace this tag is for static const BSONField<std::string> ns;
static BSONField<std::string> tag; // tag name static const BSONField<std::string> tag;
static BSONField<BSONObj> min; // first key of the tag, includi static const BSONField<BSONObj> min;
ng static const BSONField<BSONObj> max;
static BSONField<BSONObj> max; // last key of the tag, non-incl
uding
// //
// tags type methods // tags type methods
// //
TagsType(); TagsType();
~TagsType(); ~TagsType();
/** /**
* Returns true if all the mandatory fields are present and have va lid * Returns true if all the mandatory fields are present and have va lid
skipping to change at line 90 skipping to change at line 87
/** /**
* Returns the BSON representation of the entry. * Returns the BSON representation of the entry.
*/ */
BSONObj toBSON() const; BSONObj toBSON() const;
/** /**
* Clears and populates the internal state using the 'source' BSON object if the * Clears and populates the internal state using the 'source' BSON object if the
* latter contains valid values. Otherwise sets errMsg and returns false. * latter contains valid values. Otherwise sets errMsg and returns false.
*/ */
bool parseBSON(BSONObj source, std::string* errMsg); bool parseBSON(const BSONObj& source, std::string* errMsg);
/** /**
* Clears the internal state. * Clears the internal state.
*/ */
void clear(); void clear();
/** /**
* Copies all the fields present in 'this' to 'other'. * Copies all the fields present in 'this' to 'other'.
*/ */
void cloneTo(TagsType* other); void cloneTo(TagsType* other) const;
/** /**
* Returns a string representation of the current internal state. * Returns a string representation of the current internal state.
*/ */
std::string toString() const; std::string toString() const;
// //
// individual field accessors // individual field accessors
// //
void setNS(const StringData& ns) { _ns = ns.toString(); } // Mandatory Fields
const std::string& getNS() const { return _ns; } void setNS(const StringData& ns) {
_ns = ns.toString();
_isNsSet = true;
}
void unsetNS() { _isNsSet = false; }
bool isNSSet() const { return _isNsSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string& getNS() const {
dassert(_isNsSet);
return _ns;
}
void setTag(const StringData& tag) {
_tag = tag.toString();
_isTagSet = true;
}
void unsetTag() { _isTagSet = false; }
bool isTagSet() const { return _isTagSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const std::string& getTag() const {
dassert(_isTagSet);
return _tag;
}
void setMin(const BSONObj& min) {
_min = min.getOwned();
_isMinSet = true;
}
void unsetMin() { _isMinSet = false; }
bool isMinSet() const { return _isMinSet; }
// Calling get*() methods when the member is not set results in und
efined behavior
const BSONObj getMin() const {
dassert(_isMinSet);
return _min;
}
void setMax(const BSONObj& max) {
_max = max.getOwned();
_isMaxSet = true;
}
void unsetMax() { _isMaxSet = false; }
void setTag(const StringData& tag) { _tag = tag.toString(); } bool isMaxSet() const { return _isMaxSet; }
const std::string& getTag() const { return _tag; }
void setMin(const BSONObj& min) { _min = min.getOwned(); } // Calling get*() methods when the member is not set results in und
BSONObj getMin() const { return _min; } efined behavior
const BSONObj getMax() const {
dassert(_isMaxSet);
return _max;
}
void setMax(const BSONObj& max) { _max = max.getOwned(); } // Optional Fields
BSONObj getMax() const { return _max; }
private: private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule. // Convention: (M)andatory, (O)ptional, (S)pecial rule.
string _ns; // (M) namespace this tag is for std::string _ns; // (M) namespace this tag is for
string _tag; // (M) tag name bool _isNsSet;
BSONObj _min; // (M) first key of the tag, including std::string _tag; // (M) tag name
BSONObj _max; // (M) last key of the tag, non-including bool _isTagSet;
BSONObj _min; // (M) first key of the tag, including
bool _isMinSet;
BSONObj _max; // (M) last key of the tag, non-including
bool _isMaxSet;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 12 change blocks. 
31 lines changed or deleted 87 lines changed or added


 update_internal.h   update_internal.h 
skipping to change at line 33 skipping to change at line 33
#include "mongo/db/jsobjmanipulator.h" #include "mongo/db/jsobjmanipulator.h"
#include "mongo/db/matcher.h" #include "mongo/db/matcher.h"
#include "mongo/util/embedded_builder.h" #include "mongo/util/embedded_builder.h"
#include "mongo/util/stringutils.h" #include "mongo/util/stringutils.h"
namespace mongo { namespace mongo {
class ModState; class ModState;
class ModSetState; class ModSetState;
/**
* a.$ -> a
* @return true if out is set and we made a change
*/
bool getCanonicalIndexField( const StringData& fullName, string* out );
/* Used for modifiers such as $inc, $set, $push, ... /* Used for modifiers such as $inc, $set, $push, ...
* stores the info about a single operation * stores the info about a single operation
* once created should never be modified * once created should never be modified
*/ */
struct Mod { struct Mod {
// See opFromStr below // See opFromStr below
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
enum Op { INC, SET, PUSH, PUSH_ALL, PULL, PULL_ALL , POP, UNSET, BI TAND, BITOR , BIT , ADDTOSET, RENAME_FROM, RENAME_TO, SET_ON_INSERT } op; enum Op { INC, SET, PUSH, PUSH_ALL, PULL, PULL_ALL , POP, UNSET, BI TAND, BITOR , BIT , ADDTOSET, RENAME_FROM, RENAME_TO, SET_ON_INSERT } op;
static const char* modNames[]; static const char* modNames[];
static unsigned modNamesNum; static unsigned modNamesNum;
const char* fieldName; const char* fieldName;
const char* shortFieldName; const char* shortFieldName;
// Determines if this mod must absoluetly be applied. In some repli cation scenarios, a // Determines if this mod must absoluetly be applied. In some repli cation scenarios, a
// failed apply of a mod does not constitute an error. In those cas es, setting strict // failed apply of a mod does not constitute an error. In those cas es, setting strict
// to off would not throw errors. // to off would not throw errors.
bool strictApply; bool strictApply;
// Determines if an index is going to be updated as part of the app
lication of this
// mod.
bool isIndexed;
BSONElement elt; // x:5 note: this is the actual element from the u pdateobj BSONElement elt; // x:5 note: this is the actual element from the u pdateobj
boost::shared_ptr<Matcher> matcher; boost::shared_ptr<Matcher> matcher;
bool matcherOnPrimitive; bool matcherOnPrimitive;
void init( Op o , BSONElement& e , bool forReplication ) { void init( Op o , BSONElement& e , bool forReplication ) {
op = o; op = o;
elt = e; elt = e;
strictApply = !forReplication; strictApply = !forReplication;
isIndexed = false;
if ( op == PULL && e.type() == Object ) { if ( op == PULL && e.type() == Object ) {
BSONObj t = e.embeddedObject(); BSONObj t = e.embeddedObject();
if ( t.firstElement().getGtLtOp() == 0 ) { if ( t.firstElement().getGtLtOp() == 0 ) {
matcher.reset( new Matcher( t ) ); matcher.reset( new Matcher( t ) );
matcherOnPrimitive = false; matcherOnPrimitive = false;
} }
else { else {
matcher.reset( new Matcher( BSON( "" << t ) ) ); matcher.reset( new Matcher( BSON( "" << t ) ) );
matcherOnPrimitive = true; matcherOnPrimitive = true;
} }
skipping to change at line 142 skipping to change at line 141
switch (op) { switch (op) {
case PUSH: case PUSH:
case PUSH_ALL: case PUSH_ALL:
case POP: case POP:
return true; return true;
default: default:
return false; return false;
} }
} }
static bool isIndexed( const string& fullName , const set<string>&
idxKeys ) {
const char * fieldName = fullName.c_str();
// check if there is an index key that is a parent of mod
for( const char* dot = strchr( fieldName, '.' ); dot; dot = str
chr( dot + 1, '.' ) )
if ( idxKeys.count( string( fieldName, dot - fieldName ) )
)
return true;
// check if there is an index key equal to mod
if ( idxKeys.count(fullName) )
return true;
// check if there is an index key that is a child of mod
set< string >::const_iterator j = idxKeys.upper_bound( fullName
);
if ( j != idxKeys.end() && j->find( fullName ) == 0 && (*j)[ful
lName.size()] == '.' )
return true;
return false;
}
/**
* checks if mod is in the index by inspecting fieldName, and remov
ing
* .$ or .### substrings (#=digit) with any number of digits.
*
* @return true iff the mod is indexed
*/
bool isIndexed( const set<string>& idxKeys ) const {
// first, check if full name is in idxKeys
if ( isIndexed( fieldName , idxKeys ) )
return true;
string x;
if ( getCanonicalIndexField( fieldName, &x ) ) {
if ( isIndexed( x, idxKeys ) )
return true;
}
return false;
}
void apply( BSONBuilderBase& b , BSONElement in , ModState& ms ) co nst; void apply( BSONBuilderBase& b , BSONElement in , ModState& ms ) co nst;
/** /**
* @return true iff toMatch should be removed from the array * @return true iff toMatch should be removed from the array
*/ */
bool _pullElementMatch( BSONElement& toMatch ) const; bool _pullElementMatch( BSONElement& toMatch ) const;
void _checkForAppending( const BSONElement& e ) const { void _checkForAppending( const BSONElement& e ) const {
if ( e.type() == Object ) { if ( e.type() == Object ) {
// this is a tiny bit slow, but rare and important // this is a tiny bit slow, but rare and important
skipping to change at line 232 skipping to change at line 191
BSONObj obj = elt.embeddedObject(); BSONObj obj = elt.embeddedObject();
if ( obj.nFields() != 2 ) if ( obj.nFields() != 2 )
return false; return false;
BSONObjIterator i( obj ); BSONObjIterator i( obj );
i.next(); i.next();
BSONElement elemSlice = i.next(); BSONElement elemSlice = i.next();
return strcmp( elemSlice.fieldName(), "$slice" ) == 0; return strcmp( elemSlice.fieldName(), "$slice" ) == 0;
} }
long long getSlice() const { long long getSlice() const {
// The $slice may be the second or the third elemen in the fiel d object. // The $slice may be the second or the third element in the fie ld object.
// { <field name>: { $each: [<each array>], $slice: -N, $sort: <pattern> } } // { <field name>: { $each: [<each array>], $slice: -N, $sort: <pattern> } }
// 'elt' here is the BSONElement above. // 'elt' here is the BSONElement above.
BSONObj obj = elt.embeddedObject(); BSONObj obj = elt.embeddedObject();
BSONObjIterator i( obj ); BSONObjIterator i( obj );
i.next(); i.next();
BSONElement elem = i.next(); BSONElement elem = i.next();
if ( ! str::equals( elem.fieldName(), "$slice" ) ) { if ( ! str::equals( elem.fieldName(), "$slice" ) ) {
elem = i.next(); elem = i.next();
} }
dassert( elem.isNumber() ); dassert( elem.isNumber() );
skipping to change at line 310 skipping to change at line 269
} }
}; };
/** /**
* stores a set of Mods * stores a set of Mods
* once created, should never be changed * once created, should never be changed
*/ */
class ModSet : boost::noncopyable { class ModSet : boost::noncopyable {
typedef map<string,Mod> ModHolder; typedef map<string,Mod> ModHolder;
ModHolder _mods; ModHolder _mods;
int _isIndexed; int _numIndexMaybeUpdated;
int _numIndexAlwaysUpdated;
bool _hasDynamicArray; bool _hasDynamicArray;
static Mod::Op opFromStr( const char* fn ) { static Mod::Op opFromStr( const char* fn ) {
verify( fn[0] == '$' ); verify( fn[0] == '$' );
switch( fn[1] ) { switch( fn[1] ) {
case 'i': { case 'i': {
if ( fn[2] == 'n' && fn[3] == 'c' && fn[4] == 0 ) if ( fn[2] == 'n' && fn[3] == 'c' && fn[4] == 0 )
return Mod::INC; return Mod::INC;
break; break;
} }
skipping to change at line 392 skipping to change at line 352
break; break;
} }
default: break; default: break;
} }
uassert( 10161 , "Invalid modifier specified " + string( fn ), false ); uassert( 10161 , "Invalid modifier specified " + string( fn ), false );
return Mod::INC; return Mod::INC;
} }
ModSet() {} ModSet() {}
void updateIsIndexed( const Mod& m, const set<string>& idxKeys, con /**
st set<string>* backgroundKeys ) { * if if applying this mod would require updating an index, set suc
if ( m.isIndexed( idxKeys ) || h condition in 'm',
(backgroundKeys && m.isIndexed(*backgroundKeys)) ) { * and update the number of indices touched in 'this' ModSet.
_isIndexed++; */
} void setIndexedStatus( Mod& m, const IndexPathSet& idxKeys );
}
public: public:
ModSet( const BSONObj& from, ModSet( const BSONObj& from,
const set<string>& idxKeys = set<string>(), const IndexPathSet& idxKeys = IndexPathSet(),
const set<string>* backgroundKeys = 0,
bool forReplication = false ); bool forReplication = false );
/** /**
* re-check if this mod is impacted by indexes * re-check if this mod is impacted by indexes
*/ */
void updateIsIndexed( const set<string>& idxKeys, const set<string> * backgroundKeys ); void setIndexedStatus( const IndexPathSet& idxKeys );
// TODO: this is inefficient - should probably just handle when ite rating // TODO: this is inefficient - should probably just handle when ite rating
ModSet * fixDynamicArray( const string& elemMatchKey ) const; ModSet * fixDynamicArray( const string& elemMatchKey ) const;
bool hasDynamicArray() const { return _hasDynamicArray; } bool hasDynamicArray() const { return _hasDynamicArray; }
/** /**
* creates a ModSetState suitable for operation on obj * creates a ModSetState suitable for operation on obj
* doesn't change or modify this ModSet or any underlying Mod * doesn't change or modify this ModSet or any underlying Mod
*
* flag 'insertion' differentiates between obj existing prior to th
is update.
*/ */
auto_ptr<ModSetState> prepare( const BSONObj& obj ) const; auto_ptr<ModSetState> prepare( const BSONObj& obj, bool insertion = false ) const;
/** /**
* given a query pattern, builds an object suitable for an upsert * given a query pattern, builds an object suitable for an upsert
* will take the query spec and combine all $ operators * will take the query spec and combine all $ operators
*/ */
BSONObj createNewFromQuery( const BSONObj& query ); BSONObj createNewFromQuery( const BSONObj& query );
int isIndexed() const { return _isIndexed; } int maxNumIndexUpdated() const { return _numIndexMaybeUpdated + _nu mIndexAlwaysUpdated; }
unsigned size() const { return _mods.size(); } unsigned size() const { return _mods.size(); }
bool haveModForField( const char* fieldName ) const { bool haveModForField( const char* fieldName ) const {
return _mods.find( fieldName ) != _mods.end(); return _mods.find( fieldName ) != _mods.end();
} }
bool haveConflictingMod( const string& fieldName ) { bool haveConflictingMod( const string& fieldName ) {
size_t idx = fieldName.find( '.' ); size_t idx = fieldName.find( '.' );
if ( idx == string::npos ) if ( idx == string::npos )
skipping to change at line 464 skipping to change at line 424
} }
}; };
/** /**
* Comparator between two BSONObjects that takes in consideration only the keys and * Comparator between two BSONObjects that takes in consideration only the keys and
* direction described in the sort pattern. * direction described in the sort pattern.
*/ */
struct ProjectKeyCmp { struct ProjectKeyCmp {
BSONObj sortPattern; BSONObj sortPattern;
BSONObj projectionPattern;
ProjectKeyCmp( BSONObj pattern ) : sortPattern( pattern ) {
BSONObjBuilder projectBuilder;
BSONObjIterator i( sortPattern );
while ( i.more() ) {
BSONElement elem = i.next();
uassert( 16645, "sort pattern must be numeric", elem.isNumb
er() );
double val = elem.Number(); ProjectKeyCmp( BSONObj pattern ) : sortPattern( pattern) {}
uassert( 16646, "sort pattern must contain 1 or -1", val*va
l == 1.0);
//
// If there are dots in the field name, check that they for
m a proper
// field path (e.g., no empty field parts).
//
StringData field( elem.fieldName() );
uassert( 16651, "sort pattern field name cannot be empty" ,
field.size() );
size_t pos = field.find('.');
while ( pos != string::npos ) {
uassert( 16639,
"empty field in dotted sort pattern",
(pos > 0) && (pos != field.size() - 1) );
field = field.substr( pos+1 );
pos = field.find('.');
}
projectBuilder.append( elem.fieldName(), 1 ); int operator()( const BSONObj& left, const BSONObj& right ) const {
BSONObj keyLeft = left.extractFields( sortPattern, true );
} BSONObj keyRight = right.extractFields( sortPattern, true );
projectionPattern = projectBuilder.obj();
}
int operator()( const BSONObj& left, const BSONObj& right ) {
BSONObj keyLeft = left.extractFields( projectionPattern, true )
;
BSONObj keyRight = right.extractFields( projectionPattern, true
);
return keyLeft.woCompare( keyRight, sortPattern ) < 0; return keyLeft.woCompare( keyRight, sortPattern ) < 0;
} }
}; };
/** /**
* stores any information about a single Mod operating on a single Obje ct * stores any information about a single Mod operating on a single Obje ct
*/ */
class ModState : boost::noncopyable { class ModState : boost::noncopyable {
public: public:
const Mod* m; const Mod* m;
skipping to change at line 572 skipping to change at line 498
return true; return true;
case Mod::BIT: case Mod::BIT:
case Mod::BITAND: case Mod::BITAND:
case Mod::BITOR: case Mod::BITOR:
return true; return true;
default: default:
return false; return false;
} }
} }
const char* getOpLogName() const;
void appendForOpLog( BSONObjBuilder& b ) const; void appendForOpLog( BSONObjBuilder& b ) const;
void apply( BSONBuilderBase& b , BSONElement in ) { void apply( BSONBuilderBase& b , BSONElement in ) {
m->apply( b , in , *this ); m->apply( b , in , *this );
} }
void appendIncValue( BSONBuilderBase& b , bool useFullName ) const { void appendIncValue( BSONBuilderBase& b , bool useFullName ) const {
const char* n = useFullName ? m->fieldName : m->shortFieldName; const char* n = useFullName ? m->fieldName : m->shortFieldName;
switch ( incType ) { switch ( incType ) {
skipping to change at line 609 skipping to change at line 536
* this is used to hold state, meta data while applying a ModSet to a B SONObj * this is used to hold state, meta data while applying a ModSet to a B SONObj
* the goal is to make ModSet const so its re-usable * the goal is to make ModSet const so its re-usable
*/ */
class ModSetState : boost::noncopyable { class ModSetState : boost::noncopyable {
typedef map<string,shared_ptr<ModState>,LexNumCmp> ModStateHolder; typedef map<string,shared_ptr<ModState>,LexNumCmp> ModStateHolder;
typedef pair<const ModStateHolder::iterator,const ModStateHolder::i terator> ModStateRange; typedef pair<const ModStateHolder::iterator,const ModStateHolder::i terator> ModStateRange;
const BSONObj& _obj; const BSONObj& _obj;
ModStateHolder _mods; ModStateHolder _mods;
bool _inPlacePossible; bool _inPlacePossible;
BSONObj _newFromMods; // keep this data alive, as oplog generation may depend on it BSONObj _newFromMods; // keep this data alive, as oplog generation may depend on it
int _numIndexAlwaysUpdated;
int _numIndexMaybeUpdated;
ModSetState( const BSONObj& obj ) ModSetState( const BSONObj& obj , int numIndexAlwaysUpdated , int n
: _obj( obj ) , _mods( LexNumCmp( true ) ) , _inPlacePossible(t umIndexMaybeUpdated )
rue) { : _obj( obj )
, _mods( LexNumCmp( true ) )
, _inPlacePossible(true)
, _numIndexAlwaysUpdated( numIndexAlwaysUpdated )
, _numIndexMaybeUpdated( numIndexMaybeUpdated ) {
} }
/** /**
* @return if in place is still possible * @return if in place is still possible
*/ */
bool amIInPlacePossible( bool inPlacePossible ) { bool amIInPlacePossible( bool inPlacePossible ) {
if ( ! inPlacePossible ) if ( ! inPlacePossible )
_inPlacePossible = false; _inPlacePossible = false;
return _inPlacePossible; return _inPlacePossible;
} }
skipping to change at line 677 skipping to change at line 610
continue; continue;
} }
arrBuilder.append( j.next() ); arrBuilder.append( j.next() );
} }
ms.forceEmptyArray = true; ms.forceEmptyArray = true;
ms.fixedArray = BSONArray( arrBuilder.done().getOwn ed() ); ms.fixedArray = BSONArray( arrBuilder.done().getOwn ed() );
} }
else if ( m.isSliceAndSort() ) { else if ( m.isSliceAndSort() ) {
long long slice = m.getSlice(); long long slice = m.getSlice();
BSONObj sortPattern = m.getSort();
// Sort the $each array over sortPattern. // Sort the $each array over sortPattern.
vector<BSONObj> workArea; vector<BSONObj> workArea;
BSONObjIterator j( arr ); BSONObjIterator j( arr );
while ( j.more() ) { while ( j.more() ) {
workArea.push_back( j.next().Obj() ); workArea.push_back( j.next().Obj() );
} }
sort( workArea.begin(), workArea.end(), ProjectKeyC ProjectKeyCmp cmp( m.getSort() );
mp( sortPattern) ); sort( workArea.begin(), workArea.end(), cmp );
// Slice to the appropriate size. If slice is zero, that's equivalent // Slice to the appropriate size. If slice is zero, that's equivalent
// to resetting the array, ie, a no-op. // to resetting the array, ie, a no-op.
BSONArrayBuilder arrBuilder( b.subarrayStart( m.sho rtFieldName ) ); BSONArrayBuilder arrBuilder( b.subarrayStart( m.sho rtFieldName ) );
if (slice > 0) { if (slice > 0) {
long long skip = std::max( 0LL, long long skip = std::max( 0LL,
(long long)workArea. size() - slice ); (long long)workArea. size() - slice );
for (vector<BSONObj>::iterator it = workArea.be gin(); for (vector<BSONObj>::iterator it = workArea.be gin();
it != workArea.end(); it != workArea.end();
++it ) { ++it ) {
skipping to change at line 794 skipping to change at line 727
/** @return true iff the elements aren't eoo(), are distinct, and s hare a field name. */ /** @return true iff the elements aren't eoo(), are distinct, and s hare a field name. */
static bool duplicateFieldName( const BSONElement& a, const BSONEle ment& b ); static bool duplicateFieldName( const BSONElement& a, const BSONEle ment& b );
public: public:
bool canApplyInPlace() const { bool canApplyInPlace() const {
return _inPlacePossible; return _inPlacePossible;
} }
bool isUpdateIndexed() const {
if ( _numIndexAlwaysUpdated != 0 ) {
return true;
}
return isUpdateIndexedSlow();
}
bool isUpdateIndexedSlow() const;
/** /**
* modified underlying _obj * modified underlying _obj
* @param isOnDisk - true means this is an on disk object, and this update needs to be made durable * @param isOnDisk - true means this is an on disk object, and this update needs to be made durable
*/ */
void applyModsInPlace( bool isOnDisk ); void applyModsInPlace( bool isOnDisk );
BSONObj createNewFromMods(); BSONObj createNewFromMods();
// re-writing for oplog // re-writing for oplog
bool DEPRECATED_needOpLogRewrite() const { bool DEPRECATED_needOpLogRewrite() const {
for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ ) for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ )
if ( i->second->DEPRECATED_needOpLogRewrite() ) if ( i->second->DEPRECATED_needOpLogRewrite() )
return true; return true;
return false; return false;
} }
BSONObj getOpLogRewrite() const { BSONObj getOpLogRewrite() const;
BSONObjBuilder b;
for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m
ods.end(); i++ )
i->second->appendForOpLog( b );
return b.obj();
}
bool DEPRECATED_haveArrayDepMod() const { bool DEPRECATED_haveArrayDepMod() const {
for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ ) for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ )
if ( i->second->m->arrayDep() ) if ( i->second->m->arrayDep() )
return true; return true;
return false; return false;
} }
void DEPRECATED_appendSizeSpecForArrayDepMods( BSONObjBuilder& b ) const { void DEPRECATED_appendSizeSpecForArrayDepMods( BSONObjBuilder& b ) const {
for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ ) { for ( ModStateHolder::const_iterator i = _mods.begin(); i != _m ods.end(); i++ ) {
 End of changes. 22 change blocks. 
123 lines changed or deleted 49 lines changed or added


 v8_db.h   v8_db.h 
skipping to change at line 30 skipping to change at line 30
#include <boost/function.hpp> #include <boost/function.hpp>
#include <v8.h> #include <v8.h>
#include "mongo/scripting/engine_v8.h" #include "mongo/scripting/engine_v8.h"
namespace mongo { namespace mongo {
class DBClientBase; class DBClientBase;
/** /**
* install the db related functions and objects in the given scope * install database access functions
*/ */
void installDBTypes(V8Scope* scope, v8::Handle<v8::Object>& global); void installDBAccess(V8Scope* scope);
/**
* install BSON types and helpers
*/
void installBSONTypes(V8Scope* scope);
/** /**
* get the DBClientBase connection from JS args * get the DBClientBase connection from JS args
*/ */
mongo::DBClientBase* getConnection(const v8::Arguments& args); mongo::DBClientBase* getConnection(const v8::Arguments& args);
// Mongo constructors // Mongo constructors
v8::Handle<v8::Value> mongoConsLocal(V8Scope* scope, const v8::Argument s& args); v8::Handle<v8::Value> mongoConsLocal(V8Scope* scope, const v8::Argument s& args);
v8::Handle<v8::Value> mongoConsExternal(V8Scope* scope, const v8::Argum ents& args); v8::Handle<v8::Value> mongoConsExternal(V8Scope* scope, const v8::Argum ents& args);
v8::Handle<v8::FunctionTemplate> getMongoFunctionTemplate(V8Scope* scop e, bool local); v8::Handle<v8::FunctionTemplate> getMongoFunctionTemplate(V8Scope* scop e, bool local);
 End of changes. 2 change blocks. 
2 lines changed or deleted 7 lines changed or added


 v8_utils.h   v8_utils.h 
skipping to change at line 28 skipping to change at line 28
#pragma once #pragma once
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <v8.h> #include <v8.h>
namespace mongo { namespace mongo {
void ReportException(v8::TryCatch* handler); #define jsassert(x,msg) uassert(16664, (msg), (x))
#define jsassert(x,msg) uassert(16664, msg, x) #define argumentCheck(mustBeTrue, errorMessage) \
if (!(mustBeTrue)) { \
return v8AssertionException((errorMessage)); \
}
std::ostream& operator<<(std::ostream& s, const v8::Handle<v8::Value>& o); std::ostream& operator<<(std::ostream& s, const v8::Handle<v8::Value>& o);
std::ostream& operator<<(std::ostream& s, const v8::Handle<v8::TryCatch >* try_catch); std::ostream& operator<<(std::ostream& s, const v8::Handle<v8::TryCatch >* try_catch);
/** Simple v8 object to string conversion helper */
std::string toSTLString(const v8::Handle<v8::Value>& o); std::string toSTLString(const v8::Handle<v8::Value>& o);
std::string toSTLString(const v8::TryCatch* try_catch);
/** Get the properties of an object (and it's prototype) as a comma-del
imited string */
std::string v8ObjectToString(const v8::Handle<v8::Object>& o);
class V8Scope; class V8Scope;
void installFork(V8Scope* scope, void installFork(V8Scope* scope,
v8::Handle<v8::Object>& global, v8::Handle<v8::Object>& global,
v8::Handle<v8::Context>& context); v8::Handle<v8::Context>& context);
/** Throw a V8 exception from Mongo callback code; message text will be
preceded by "Error: ".
* Note: this function should be used for text that did not originate
from the JavaScript
* engine. Errors from the JavaScript engine will already have
a prefix such as
* ReferenceError, TypeError or SyntaxError.
* Note: call only from a native function called from JavaScript (a c
allback).
* The V8 ThrowException routine will note a JavaScript excepti
on that will be
* "thrown" in JavaScript when we return from the native functi
on.
* Note: it's required to return immediately to V8's execution contro
l without calling any
* V8 API functions. In this state, an empty handle may (will)
be returned.
* @param errorMessage Error message text.
* @return Empty handle to be returned from callback function.
*/
v8::Handle<v8::Value> v8AssertionException(const char* errorMessage);
v8::Handle<v8::Value> v8AssertionException(const std::string& errorMess
age);
} }
 End of changes. 5 change blocks. 
3 lines changed or deleted 34 lines changed or added


 value_internal.h   value_internal.h 
skipping to change at line 121 skipping to change at line 121
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) {
putString(StringData(static_cast<const char*>(bd.data), bd.leng putRefCountable(
th)); RCString::create(
StringData(static_cast<const char*>(bd.data), bd.length
)));
binSubType = bd.type; binSubType = bd.type;
} }
void putDBRef(const BSONDBRef& dbref) { void putDBRef(const BSONDBRef& dbref) {
putRefCountable(new RCDBRef(dbref.ns.toString(), dbref.oid)); putRefCountable(new RCDBRef(dbref.ns.toString(), dbref.oid));
} }
void putCodeWScope(const BSONCodeWScope& cws) { void putCodeWScope(const BSONCodeWScope& cws) {
putRefCountable(new RCCodeWScope(cws.code.toString(), cws.scope )); putRefCountable(new RCCodeWScope(cws.code.toString(), cws.scope ));
} }
skipping to change at line 213 skipping to change at line 215
// bytes 3-16; // bytes 3-16;
union { union {
unsigned char oid[12]; unsigned char oid[12];
struct { struct {
char shortStrSize; // TODO Consider moving into fla gs union (4 bits) char shortStrSize; // TODO Consider moving into fla gs union (4 bits)
char shortStrStorage[16/*total bytes*/ - 3/*offset* / - 1/*NUL byte*/]; char shortStrStorage[16/*total bytes*/ - 3/*offset* / - 1/*NUL byte*/];
union { union {
char nulTerminator; char nulTerminator;
unsigned char binSubType; // type always goes h ere even if !shortStr
}; };
}; };
struct { struct {
union { union {
unsigned char binSubType;
char pad[6]; char pad[6];
char stringCache[6]; // TODO copy first few byt es of strings in here char stringCache[6]; // TODO copy first few byt es of strings in here
}; };
union { // 8 bytes long and 8-byte aligned union { // 8 bytes long and 8-byte aligned
// There should be no pointers to non-const dat a // There should be no pointers to non-const dat a
const RefCountable* genericRCPtr; const RefCountable* genericRCPtr;
double doubleValue; double doubleValue;
bool boolValue; bool boolValue;
int intValue; int intValue;
 End of changes. 3 change blocks. 
3 lines changed or deleted 5 lines changed or added


 version.h   version.h 
skipping to change at line 33 skipping to change at line 33
#include "mongo/bson/bsonobjbuilder.h" #include "mongo/bson/bsonobjbuilder.h"
namespace mongo { namespace mongo {
struct BSONArray; struct BSONArray;
// mongo version // mongo version
extern const char versionString[]; extern const char versionString[];
extern const BSONArray versionArray; extern const BSONArray versionArray;
std::string mongodVersion(); std::string mongodVersion();
// Convert a version string into a numeric array
BSONArray toVersionArray(const char* version);
// Checks whether another version is the same major version as us
bool isSameMajorVersion(const char* version);
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();
 End of changes. 1 change blocks. 
0 lines changed or deleted 6 lines changed or added


 windows_basic.h   windows_basic.h 
skipping to change at line 30 skipping to change at line 30
#if defined(_WIN32) #if defined(_WIN32)
// for rand_s() usage: // for rand_s() usage:
# define _CRT_RAND_S # define _CRT_RAND_S
# ifndef NOMINMAX # ifndef NOMINMAX
# define NOMINMAX # define NOMINMAX
# endif # endif
// tell windows.h not to include a bunch of headers we don't need: // tell windows.h not to include a bunch of headers we don't need:
# define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
# include "mongo/targetver.h" # include "mongo/targetver.h"
# include <winsock2.h> //this must be included before the first windows.h i nclude # include <winsock2.h> //this must be included before the first windows.h i nclude
# include <ws2tcpip.h> # include <ws2tcpip.h>
# include <wspiapi.h> # include <wspiapi.h>
# include <windows.h> # include <windows.h>
#endif #endif
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 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/platform/unordered_map.h"
#include "mongo/platform/unordered_set.h"
#include "../client/connpool.h" #include "../client/connpool.h"
#include "../util/background.h" #include "../util/background.h"
#include "../db/client.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.
skipping to change at line 75 skipping to change at line 77
WriteBackListener( const string& addr ); WriteBackListener( const string& addr );
string name() const { return _name; } string name() const { return _name; }
void run(); void run();
private: private:
string _addr; string _addr;
string _name; string _name;
static mongo::mutex _cacheLock; // protects _cache static mongo::mutex _cacheLock; // protects _cache
static map<string,WriteBackListener*> _cache; // server to listener static unordered_map<string,WriteBackListener*> _cache; // server t
static set<string> _seenSets; // cache of set urls we've seen - not o listener
e this is ever expanding for order, case, changes static unordered_set<string> _seenSets; // cache of set urls we've
seen - note this is ever expanding for order, case, changes
struct WBStatus { struct WBStatus {
OID id; OID id;
BSONObj gle; BSONObj gle;
}; };
static mongo::mutex _seenWritebacksLock; // protects _seenWritback s static mongo::mutex _seenWritebacksLock; // protects _seenWritback s
static map<ConnectionIdent,WBStatus> _seenWritebacks; // connection Id -> last write back GLE static map<ConnectionIdent,WBStatus> _seenWritebacks; // connection Id -> last write back GLE
}; };
 End of changes. 2 change blocks. 
3 lines changed or deleted 6 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/