Compare commits

...

25 Commits

Author SHA1 Message Date
Eliot Horowitz
5b29dec970 BUMP 1.4.1 2010-04-14 15:52:44 -04:00
Eliot Horowitz
828178f05a Merge branch 'v1.4' of git@github.com:mongodb/mongo into v1.4 2010-04-13 17:21:16 -04:00
Eliot Horowitz
f8339b000d adaptive sleep for ClientCusror::yield SERVER-975 2010-04-13 17:19:28 -04:00
Aaron Staple
811623e385 reset mem size audit correctly for repl ids 2010-04-09 23:39:14 -07:00
Aaron
4fb7888bfe SERVER-847 flush log message when setting master 2010-04-09 23:39:06 -07:00
Eliot Horowitz
adb8a476bc client fix for bad queries 2010-04-09 14:32:49 -04:00
Aaron
601f3d44fa SERVER-983 split bucket unevenly when inserting at high end 2010-04-08 21:35:58 -04:00
Eliot Horowitz
fc7f36ad70 first cut at radius limiting $near SERVER-813 2010-04-01 15:33:50 -04:00
Mike Dirolf
a57baf1d05 use application/json for _status SERVER-861 2010-04-01 12:00:01 -04:00
Eliot Horowitz
da5872874f getIndexSizeForCollection shouldn't use DBDIrectClient SERVER-860 2010-04-01 10:20:10 -04:00
Eliot Horowitz
7109c020a3 do'nt require boost options in mongoclient SERVER-855 2010-03-31 11:58:09 -04:00
Aaron
3e286b07bb SERVER-841 don't use dummy op when figuring other side's log endpoint 2010-03-29 23:25:17 -07:00
Aaron
1cab1d1c7c SERVER-841 fastsync corner cases 2010-03-29 23:25:04 -07:00
Eliot Horowitz
d979fd7da6 catch empty db names early SERVER-821 2010-03-29 10:41:04 -04:00
Eliot Horowitz
6de759673d make sure tools create a LastError object SERVER-839 2010-03-28 17:15:56 -04:00
Eliot Horowitz
2f3fc62619 wrong method name 2010-03-28 00:34:09 -04:00
Eliot Horowitz
6a05e9026e reset curop in repl thread SERVER-837 2010-03-26 21:39:22 -04:00
Eliot Horowitz
2b2f91fad0 use god scope for webserver auth 2010-03-26 16:33:38 -04:00
Eliot Horowitz
1bab750b19 fix array numberic sort order SERVER-833 2010-03-26 15:31:11 -04:00
Richard Kreuter
b44262e4ef Backport to 1.4 of bdcd668. SERVER-834 2010-03-26 12:14:15 -04:00
Eliot Horowitz
dac3b92e7c post 1.4.0 2010-03-25 12:02:37 -04:00
Eliot Horowitz
514f8bbab6 BUMP 1.4.0 2010-03-25 11:04:10 -04:00
Eliot Horowitz
35885ba8de fix looping with circle queries for geo 2010-03-25 10:34:55 -04:00
Eliot Horowitz
656cd5df27 new version 2010-03-25 01:20:06 -04:00
Eliot Horowitz
41a2421ab9 1.4 branch 2010-03-24 23:15:02 -04:00
35 changed files with 266 additions and 91 deletions

View File

