Permalink
Browse files

SERVER-3803 check proper n sentinel value for deallocated bucket in v…

…0 index
  • Loading branch information...
astaple committed Mar 1, 2012
1 parent dd4909f commit b974a8e8229440c1cb1cf06061f1cc4df0b3c9c4
Showing with 30 additions and 2 deletions.
  1. +23 −0 jstests/removea.js
  2. +2 −1 src/mongo/db/btree.cpp
  3. +4 −0 src/mongo/db/btree.h
  4. +1 −1 src/mongo/db/btreecursor.cpp
View
@@ -0,0 +1,23 @@
+// Test removal of a substantial proportion of inserted documents. SERVER-3803
+// A complete test will only be performed against a DEBUG build.
+
+t = db.jstests_removea;
+
+Random.setRandomSeed();
+
+for( v = 0; v < 2; ++v ) { // Try each index version.
+ t.drop();
+ t.ensureIndex( { a:1 }, { v:v } );
+ for( i = 0; i < 10000; ++i ) {
+ t.save( { a:i } );
+ }
+
+ toDrop = [];
+ for( i = 0; i < 10000; ++i ) {
+ toDrop.push( Random.randInt( 10000 ) ); // Dups in the query will be ignored.
+ }
+ // Remove many of the documents; $atomic prevents use of a ClientCursor, which would invoke a
+ // different bucket deallocation procedure than the one to be tested (see SERVER-4575).
+ t.remove( { a:{ $in:toDrop }, $atomic:true } );
+ assert( !db.getLastError() );
+}
View
@@ -838,8 +838,9 @@ namespace mongo {
// it (meaning it is ineligible for reuse).
memset(this, 0, Size());
#else
+ // Mark the bucket as deallocated, see SERVER-4575.
+ this->n = this->INVALID_N_SENTINEL;
// defensive:
- this->n = -1;
this->parent.Null();
string ns = id.indexNamespace();
theDataFileMgr._deleteRecord(nsdetails(ns.c_str()), ns.c_str(), thisLoc.rec(), thisLoc);
View
@@ -180,6 +180,8 @@ namespace mongo {
// largest key size we allow. note we very much need to support bigger keys (somehow) in the future.
static const int KeyMax = OldBucketSize / 10;
+ // A sentinel value sometimes used to identify a deallocated bucket.
+ static const int INVALID_N_SENTINEL = -1;
};
// a a a ofs ofs ofs ofs
@@ -262,6 +264,8 @@ namespace mongo {
enum { BucketSize = 8192-16 }; // leave room for Record header
// largest key size we allow. note we very much need to support bigger keys (somehow) in the future.
static const int KeyMax = 1024;
+ // A sentinel value sometimes used to identify a deallocated bucket.
+ static const unsigned short INVALID_N_SENTINEL = 0xffff;
protected:
/** Parent bucket of this bucket, which isNull() for the root bucket. */
Loc parent;
@@ -52,7 +52,7 @@ namespace mongo {
assert( !bucket.isNull() );
const BtreeBucket<V> *b = bucket.btree<V>();
int n = b->getN();
- if( n == 0xffff ) {
+ if( n == b->INVALID_N_SENTINEL ) {
throw UserException(15850, "keyAt bucket deleted");
}
dassert( n >= 0 && n < 10000 );

0 comments on commit b974a8e

Please sign in to comment.