summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
Diffstat (limited to 'db')
-rw-r--r--db/cmdline.h5
-rw-r--r--db/db.cpp9
-rw-r--r--db/dbcommands.cpp2
-rw-r--r--db/dbhelpers.cpp2
-rw-r--r--db/instance.cpp4
-rw-r--r--db/pdfile.cpp2
-rw-r--r--db/query.h26
-rw-r--r--db/repl.cpp12
-rw-r--r--db/update.cpp81
9 files changed, 83 insertions, 60 deletions
diff --git a/db/cmdline.h b/db/cmdline.h
index fff2fbec511..801343c9f14 100644
--- a/db/cmdline.h
+++ b/db/cmdline.h
@@ -26,13 +26,14 @@ namespace mongo {
string source; // --source
string only; // --only
-
+
bool quiet; // --quiet
bool notablescan; // --notablescan
bool prealloc; // --noprealloc
bool smallfiles; // --smallfiles
bool quota; // --quota
+ int quotaFiles; // --quotaFiles
bool cpu; // --cpu show cpu time periodically
long long oplogSize; // --oplogSize
@@ -43,7 +44,7 @@ namespace mongo {
CmdLine() :
port(27017), quiet(false), notablescan(false), prealloc(true), smallfiles(false),
- quota(false), cpu(false), oplogSize(0)
+ quota(false), quotaFiles(8), cpu(false), oplogSize(0)
{ }
};
diff --git a/db/db.cpp b/db/db.cpp
index 159a90c04f5..a7541776f07 100644
--- a/db/db.cpp
+++ b/db/db.cpp
@@ -96,8 +96,8 @@ namespace mongo {
deleteObjects("sys.unittest.delete", j1, false);
theDataFileMgr.insert("sys.unittest.delete", &js1, sizeof(js1));
deleteObjects("sys.unittest.delete", j1, false);
- updateObjects("sys.unittest.delete", j1, j1, true,ss);
- updateObjects("sys.unittest.delete", j1, j1, false,ss);
+ updateObjects("sys.unittest.delete", j1, j1, true,false,ss,true);
+ updateObjects("sys.unittest.delete", j1, j1, false,false,ss,true);
auto_ptr<Cursor> c = theDataFileMgr.findAll("sys.unittest.pdfile");
while ( c->ok() ) {
@@ -541,6 +541,7 @@ int main(int argc, char* argv[], char *envp[] )
("auth", "run with security")
("objcheck", "inspect client data for validity on receipt")
("quota", "enable db quota management")
+ ("quotaFiles", po::value<int>(), "number of files allower per db, requires --quota")
("appsrvpath", po::value<string>(), "root directory for the babble app server")
("nocursors", "diagnostic/debugging option")
("nohints", "ignore query hints")
@@ -694,6 +695,10 @@ int main(int argc, char* argv[], char *envp[] )
if (params.count("quota")) {
cmdLine.quota = true;
}
+ if (params.count("quotaFiles")) {
+ cmdLine.quota = true;
+ cmdLine.quotaFiles = params["quotaFiles"].as<int>() - 1;
+ }
if (params.count("objcheck")) {
objcheck = true;
}
diff --git a/db/dbcommands.cpp b/db/dbcommands.cpp
index 6d89570a19c..2068400339d 100644
--- a/db/dbcommands.cpp
+++ b/db/dbcommands.cpp
@@ -1314,7 +1314,7 @@ namespace mongo {
n = map.size();
s->setObject( "$key" , key , true );
- uassert( "group() can't handle more than 10000 unique keys" , n < 10000 );
+ uassert( "group() can't handle more than 10000 unique keys" , n <= 10000 );
}
s->setObject( "obj" , obj , true );
diff --git a/db/dbhelpers.cpp b/db/dbhelpers.cpp
index 1956c4bd560..45e4176463b 100644
--- a/db/dbhelpers.cpp
+++ b/db/dbhelpers.cpp
@@ -122,7 +122,7 @@ namespace mongo {
void Helpers::putSingleton(const char *ns, BSONObj obj) {
DBContext context(ns);
stringstream ss;
- updateObjects(ns, obj, /*pattern=*/BSONObj(), /*upsert=*/true, ss);
+ updateObjects(ns, obj, /*pattern=*/BSONObj(), /*upsert=*/true, /*multi=*/false, ss, /*logop=*/true );
}
void Helpers::emptyCollection(const char *ns) {
diff --git a/db/instance.cpp b/db/instance.cpp
index 8b039cb2d7e..df9e8243b58 100644
--- a/db/instance.cpp
+++ b/db/instance.cpp
@@ -358,8 +358,8 @@ namespace mongo {
CurOp& currentOp = *client.curop();
strncpy(currentOp.query, s.c_str(), sizeof(currentOp.query)-2);
}
- bool updatedExisting = updateObjects(ns, toupdate, query, upsert, ss, multi);
- recordUpdate( updatedExisting, ( upsert || updatedExisting ) ? 1 : 0 ); // for getlasterror
+ UpdateResult res = updateObjects(ns, toupdate, query, upsert, multi, ss, true);
+ recordUpdate( res.existing , res.num ); // for getlasterror
}
void receivedDelete(Message& m, stringstream &ss) {
diff --git a/db/pdfile.cpp b/db/pdfile.cpp
index 23f3c4508a7..b24347dca2a 100644
--- a/db/pdfile.cpp
+++ b/db/pdfile.cpp
@@ -226,7 +226,7 @@ namespace mongo {
very simple temporary implementation - we will in future look up
the quota from the grid database
*/
- if ( cmdLine.quota && fileNo > 8 && !boost::filesystem::exists(filename) ) {
+ if ( cmdLine.quota && fileNo > cmdLine.quotaFiles && !boost::filesystem::exists(filename) ) {
/* todo: if we were adding / changing keys in an index did we do some
work previously that needs cleaning up? Possible. We should
check code like that and have it catch the exception and do
diff --git a/db/query.h b/db/query.h
index 3a4f975ba51..16be7c44f55 100644
--- a/db/query.h
+++ b/db/query.h
@@ -74,10 +74,34 @@ namespace mongo {
// for an existing query (ie a ClientCursor), send back additional information.
QueryResult* getMore(const char *ns, int ntoreturn, long long cursorid , stringstream& ss);
+ struct UpdateResult {
+ bool existing;
+ bool mod;
+ unsigned long long num;
+
+ UpdateResult( bool e, bool m, unsigned long long n )
+ : existing(e) , mod(m), num(n ){}
+
+ int oldCode(){
+ if ( ! num )
+ return 0;
+
+ if ( existing ){
+ if ( mod )
+ return 2;
+ return 1;
+ }
+
+ if ( mod )
+ return 3;
+ return 4;
+ }
+ };
+
/* returns true if an existing object was updated, false if no existing object was found.
multi - update multiple objects - mostly useful with things like $set
*/
- bool updateObjects(const char *ns, BSONObj updateobj, BSONObj pattern, bool upsert, stringstream& ss, bool multi = false);
+ UpdateResult updateObjects(const char *ns, BSONObj updateobj, BSONObj pattern, bool upsert, bool multi , stringstream& ss, bool logop );
// If justOne is true, deletedId is set to the id of the deleted object.
int deleteObjects(const char *ns, BSONObj pattern, bool justOne, bool logop = false, bool god=false);
diff --git a/db/repl.cpp b/db/repl.cpp
index 3ba2fb4d7be..0bf3ed201fe 100644
--- a/db/repl.cpp
+++ b/db/repl.cpp
@@ -49,7 +49,6 @@
namespace mongo {
extern boost::recursive_mutex &dbMutex;
- int _updateObjects(const char *ns, BSONObj updateobj, BSONObj pattern, bool upsert, stringstream& ss, bool logOp=false);
void ensureHaveIdIndex(const char *ns);
/* if 1 sync() is running */
@@ -545,8 +544,9 @@ namespace mongo {
stringstream ss;
setClient("local.sources");
- int u = _updateObjects("local.sources", o, pattern, true/*upsert for pair feature*/, ss);
- assert( u == 1 || u == 4 );
+ UpdateResult res = updateObjects("local.sources", o, pattern, true/*upsert for pair feature*/, false,ss,false);
+ assert( ! res.mod );
+ assert( res.num == 1 );
cc().clearns();
if ( replacing ) {
@@ -780,7 +780,7 @@ namespace mongo {
if( !o.getObjectID(_id) ) {
/* No _id. This will be very slow. */
Timer t;
- _updateObjects(ns, o, o, true, ss);
+ updateObjects(ns, o, o, true, false, ss, false );
if( t.millis() >= 2 ) {
RARELY OCCASIONALLY log() << "warning, repl doing slow updates (no _id field) for " << ns << endl;
}
@@ -792,13 +792,13 @@ namespace mongo {
/* erh 10/16/2009 - this is probably not relevant any more since its auto-created, but not worth removing */
RARELY ensureHaveIdIndex(ns); // otherwise updates will be slow
- _updateObjects(ns, o, b.done(), true, ss);
+ updateObjects(ns, o, b.done(), true, false, ss, false );
}
}
}
else if ( *opType == 'u' ) {
RARELY ensureHaveIdIndex(ns); // otherwise updates will be super slow
- _updateObjects(ns, o, op.getObjectField("o2"), op.getBoolField("b"), ss);
+ updateObjects(ns, o, op.getObjectField("o2"), op.getBoolField("b"), false, ss, false );
}
else if ( *opType == 'd' ) {
if ( opType[1] == 0 )
diff --git a/db/update.cpp b/db/update.cpp
index adedd3c2b3e..9e0ded33637 100644
--- a/db/update.cpp
+++ b/db/update.cpp
@@ -116,7 +116,7 @@ namespace mongo {
else if( nint )
*nint += n.numberInt();
else
- *nlong += n.numberLong();\
+ *nlong += n.numberLong();
}
void setElementToOurNumericValue(BSONElement& e) const {
@@ -218,22 +218,22 @@ namespace mongo {
bool applyModsInPlace( const BSONObj &obj ) const;
BSONObj createNewFromMods( const BSONObj &obj );
- void checkUnindexed( const set<string>& idxKeys ) const {
+ bool isIndexed( const set<string>& idxKeys ) const {
for ( vector<Mod>::const_iterator i = _mods.begin(); i != _mods.end(); i++ ) {
// check if there is an index key that is a parent of mod
for( const char *dot = strchr( i->fieldName, '.' ); dot; dot = strchr( dot + 1, '.' ) )
if ( idxKeys.count( string( i->fieldName, dot - i->fieldName ) ) )
- uassert("E12010 can't $inc/$set an indexed field ", false);
+ return true;
string fullName = i->fieldName;
// check if there is an index key equal to mod
if ( idxKeys.count(fullName) )
- uassert("E12011 can't $inc/$set an indexed field", false);
+ 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)[fullName.size()] == '.' ){
- uassert("E12012 can't $inc/$set an indexed field", false);
- }
+ if ( j != idxKeys.end() && j->find( fullName ) == 0 && (*j)[fullName.size()] == '.' )
+ return true;
}
+ return false;
}
unsigned size() const { return _mods.size(); }
@@ -348,19 +348,28 @@ namespace mongo {
for ( vector<Mod>::const_iterator i = _mods.begin(); i != _mods.end(); ++i ) {
const Mod& m = *i;
BSONElement e = obj.getFieldDotted(m.fieldName);
- if ( m.op == Mod::PULL || m.op == Mod::PULL_ALL )
- continue;
+
+ switch ( m.op ){
+ case Mod::PULL:
+ case Mod::PULL_ALL:
+ break;
// [dm] the BSONElementManipulator statements below are for replication (correct?)
- if ( m.op == Mod::INC ) {
+ case Mod::INC:
m.inc(e);
m.setElementToOurNumericValue(e);
- } else {
+ break;
+ case Mod::SET:
if ( e.isNumber() && m.elt.isNumber() ) {
// todo: handle NumberLong:
m.setElementToOurNumericValue(e);
- } else
+ }
+ else {
BSONElementManipulator( e ).replaceTypeAndValue( m.elt );
+ }
+ break;
+ default:
+ uassert( "can't handle mod" , 0 );
}
}
return true;
@@ -553,10 +562,8 @@ namespace mongo {
*/
void ModSet::getMods(const BSONObj &from) {
BSONObjIterator it(from);
- while ( it.moreWithEOO() ) {
+ while ( it.more() ) {
BSONElement e = it.next();
- if ( e.eoo() )
- break;
const char *fn = e.fieldName();
uassert( "Invalid modifier specified" + string( fn ), e.type() == Object );
BSONObj j = e.embeddedObject();
@@ -641,8 +648,11 @@ namespace mongo {
long long nscanned_;
auto_ptr< KeyValJSMatcher > matcher_;
};
+
- int __updateObjects(const char *ns, BSONObj updateobj, BSONObj &pattern, bool upsert, stringstream& ss, bool logop=false) {
+ UpdateResult updateObjects(const char *ns, BSONObj updateobj, BSONObj pattern, bool upsert, bool multi, stringstream& ss, bool logop ) {
+ uassert("multi not coded yet", !multi);
+
int profile = cc().database()->profile;
uassert("cannot update reserved $ collection", strchr(ns, '$') == 0 );
@@ -689,8 +699,7 @@ namespace mongo {
mods.getMods(updateobj);
NamespaceDetailsTransient& ndt = NamespaceDetailsTransient::get(ns);
set<string>& idxKeys = ndt.indexKeys();
- mods.checkUnindexed( idxKeys );
- if ( mods.applyModsInPlace( c->currLoc().obj() ) ) {
+ if ( ! mods.isIndexed( idxKeys ) && mods.applyModsInPlace( c->currLoc().obj() ) ) {
if ( profile )
ss << " fastmod ";
} else {
@@ -705,18 +714,20 @@ namespace mongo {
mods.appendSizeSpecForArrayDepMods( patternBuilder );
pattern = patternBuilder.obj();
}
- logOp("u", ns, updateobj, &pattern );
- return 5;
}
+ logOp("u", ns, updateobj, &pattern );
}
- return 2;
- } else {
+ return UpdateResult( 1 , 1 , 1 );
+ }
+ else {
BSONElementManipulator::lookForTimestamps( updateobj );
checkNoMods( updateobj );
}
theDataFileMgr.update(ns, r, c->currLoc(), updateobj.objdata(), updateobj.objsize(), ss);
- return 1;
+ if ( logop )
+ logOp("u", ns, updateobj, &pattern );
+ return UpdateResult( 1 , 0 , 1 );
}
if ( profile )
@@ -740,7 +751,7 @@ namespace mongo {
ss << " fastmodinsert ";
if ( logop )
logOp( "i", ns, newObj );
- return 3;
+ return UpdateResult( 0 , 1 , 1 );
}
checkNoMods( updateobj );
if ( profile )
@@ -748,27 +759,9 @@ namespace mongo {
theDataFileMgr.insert(ns, updateobj);
if ( logop )
logOp( "i", ns, updateobj );
- return 4;
+ return UpdateResult( 0 , 0 , 1 );
}
- return 0;
+ return UpdateResult( 0 , 0 , 0 );
}
- /* todo:
- _ smart requery find record immediately
- (clean return codes up later...)
- */
- int _updateObjects(const char *ns, BSONObj updateobj, BSONObj pattern, bool upsert, stringstream& ss, bool logop=false) {
- return __updateObjects( ns, updateobj, pattern, upsert, ss, logop );
- }
-
- /* multi means multiple updates. this is not implemented yet, but stubbing out for future work */
- /* todo - clean up these crazy __updateobjects return codes! */
- bool updateObjects(const char *ns, BSONObj updateobj, BSONObj pattern, bool upsert, stringstream& ss, bool multi) {
- uassert("multi not coded yet", !multi);
- int rc = __updateObjects(ns, updateobj, pattern, upsert, ss, true);
- /* todo: why is there a logOp here when __updateObjects also does a bunch of logOps? */
- if ( rc != 5 && rc != 0 && rc != 4 && rc != 3 )
- logOp("u", ns, updateobj, &pattern, &upsert);
- return ( rc == 1 || rc == 2 || rc == 5 );
- }
}