@@ -359,7 +359,7 @@ if GetOption( "extralib" ) is not None:
# ------ SOURCE FILE SETUP -----------
commonFiles = Split( "stdafx.cpp buildinfo.cpp db/common.cpp db/jsobj.cpp db/json.cpp db/lasterror.cpp db/nonce.cpp db/queryutil.cpp db/cmdline.cpp shell/mongo.cpp" )
commonFiles = Split( "stdafx.cpp buildinfo.cpp db/common.cpp db/jsobj.cpp db/json.cpp db/lasterror.cpp db/nonce.cpp db/queryutil.cpp shell/mongo.cpp" )
commonFiles += [ "util/background.cpp" , "util/mmap.cpp" , "util/sock.cpp" , "util/util.cpp" , "util/message.cpp" ,
"util/assert_util.cpp" , "util/httpclient.cpp" , "util/md5main.cpp" , "util/base64.cpp", "util/debug_util.cpp",
"util/thread_pool.cpp" ]
@@ -384,7 +384,7 @@ else:
coreDbFiles = [ "db/commands.cpp" ]
coreServerFiles = [ "util/message_server_port.cpp" , "util/message_server_asio.cpp" ]
serverOnlyFiles = Split( "db/query.cpp db/update.cpp db/introspect.cpp db/btree.cpp db/clientcursor.cpp db/tests.cpp db/repl.cpp db/btreecursor.cpp db/cloner.cpp db/namespace.cpp db/matcher.cpp db/dbeval.cpp db/dbwebserver.cpp db/dbhelpers.cpp db/instance.cpp db/database.cpp db/pdfile.cpp db/cursor.cpp db/security_commands.cpp db/client.cpp db/security.cpp util/miniwebserver.cpp db/storage.cpp db/reccache.cpp db/queryoptimizer.cpp db/extsort.cpp db/mr.cpp s/d_util.cpp" )
serverOnlyFiles = Split( "db/query.cpp db/update.cpp db/introspect.cpp db/btree.cpp db/clientcursor.cpp db/tests.cpp db/repl.cpp db/btreecursor.cpp db/cloner.cpp db/namespace.cpp db/matcher.cpp db/dbeval.cpp db/dbwebserver.cpp db/dbhelpers.cpp db/instance.cpp db/database.cpp db/pdfile.cpp db/cursor.cpp db/security_commands.cpp db/client.cpp db/security.cpp util/miniwebserver.cpp db/storage.cpp db/reccache.cpp db/queryoptimizer.cpp db/extsort.cpp db/mr.cpp s/d_util.cpp db/cmdline.cpp" )
serverOnlyFiles += [ "db/index.cpp" ] + Glob( "db/index_*.cpp" )
serverOnlyFiles += Glob( "db/dbcommands*.cpp" )
@@ -404,7 +404,7 @@ else:
nojni = True
coreShardFiles = []
shardServerFiles = coreShardFiles + Glob( "s/strategy*.cpp" ) + [ "s/commands_admin.cpp" , "s/commands_public.cpp" , "s/request.cpp" , "s/cursors.cpp" , "s/server.cpp" , "s/chunk.cpp" , "s/shardkey.cpp" , "s/config.cpp" , "s/s_only.cpp" ]
shardServerFiles = coreShardFiles + Glob( "s/strategy*.cpp" ) + [ "s/commands_admin.cpp" , "s/commands_public.cpp" , "s/request.cpp" , "s/cursors.cpp" , "s/server.cpp" , "s/chunk.cpp" , "s/shardkey.cpp" , "s/config.cpp" , "s/s_only.cpp" , "db/cmdline.cpp" ]
serverOnlyFiles += coreShardFiles + [ "s/d_logic.cpp" ]
serverOnlyFiles += [ "db/module.cpp" ] + Glob( "db/modules/*.cpp" )

View File

@@ -16,7 +16,7 @@ def checkOk():
print( "excpted version [" + m + "]" )
from subprocess import Popen, PIPE
diff = Popen( [ "git", "diff", "origin/v1.2" ], stdout=PIPE ).communicate()[ 0 ]
diff = Popen( [ "git", "diff", "origin/v1.4" ], stdout=PIPE ).communicate()[ 0 ]
if len(diff) > 0:
print( diff )
raise Exception( "build bot broken?" )

View File

@@ -22,6 +22,8 @@
namespace mongo {
CmdLine cmdLine;
const char * curNs = "in client mode";
bool dbexitCalled = false;

View File

@@ -769,6 +769,8 @@ namespace mongo {
}
if ( !connector->call( toSend, *m, false ) )
return false;
if ( ! m->data )
return false;
dataReceived();
return true;
}

View File

