summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/cap.cpp2
-rw-r--r--db/dbcommands.cpp25
-rw-r--r--jstests/capped6.js82
-rw-r--r--mongo.xcodeproj/project.pbxproj2
4 files changed, 111 insertions, 0 deletions
diff --git a/db/cap.cpp b/db/cap.cpp
index ad1cfe3c4ed..d107d95d700 100644
--- a/db/cap.cpp
+++ b/db/cap.cpp
@@ -300,6 +300,8 @@ namespace mongo {
}
}
+ massert( 13415, "emptying the collection is not allowed", nrecords > 1 );
+
if ( !capLooped() ) {
theDataFileMgr.deleteRecord(ns, curr.rec(), curr, true);
compact();
diff --git a/db/dbcommands.cpp b/db/dbcommands.cpp
index 61d6340196f..fe71758ee2a 100644
--- a/db/dbcommands.cpp
+++ b/db/dbcommands.cpp
@@ -1760,6 +1760,31 @@ namespace mongo {
}
} availableQueryOptionsCmd;
+ // just for testing
+ class CapTrunc : public Command {
+ public:
+ CapTrunc() : Command( "captrunc" ){}
+ virtual bool slaveOk() const { return false; }
+ virtual LockType locktype() const { return WRITE; }
+ virtual bool requiresAuth() { return true; }
+ virtual bool run(const string& dbname , BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool){
+ string coll = cmdObj[ "captrunc" ].valuestrsafe();
+ uassert( 13412, "captrunc must specify a collection", !coll.empty() );
+ string ns = dbname + "." + coll;
+ int n = cmdObj.getIntField( "n" );
+ bool inc = cmdObj.getBoolField( "inc" );
+ NamespaceDetails *nsd = nsdetails( ns.c_str() );
+ ReverseCappedCursor c( nsd );
+ massert( 13414, "captrunc invalid collection", c.ok() );
+ for( int i = 0; i < n; ++i ) {
+ massert( 13413, "captrunc invalid n", c.advance() );
+ }
+ DiskLoc end = c.currLoc();
+ nsd->cappedTruncateAfter( ns.c_str(), end, inc );
+ return true;
+ }
+ } capTruncCmd;
+
/**
* this handles
- auth
diff --git a/jstests/capped6.js b/jstests/capped6.js
new file mode 100644
index 00000000000..851bbd19ce3
--- /dev/null
+++ b/jstests/capped6.js
@@ -0,0 +1,82 @@
+Random.setRandomSeed();
+
+db.capped6.drop();
+db._dbCommand( { create: "capped6", capped: true, size: 1000, $nExtents: 11, autoIndexId: false } );
+tzz = db.capped6;
+
+function debug( x ) {
+// print( x );
+}
+
+function checkOrder( i ) {
+ res = tzz.find().sort( { $natural: -1 } );
+ assert( res.hasNext(), "A" );
+ var j = i;
+ while( res.hasNext() ) {
+ try {
+ assert.eq( val[ j-- ].a, res.next().a, "B" );
+ } catch( e ) {
+ debug( "capped6 err " + j );
+ throw e;
+ }
+ }
+ res = tzz.find().sort( { $natural: 1 } );
+ assert( res.hasNext(), "C" );
+ while( res.hasNext() )
+ assert.eq( val[ ++j ].a, res.next().a, "D" );
+ assert.eq( j, i, "E" );
+}
+
+var val = new Array( 500 );
+var c = "";
+for( i = 0; i < 500; ++i, c += "-" ) {
+ val[ i ] = { a: c };
+}
+
+var oldMax = Random.randInt( 500 );
+var max = 0;
+
+function doTest() {
+ for( var i = max; i < oldMax; ++i ) {
+ tzz.save( val[ i ] );
+ }
+ max = oldMax;
+ count = tzz.count();
+
+ var min = 1;
+ if ( Random.rand() > 0.3 ) {
+ min = Random.randInt( count ) + 1;
+ }
+
+ while( count > min ) {
+ var n = Random.randInt( count - min - 1 ); // 0 <= x <= count - min - 1
+ var inc = Random.rand() > 0.5;
+ debug( count + " " + n + " " + inc );
+ assert.commandWorked( db.runCommand( { captrunc:"capped6", n:n, inc:inc } ) );
+ if ( inc ) {
+ n += 1;
+ }
+ count -= n;
+ max -= n;
+ checkOrder( max - 1 );
+ }
+}
+
+for( var i = 0; i < 10; ++i ) {
+ doTest();
+}
+
+// reverse order of values
+var val = new Array( 500 );
+
+var c = "";
+for( i = 499; i >= 0; --i, c += "-" ) {
+ val[ i ] = { a: c };
+}
+db.capped6.drop();
+db._dbCommand( { create: "capped6", capped: true, size: 1000, $nExtents: 11, autoIndexId: false } );
+tzz = db.capped6;
+
+for( var i = 0; i < 10; ++i ) {
+ doTest();
+}
diff --git a/mongo.xcodeproj/project.pbxproj b/mongo.xcodeproj/project.pbxproj
index b5f76a2e6fb..d64006fb718 100644
--- a/mongo.xcodeproj/project.pbxproj
+++ b/mongo.xcodeproj/project.pbxproj
@@ -581,6 +581,7 @@
93E5B88E10D7FF890044F9E4 /* v8_wrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = v8_wrapper.cpp; sourceTree = "<group>"; };
93E5B88F10D7FF890044F9E4 /* v8_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8_wrapper.h; sourceTree = "<group>"; };
93E6E09F11FDFAAA00EDA451 /* cap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cap.cpp; sourceTree = "<group>"; };
+ 93E6E10A11FE2BBC00EDA451 /* capped6.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = capped6.js; sourceTree = "<group>"; };
93E727090F4B5B5B004F9B5D /* shardkey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shardkey.cpp; sourceTree = "<group>"; };
93E7270A0F4B5B5B004F9B5D /* shardkey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shardkey.h; sourceTree = "<group>"; };
93E8A4381173E6480025F7F8 /* or1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = or1.js; sourceTree = "<group>"; };
@@ -830,6 +831,7 @@
934BEB9A10DFFA9600178102 /* jstests */ = {
isa = PBXGroup;
children = (
+ 93E6E10A11FE2BBC00EDA451 /* capped6.js */,
93C5BC9E11E5B7FE00F9671C /* group6.js */,
93C5BC7911E5AE8700F9671C /* in6.js */,
938A74BF11D17ECE005265E1 /* numberlong.js */,