@@ -665,13 +665,18 @@ found:
if ( split_debug )
out() << " " << thisLoc.toString() << ".split" << endl;
int mid = n / 2;
int split = n / 2;
if ( keypos == n ) { // see SERVER-983
split = 0.9 * n;
if ( split > n - 2 )
split = n - 2;
}
DiskLoc rLoc = addBucket(idx);
BtreeBucket *r = rLoc.btreemod();
if ( split_debug )
out() << " mid:" << mid << ' ' << keyNode(mid).key.toString() << " n:" << n << endl;
for ( int i = mid+1; i < n; i++ ) {
out() << " split:" << split << ' ' << keyNode(split).key.toString() << " n:" << n << endl;
for ( int i = split+1; i < n; i++ ) {
KeyNode kn = keyNode(i);
r->pushBack(kn.recordLoc, kn.key, order, kn.prevChildBucket);
}
@@ -684,18 +689,18 @@ found:
rLoc.btree()->fixParentPtrs(rLoc);
{
KeyNode middle = keyNode(mid);
nextChild = middle.prevChildBucket; // middle key gets promoted, its children will be thisLoc (l) and rLoc (r)
KeyNode splitkey = keyNode(split);
nextChild = splitkey.prevChildBucket; // splitkey key gets promoted, its children will be thisLoc (l) and rLoc (r)
if ( split_debug ) {
out() << " middle key:" << middle.key.toString() << endl;
out() << " splitkey key:" << splitkey.key.toString() << endl;
}
// promote middle to a parent node
// promote splitkey to a parent node
if ( parent.isNull() ) {
// make a new parent if we were the root
DiskLoc L = addBucket(idx);
BtreeBucket *p = L.btreemod();
p->pushBack(middle.recordLoc, middle.key, order, thisLoc);
p->pushBack(splitkey.recordLoc, splitkey.key, order, thisLoc);
p->nextChild = rLoc;
p->assertValid( order );
parent = idx.head = L;
@@ -708,22 +713,22 @@ found:
*/
rLoc.btreemod()->parent = parent;
if ( split_debug )
out() << " promoting middle key " << middle.key.toString() << endl;
parent.btree()->_insert(parent, middle.recordLoc, middle.key, order, /*dupsallowed*/true, thisLoc, rLoc, idx);
out() << " promoting splitkey key " << splitkey.key.toString() << endl;
parent.btree()->_insert(parent, splitkey.recordLoc, splitkey.key, order, /*dupsallowed*/true, thisLoc, rLoc, idx);
}
}
truncateTo(mid, order); // note this may trash middle.key. thus we had to promote it before finishing up here.
truncateTo(split, order); // note this may trash splitkey.key. thus we had to promote it before finishing up here.
// add our new key, there is room now
{
if ( keypos <= mid ) {
if ( keypos <= split ) {
if ( split_debug )
out() << " keypos<mid, insertHere() the new key" << endl;
out() << " keypos<split, insertHere() the new key" << endl;
insertHere(thisLoc, keypos, recordLoc, key, order, lchild, rchild, idx);
} else {
int kp = keypos-mid-1;
int kp = keypos-split-1;
assert(kp>=0);
rLoc.btree()->insertHere(rLoc, kp, recordLoc, key, order, lchild, rchild, idx);
}

View File

@@ -245,4 +245,21 @@ namespace mongo {
return b.obj();
}
int Client::recommendedYieldMicros(){
int num = 0;
{
scoped_lock bl(clientsMutex);
num = clients.size();
}
if ( --num <= 0 ) // -- is for myself
return 0;
if ( num > 50 )
num = 50;
num *= 100;
return num;
}
}

View File

@@ -45,6 +45,8 @@ namespace mongo {
static mongo::mutex clientsMutex;
static set<Client*> clients; // always be in clientsMutex when manipulating this
static int recommendedYieldMicros();
class GodScope {
bool _prev;
public:

View File

@@ -232,6 +232,7 @@ namespace mongo {
{
dbtempreleasecond unlock;
sleepmicros( Client::recommendedYieldMicros() );
}
if ( ClientCursor::find( id , false ) == 0 ){

View File

@@ -23,7 +23,6 @@
namespace po = boost::program_options;
namespace mongo {
CmdLine cmdLine;
void setupSignals();
BSONArray argvArray;

View File

@@ -108,15 +108,19 @@ namespace mongo {
Top::global.record( _ns , _op , _lockType , now - _checkpoint , _command );
_checkpoint = now;
}
void reset( const sockaddr_in & remote, int op ) {
void reset(){
_reset();
_start = _checkpoint = 0;
_active = true;
_opNum = _nextOpNum++;
_ns[0] = '?'; // just in case not set later
_debug.reset();
resetQuery();
resetQuery();
}
void reset( const sockaddr_in & remote, int op ) {
reset();
_remote = remote;
_op = op;
}

View File

@@ -45,6 +45,8 @@
namespace mongo {
CmdLine cmdLine;
bool useJNI = true;
/* only off if --nocursors which is for debugging. */

View File

@@ -141,8 +141,11 @@ namespace mongo {
string _todb( const string& ns ) const {
size_t i = ns.find( '.' );
if ( i == string::npos )
if ( i == string::npos ){
uassert( 13074 , "db name can't be empty" , ns.size() );
return ns;
}
uassert( 13075 , "db name can't be empty" , i > 0 );
return ns.substr( 0 , i );
}

View File

@@ -1020,19 +1020,26 @@ namespace mongo {
namespace {
long long getIndexSizeForCollection(string db, string ns, BSONObjBuilder* details=NULL, int scale = 1 ){
DBDirectClient client;
auto_ptr<DBClientCursor> indexes =
client.query(db + ".system.indexes", QUERY( "ns" << ns));
dbMutex.assertAtLeastReadLocked();
long long totalSize = 0;
while (indexes->more()){
BSONObj index = indexes->nextSafe();
NamespaceDetails * nsd = nsdetails( (ns + ".$" + index["name"].valuestrsafe()).c_str() );
if (!nsd)
continue; // nothing to do here
totalSize += nsd->datasize;
if (details)
details->appendNumber(index["name"].valuestrsafe(), nsd->datasize / scale );
NamespaceDetails * nsd = nsdetails( ns.c_str() );
if ( ! nsd )
return 0;
long long totalSize = 0;
NamespaceDetails::IndexIterator ii = nsd->ii();
while ( ii.more() ){
IndexDetails& d = ii.next();
string collNS = d.indexNamespace();
NamespaceDetails * mine = nsdetails( collNS.c_str() );
if ( ! mine ){
log() << "error: have index [" << collNS << "] but no NamespaceDetails" << endl;
continue;
}
totalSize += mine->datasize;
if ( details )
details->appendNumber( d.indexName() , mine->datasize / scale );
}
return totalSize;
}

View File

@@ -241,6 +241,8 @@ namespace mongo {
if ( from.localhost() )
return true;
Client::GodScope gs;
if ( db.findOne( "admin.system.users" , BSONObj() , 0 , QueryOption_SlaveOk ).isEmpty() )
return true;
@@ -315,6 +317,7 @@ namespace mongo {
responseMsg = "not allowed\n";
return;
}
headers.push_back( "Content-Type: application/json" );
generateServerStatus( url , responseMsg );
responseCode = 200;
return;
@@ -519,7 +522,7 @@ namespace mongo {
BSONObj query = queryBuilder.obj();
auto_ptr<DBClientCursor> cursor = db.query( ns.c_str() , query, num , skip );
uassert( 13085 , "query failed for dbwebserver" , cursor.get() );
if ( one ) {
if ( cursor->more() ) {
BSONObj obj = cursor->next();

View File

@@ -893,14 +893,14 @@ namespace mongo {
public:
typedef multiset<GeoPoint> Holder;
GeoHopper( const Geo2dType * g , unsigned max , const GeoHash& n , const BSONObj& filter = BSONObj() )
: GeoAccumulator( g , filter ) , _max( max ) , _near( n ) {
GeoHopper( const Geo2dType * g , unsigned max , const GeoHash& n , const BSONObj& filter = BSONObj() , double maxDistance = numeric_limits<double>::max() )
: GeoAccumulator( g , filter ) , _max( max ) , _near( n ), _maxDistance( maxDistance ) {
}
virtual bool checkDistance( const GeoHash& h , double& d ){
d = _g->distance( _near , h );
bool good = _points.size() < _max || d < farthest();
bool good = d < _maxDistance && ( _points.size() < _max || d < farthest() );
GEODEBUG( "\t\t\t\t\t\t\t checkDistance " << _near << "\t" << h << "\t" << d
<< " ok: " << good << " farthest: " << farthest() );
return good;
@@ -926,6 +926,7 @@ namespace mongo {
unsigned _max;
GeoHash _near;
Holder _points;
double _maxDistance;
};
@@ -999,10 +1000,10 @@ namespace mongo {
class GeoSearch {
public:
GeoSearch( const Geo2dType * g , const GeoHash& n , int numWanted=100 , BSONObj filter=BSONObj() )
GeoSearch( const Geo2dType * g , const GeoHash& n , int numWanted=100 , BSONObj filter=BSONObj() , double maxDistance = numeric_limits<double>::max() )
: _spec( g ) , _n( n ) , _start( n ) ,
_numWanted( numWanted ) , _filter( filter ) ,
_hopper( new GeoHopper( g , numWanted , n , filter ) )
_hopper( new GeoHopper( g , numWanted , n , filter , maxDistance ) )
{
assert( g->getDetails() );
_nscanned = 0;
@@ -1201,11 +1202,13 @@ namespace mongo {
if ( ! _cur.isEmpty() || _stack.size() )
return true;
if ( ! moreToDo() )
return false;
while ( moreToDo() ){
fillStack();
if ( ! _cur.isEmpty() )
return true;
}
fillStack();
return ! _cur.isEmpty();
return false;
}
virtual bool advance(){
@@ -1296,12 +1299,13 @@ namespace mongo {
while ( _max.hasPrefix( _prefix ) && _max.advance( 1 , _found , this ) );
if ( ! _prefix.constrains() ){
// we've exhausted the btree
GEODEBUG( "\t exhausted the btree" );
_state = DONE;
return;
}
if ( _g->distance( _prefix , _start ) > _maxDistance ){
GEODEBUG( "\tpast circle bounds" );
GeoHash tr = _prefix;
tr.move( 1 , 1 );
if ( _g->distance( tr , _start ) > _maxDistance )
@@ -1322,6 +1326,7 @@ namespace mongo {
virtual bool checkDistance( const GeoHash& h , double& d ){
d = _g->distance( _start , h );
GEODEBUG( "\t " << h << "\t" << d );
return d <= ( _maxDistance + .01 );
}
@@ -1474,7 +1479,16 @@ namespace mongo {
switch ( e.embeddedObject().firstElement().getGtLtOp() ){
case BSONObj::opNEAR: {
e = e.embeddedObject().firstElement();
shared_ptr<GeoSearch> s( new GeoSearch( this , _tohash(e) , numWanted , query ) );
double maxDistance = numeric_limits<double>::max();
if ( e.isABSONObj() && e.embeddedObject().nFields() > 2 ){
BSONObjIterator i(e.embeddedObject());
i.next();
i.next();
BSONElement e = i.next();
if ( e.isNumber() )
maxDistance = e.numberDouble();
}
shared_ptr<GeoSearch> s( new GeoSearch( this , _tohash(e) , numWanted , query , maxDistance ) );
s->exec();
auto_ptr<Cursor> c;
c.reset( new GeoSearchCursor( s ) );

View File

@@ -72,8 +72,14 @@ namespace mongo {
LastError * LastErrorHolder::_get( bool create ){
int id = _id.get();
if ( id == 0 )
return _tl.get();
if ( id == 0 ){
LastError * le = _tl.get();
if ( ! le && create ){
le = new LastError();
_tl.reset( le );
}
return le;
}
scoped_lock lock(_idsmutex);
map<int,Status>::iterator i = _ids.find( id );

View File

@@ -1141,7 +1141,7 @@ namespace mongo {
break;
}
}
progress.done();
progress.finished();
return n;
}
@@ -1192,7 +1192,7 @@ namespace mongo {
// throws DBException
static void buildAnIndex(string ns, NamespaceDetails *d, IndexDetails& idx, int idxNo, bool background) {
log() << "building new index on " << idx.keyPattern() << " for " << ns << endl;
log() << "building new index on " << idx.keyPattern() << " for " << ns << ( background ? " background" : "" ) << endl;
Timer t;
unsigned long long n;

View File

@@ -102,7 +102,7 @@ namespace mongo {
return;
info = _comment;
if ( n != state && !cmdLine.quiet )
log() << "pair: setting master=" << n << " was " << state << '\n';
log() << "pair: setting master=" << n << " was " << state << endl;
state = n;
}
@@ -732,7 +732,7 @@ namespace mongo {
( replPair && replSettings.fastsync ) ) {
DBDirectClient c;
if ( c.exists( "local.oplog.$main" ) ) {
BSONObj op = c.findOne( "local.oplog.$main", Query().sort( BSON( "$natural" << -1 ) ) );
BSONObj op = c.findOne( "local.oplog.$main", QUERY( "op" << NE << "n" ).sort( BSON( "$natural" << -1 ) ) );
if ( !op.isEmpty() ) {
tmp.syncedTo = op[ "ts" ].date();
tmp._lastSavedLocalTs = op[ "ts" ].date();
@@ -938,6 +938,7 @@ namespace mongo {
}
Client::Context ctx( ns );
ctx.getClient()->curop()->reset();
bool empty = ctx.db()->isEmpty();
bool incompleteClone = incompleteCloneDbs.count( clientName ) != 0;
@@ -1606,6 +1607,7 @@ namespace mongo {
ReplInfo r("replMain load sources");
dblock lk;
ReplSource::loadAll(sources);
replSettings.fastsync = false; // only need this param for initial reset
}
if ( sources.empty() ) {
@@ -1860,6 +1862,9 @@ namespace mongo {
createOplog();
boost::thread t(replMasterThread);
}
while( replSettings.fastsync ) // don't allow writes until we've set up from log
sleepmillis( 50 );
}
/* called from main at server startup */

View File

@@ -205,7 +205,10 @@ namespace mongo {
public:
MemIds() : size_() {}
friend class IdTracker;
void reset() { imp_.clear(); }
void reset() {
imp_.clear();
size_ = 0;
}
bool get( const char *ns, const BSONObj &id ) { return imp_[ ns ].count( id ); }
void set( const char *ns, const BSONObj &id, bool val ) {
if ( val ) {

View File

@@ -24,11 +24,11 @@
#include "repl.h"
#include "update.h"
//#define DEBUGUPDATE(x) cout << x << endl;
#define DEBUGUPDATE(x)
namespace mongo {
//#define DEBUGUPDATE(x) cout << x << endl;
#define DEBUGUPDATE(x)
const char* Mod::modNames[] = { "$inc", "$set", "$push", "$pushAll", "$pull", "$pullAll" , "$pop", "$unset" ,
"$bitand" , "$bitor" , "$bit" , "$addToSet" };
unsigned Mod::modNamesNum = sizeof(Mod::modNames)/sizeof(char*);
@@ -310,11 +310,12 @@ namespace mongo {
// Perform this check first, so that we don't leave a partially modified object on uassert.
for ( ModHolder::const_iterator i = _mods.begin(); i != _mods.end(); ++i ) {
DEBUGUPDATE( "\t\t prepare : " << i->first );
ModState& ms = mss->_mods[i->first];
const Mod& m = i->second;
BSONElement e = obj.getFieldDotted(m.fieldName);
ms.m = &m;
ms.old = e;
@@ -406,6 +407,7 @@ namespace mongo {
mss->amIInPlacePossible( false );
}
}
return auto_ptr<ModSetState>( mss );
}
@@ -477,6 +479,7 @@ namespace mongo {
template< class Builder >
void ModSetState::createNewFromMods( const string& root , Builder& b , const BSONObj &obj ){
DEBUGUPDATE( "\t\t createNewFromMods root: " << root );
BSONObjIteratorSorted es( obj );
BSONElement e = es.next();
@@ -488,6 +491,8 @@ namespace mongo {
while ( e.type() && m != mend ){
string field = root + e.fieldName();
FieldCompareResult cmp = compareDottedFieldNames( m->second.m->fieldName , field );
DEBUGUPDATE( "\t\t\t" << field << "\t" << m->second.m->fieldName << "\t" << cmp );
switch ( cmp ){

View File

@@ -306,11 +306,14 @@ namespace BasicTests {
ASSERT_EQUALS( 1, lexNumCmp( "f12g", "f12f" ) );
ASSERT_EQUALS( 1, lexNumCmp( "aa{", "aab" ) );
ASSERT_EQUALS( 1, lexNumCmp( "aa{", "aa1" ) );
ASSERT_EQUALS( 1, lexNumCmp( "a1{", "a11" ) );
ASSERT_EQUALS( -1, lexNumCmp( "a1{", "a11" ) );
ASSERT_EQUALS( 1, lexNumCmp( "a1{a", "a1{" ) );
ASSERT_EQUALS( -1, lexNumCmp( "a1{", "a1{a" ) );
ASSERT_EQUALS( 1, lexNumCmp("21", "11") );
ASSERT_EQUALS( -1, lexNumCmp("11", "21") );
ASSERT_EQUALS( -1 , lexNumCmp( "a.0" , "a.1" ) );
ASSERT_EQUALS( -1 , lexNumCmp( "a.0.b" , "a.1" ) );
}
};

View File

@@ -72,6 +72,9 @@ namespace BtreeTests {
bt()->assertValid( order(), true );
ASSERT_EQUALS( nKeys, bt()->fullValidate( dl(), order() ) );
}
void dump() {
bt()->dumpTree( dl(), order() );
}
void insert( BSONObj &key ) {
bt()->bt_insert( dl(), recordLoc(), key, order(), true, id(), true );
}
@@ -206,10 +209,12 @@ namespace BtreeTests {
class MissingLocateMultiBucket : public Base {
public:
void run() {
for ( int i = 0; i < 10; ++i ) {
BSONObj k = key( 'b' + 2 * i );
insert( k );
for ( int i = 0; i < 8; ++i ) {
insert( i );
}
insert( 9 );
insert( 8 );
// dump();
BSONObj straddle = key( 'i' );
locate( straddle, 0, false, dl(), 1 );
straddle = key( 'k' );
@@ -219,8 +224,34 @@ namespace BtreeTests {
BSONObj key( char c ) {
return simpleKey( c, 800 );
}
void insert( int i ) {
BSONObj k = key( 'b' + 2 * i );
Base::insert( k );
}
};
class SERVER983 : public Base {
public:
void run() {
for ( int i = 0; i < 10; ++i ) {
insert( i );
}
// dump();
BSONObj straddle = key( 'o' );
locate( straddle, 0, false, dl(), 1 );
straddle = key( 'q' );
locate( straddle, 0, false, dl(), -1 );
}
private:
BSONObj key( char c ) {
return simpleKey( c, 800 );
}
void insert( int i ) {
BSONObj k = key( 'b' + 2 * i );
Base::insert( k );
}
};
class All : public Suite {
public:
All() : Suite( "btree" ){
@@ -233,6 +264,7 @@ namespace BtreeTests {
add< SplitLeftHeavyBucket >();
add< MissingLocate >();
add< MissingLocateMultiBucket >();
add< SERVER983 >();
}
} myall;
}

View File

@@ -34,6 +34,8 @@ namespace po = boost::program_options;
namespace mongo {
CmdLine cmdLine;
namespace regression {
map<string,Suite*> * mongo::regression::Suite::_suites = 0;

View File

@@ -1053,7 +1053,8 @@ namespace ReplTests {
check();
ASSERT( !s_.inMem() );
s_.reset();
s_.reset( 4 * sizeof( BSONObj ) - 1 );
s_.mayUpgradeStorage();
ASSERT( s_.inMem() );
}
private:

13
debian/changelog vendored
View File

@@ -1,3 +1,16 @@
mongodb (1.4.1) unstable; urgency=low
* bug fixes
-- Richard Kreuter <richard@10gen.com> Wed, 14 Apr 2010 16:56:28 -0500
mongodb (1.4.0) unstable; urgency=low
* stable release
-- Richard Kreuter <richard@10gen.com> Wed, 22 Mar 2010 16:56:28 -0500
mongodb (1.3.5) unstable; urgency=low
* bug fixes

View File

@@ -11,5 +11,5 @@ stop on runlevel [06]
script
ENABLE_MONGODB="yes"
if [ -f /etc/default/mongodb ]; then . /etc/default/mongodb; fi
if [ "x$ENABLE_MONGODB" = "xyes" ]; then start-stop-daemon --start --quiet --chuid mongodb --exec /usr/bin/mongod -- --config /etc/mongodb.conf; fi
if [ "x$ENABLE_MONGODB" = "xyes" ]; then exec start-stop-daemon --start --quiet --chuid mongodb --exec /usr/bin/mongod -- --config /etc/mongodb.conf; fi
end script

View File

@@ -3,7 +3,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = MongoDB
PROJECT_NUMBER = 1.3.5
PROJECT_NUMBER = 1.4.1
OUTPUT_DIRECTORY = docs
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English

View File

@@ -41,3 +41,8 @@ assert.close( fast.stats.avgDistance , a( t.find( { loc : { $near : [ 50 , 50 ]
printjson( t.find( { loc : { $near : [ 50 , 50 ] } } ).explain() )
assert.lt( 3 , a( t.find( { loc : { $near : [ 50 , 50 ] } } ).limit(50) ) , "C1" )
assert.gt( 3 , a( t.find( { loc : { $near : [ 50 , 50 , 3 ] } } ).limit(50) ) , "C2" )

View File

@@ -2,7 +2,7 @@
ports = allocatePorts( 3 );
var baseName = "repl_snapshot2";
var baseName = "repl_snapshot3";
var basePath = "/data/db/" + baseName;
a = new MongodRunner( ports[ 0 ], basePath + "-arbiter" );

20
jstests/updated.js Normal file
View File

@@ -0,0 +1,20 @@
t = db.updated;
t.drop()
o = { _id : Math.random() ,
items:[null,null,null,null]
};
t.insert( o );
assert.eq( o , t.findOne() , "A1" );
o.items[0] = {amount:9000,itemId:1};
t.update({},{$set:{"items.0":o.items[0]}});
assert.eq( o , t.findOne() , "A2" );
o.items[0].amount += 1000;
o.items[1] = {amount:1,itemId:2};
t.update({},{$inc:{"items.0.amount":1000},$set:{"items.1":o.items[1]}});
assert.eq( o , t.findOne() , "A3" );

View File

@@ -1,5 +1,5 @@
Name: mongo
Version: 1.3.5
Version: 1.4.1
Release: mongodb_1%{?dist}
Summary: mongo client shell and tools
License: AGPL 3.0

View File

@@ -28,7 +28,8 @@
#include "chunk.h"
namespace mongo {
CmdLine cmdLine;
Database *database = 0;
string mongosCommand;
string ourHostname;

View File

@@ -32,6 +32,6 @@
namespace mongo {
const char versionString[] = "1.3.6-pre-";
const char versionString[] = "1.4.1";
} // namespace mongo

View File

@@ -32,6 +32,8 @@ namespace po = boost::program_options;
namespace mongo {
CmdLine cmdLine;
Tool::Tool( string name , bool localDBAllowed , string defaultDB , string defaultCollection ) :
_name( name ) , _db( defaultDB ) , _coll( defaultCollection ) , _conn(0), _paired(false) {
@@ -157,6 +159,7 @@ namespace mongo {
if ( _params.count( "directoryperdb" ) ) {
directoryperdb = true;
}
assert( lastError.get( true ) );
Client::initThread("tools");
_conn = new DBDirectClient();
_host = "DIRECT";

View File

@@ -195,6 +195,8 @@ namespace mongo {
boost::thread::sleep(xt);
}
inline void sleepmicros(int s) {
if ( s <= 0 )
return;
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
xt.sec += ( s / 1000000 );
@@ -215,6 +217,8 @@ namespace mongo {
}
}
inline void sleepmicros(int s) {
if ( s <= 0 )
return;
struct timespec t;
t.tv_sec = (int)(s / 1000000);
t.tv_nsec = s % 1000000;
@@ -650,43 +654,54 @@ namespace mongo {
// for convenience, '{' is greater than anything and stops number parsing
inline int lexNumCmp( const char *s1, const char *s2 ) {
int nret = 0;
while( *s1 && *s2 ) {
bool p1 = ( *s1 == '{' );
bool p2 = ( *s2 == '{' );
if ( p1 && !p2 )
return 1;
if ( p2 && !p1 )
return -1;
bool n1 = isNumber( *s1 );
bool n2 = isNumber( *s2 );
if ( n1 && n2 ) {
if ( nret == 0 ) {
nret = *s1 > *s2 ? 1 : ( *s1 == *s2 ? 0 : -1 );
}
} else if ( n1 ) {
return 1;
} else if ( n2 ) {
return -1;
} else {
if ( nret ) {
return nret;
}
if ( *s1 > *s2 ) {
char * e1;
char * e2;
long l1 = strtol( s1 , &e1 , 10 );
long l2 = strtol( s2 , &e2 , 10 );
if ( l1 > l2 )
return 1;
} else if ( *s2 > *s1 ) {
else if ( l1 < l2 )
return -1;
}
nret = 0;
}
++s1; ++s2;
s1 = e1;
s2 = e2;
continue;
}
if ( n1 )
return 1;
if ( n2 )
return -1;
if ( *s1 > *s2 )
return 1;
if ( *s2 > *s1 )
return -1;
s1++; s2++;
}
if ( *s1 ) {
if ( *s1 )
return 1;
} else if ( *s2 ) {
if ( *s2 )
return -1;
}
return nret;
return 0;
}
} // namespace mongo