diff options
-rw-r--r-- | src/mongo/db/catalog/database.cpp | 23 | ||||
-rw-r--r-- | src/mongo/db/storage/extent.cpp | 51 | ||||
-rw-r--r-- | src/mongo/db/storage/extent.h | 14 | ||||
-rw-r--r-- | src/mongo/db/storage/extent_manager.cpp | 53 | ||||
-rw-r--r-- | src/mongo/db/storage/extent_manager.h | 23 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp | 39 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h | 5 | ||||
-rw-r--r-- | src/mongo/db/structure/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_simple.cpp | 8 | ||||
-rw-r--r-- | src/mongo/dbtests/pdfiletests.cpp | 27 |
10 files changed, 115 insertions, 129 deletions
diff --git a/src/mongo/db/catalog/database.cpp b/src/mongo/db/catalog/database.cpp index 25271e766db..cc958b7e06e 100644 --- a/src/mongo/db/catalog/database.cpp +++ b/src/mongo/db/catalog/database.cpp @@ -80,8 +80,6 @@ namespace mongo { return Status( ErrorCodes::BadValue, "size has to be >= 0" ); cappedSize += 0xff; cappedSize &= 0xffffffffffffff00LL; - if ( cappedSize < Extent::minSize() ) - cappedSize = Extent::minSize(); } else if ( fieldName == "max" ) { if ( !e.isNumber() ) @@ -673,11 +671,11 @@ namespace mongo { } namespace { - int _massageExtentSize( long long size ) { - if ( size < Extent::minSize() ) - return Extent::minSize(); - if ( size > Extent::maxSize() ) - return Extent::maxSize(); + int _massageExtentSize( const ExtentManager* em, long long size ) { + if ( size < em->minSize() ) + return em->minSize(); + if ( size > em->maxSize() ) + return em->maxSize(); return static_cast<int>( size ); } } @@ -732,7 +730,8 @@ namespace mongo { if ( allocateDefaultSpace ) { if ( options.initialNumExtents > 0 ) { - int size = _massageExtentSize( options.cappedSize ); + int size = _massageExtentSize( _extentManager.get(), + options.cappedSize ); for ( int i = 0; i < options.initialNumExtents; i++ ) { collection->increaseStorageSize( txn, size, false ); } @@ -740,20 +739,22 @@ namespace mongo { else if ( !options.initialExtentSizes.empty() ) { for ( size_t i = 0; i < options.initialExtentSizes.size(); i++ ) { int size = options.initialExtentSizes[i]; - size = _massageExtentSize( size ); + size = _massageExtentSize( _extentManager.get(), + size ); collection->increaseStorageSize( txn, size, false ); } } else if ( options.capped ) { // normal while ( collection->storageSize() < options.cappedSize ) { - int sz = _massageExtentSize( options.cappedSize - collection->storageSize() ); + int sz = _massageExtentSize( _extentManager.get(), + options.cappedSize - collection->storageSize() ); sz &= 0xffffff00; collection->increaseStorageSize( txn, sz, true ); } } else { - collection->increaseStorageSize( txn, Extent::initialSize( 128 ), false ); + collection->increaseStorageSize( txn, _extentManager->initialSize( 128 ), false ); } } diff --git a/src/mongo/db/storage/extent.cpp b/src/mongo/db/storage/extent.cpp index aa442f869d1..df8f409f855 100644 --- a/src/mongo/db/storage/extent.cpp +++ b/src/mongo/db/storage/extent.cpp @@ -30,7 +30,6 @@ #include "mongo/db/storage/extent.h" -#include "mongo/db/storage/data_file.h" #include "mongo/db/storage/extent_manager.h" #include "mongo/util/mongoutils/str.h" @@ -38,46 +37,6 @@ namespace mongo { BOOST_STATIC_ASSERT( sizeof(Extent)-4 == 48+128 ); - int Extent::initialSize(int len) { - verify( len <= maxSize() ); - - long long sz = len * 16; - if ( len < 1000 ) - sz = len * 64; - - if ( sz >= maxSize() ) - return maxSize(); - - if ( sz <= minSize() ) - return minSize(); - - int z = ExtentManager::quantizeExtentSize( sz ); - verify( z >= len ); - return z; - } - - int Extent::followupSize(int len, int lastExtentLen) { - verify( len < Extent::maxSize() ); - int x = initialSize(len); - // changed from 1.20 to 1.35 in v2.1.x to get to larger extent size faster - int y = (int) (lastExtentLen < 4000000 ? lastExtentLen * 4.0 : lastExtentLen * 1.35); - int sz = y > x ? y : x; - - if ( sz < lastExtentLen ) { - // this means there was an int overflow - // so we should turn it into maxSize - return Extent::maxSize(); - } - else if ( sz > Extent::maxSize() ) { - return Extent::maxSize(); - } - - sz = ExtentManager::quantizeExtentSize( sz ); - verify( sz >= len ); - - return sz; - } - BSONObj Extent::dump() const { return BSON( "loc" << myLoc.toString() << "xnext" << xnext.toString() @@ -136,12 +95,13 @@ namespace mongo { } extentOk = false; } - if (length < minSize()) { + static const int minSize = 0x1000; + if (length < minSize) { if (errors) { StringBuilder sb; sb << "length of extent " << diskLoc.toString() << " is " << length - << ", which is less than minimum length of " << minSize(); + << ", which is less than minimum length of " << minSize; errors->push_back( sb.str() ); } extentOk = false; @@ -149,9 +109,4 @@ namespace mongo { return extentOk; } - int Extent::maxSize() { - return DataFile::maxSize() - DataFileHeader::HeaderSize - 16; - } - - } diff --git a/src/mongo/db/storage/extent.h b/src/mongo/db/storage/extent.h index 00ce898aa02..175180f2171 100644 --- a/src/mongo/db/storage/extent.h +++ b/src/mongo/db/storage/extent.h @@ -76,20 +76,6 @@ namespace mongo { void assertOk() const { verify(isOk()); } static int HeaderSize() { return sizeof(Extent)-4; } - - static int maxSize(); - static int minSize() { return 0x1000; } - /** - * @param len lengt of record we need - * @param lastRecord size of last extent which is a factor in next extent size - */ - static int followupSize(int len, int lastExtentLen); - - /** get a suggested size for the first extent in a namespace - * @param len length of record we need to insert - */ - static int initialSize(int len); - }; #pragma pack() diff --git a/src/mongo/db/storage/extent_manager.cpp b/src/mongo/db/storage/extent_manager.cpp index 96d3d4212cc..a9685f7859f 100644 --- a/src/mongo/db/storage/extent_manager.cpp +++ b/src/mongo/db/storage/extent_manager.cpp @@ -34,27 +34,66 @@ namespace mongo { - int ExtentManager::quantizeExtentSize( int size ) { + int ExtentManager::quantizeExtentSize( int size ) const { - if ( size == Extent::maxSize() ) { + if ( size == maxSize() ) { // no point doing quantizing for the entire file return size; } - verify( size <= Extent::maxSize() ); + invariant( size <= maxSize() ); // make sizes align with VM page size int newSize = (size + 0xfff) & 0xfffff000; - if ( newSize > Extent::maxSize() ) { - return Extent::maxSize(); + if ( newSize > maxSize() ) { + return maxSize(); } - if ( newSize < Extent::minSize() ) { - return Extent::minSize(); + if ( newSize < minSize() ) { + return minSize(); } return newSize; } + int ExtentManager::followupSize( int len, int lastExtentLen ) const { + invariant( len < maxSize() ); + int x = initialSize(len); + // changed from 1.20 to 1.35 in v2.1.x to get to larger extent size faster + int y = (int) (lastExtentLen < 4000000 ? lastExtentLen * 4.0 : lastExtentLen * 1.35); + int sz = y > x ? y : x; + + if ( sz < lastExtentLen ) { + // this means there was an int overflow + // so we should turn it into maxSize + return maxSize(); + } + else if ( sz > maxSize() ) { + return maxSize(); + } + + sz = quantizeExtentSize( sz ); + verify( sz >= len ); + + return sz; + } + + int ExtentManager::initialSize( int len ) const { + invariant( len <= maxSize() ); + + long long sz = len * 16; + if ( len < 1000 ) + sz = len * 64; + + if ( sz >= maxSize() ) + return maxSize(); + + if ( sz <= minSize() ) + return minSize(); + + int z = ExtentManager::quantizeExtentSize( sz ); + verify( z >= len ); + return z; + } } diff --git a/src/mongo/db/storage/extent_manager.h b/src/mongo/db/storage/extent_manager.h index b00a742309b..8d580d04ef7 100644 --- a/src/mongo/db/storage/extent_manager.h +++ b/src/mongo/db/storage/extent_manager.h @@ -128,9 +128,30 @@ namespace mongo { bool preallocateOnly = false ); /** + * @return maximum size of an Extent + */ + virtual int maxSize() const = 0; + + /** + * @return minimum size of an Extent + */ + virtual int minSize() const { return 0x1000; } + + /** + * @param len lengt of record we need + * @param lastRecord size of last extent which is a factor in next extent size + */ + virtual int followupSize( int len, int lastExtentLen ) const; + + /** get a suggested size for the first extent in a namespace + * @param len length of record we need to insert + */ + virtual int initialSize( int len ) const; + + /** * quantizes extent size to >= min + page boundary */ - static int quantizeExtentSize( int size ); + virtual int quantizeExtentSize( int size ) const; }; } diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp index b8b4a221d27..1073ba4e746 100644 --- a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp +++ b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp @@ -235,33 +235,14 @@ namespace mongo { return e; } - int MmapV1ExtentManager::quantizeExtentSize( int size ) { - - if ( size == Extent::maxSize() ) { - // no point doing quantizing for the entire file - return size; - } - - verify( size <= Extent::maxSize() ); - - // make sizes align with VM page size - int newSize = (size + 0xfff) & 0xfffff000; - - if ( newSize > Extent::maxSize() ) { - return Extent::maxSize(); - } - - if ( newSize < Extent::minSize() ) { - return Extent::minSize(); - } - - return newSize; - } - void _quotaExceeded() { uasserted(12501, "quota exceeded"); } + int MmapV1ExtentManager::maxSize() const { + return DataFile::maxSize() - DataFileHeader::HeaderSize - 16; + } + DiskLoc MmapV1ExtentManager::_createExtentInFile( TransactionExperiment* txn, int fileNo, DataFile* f, @@ -279,7 +260,7 @@ namespace mongo { } } - massert( 10358, "bad new extent size", size >= Extent::minSize() && size <= Extent::maxSize() ); + massert( 10358, "bad new extent size", size >= minSize() && size <= maxSize() ); DiskLoc loc = f->allocExtentArea( txn, size ); loc.assertOk(); @@ -300,8 +281,8 @@ namespace mongo { int maxFileNoForQuota ) { size = quantizeExtentSize( size ); - if ( size > Extent::maxSize() ) - size = Extent::maxSize(); + if ( size > maxSize() ) + size = maxSize(); verify( size < DataFile::maxSize() ); @@ -352,11 +333,11 @@ namespace mongo { } if ( high <= 0 ) { // overflowed - high = max(approxSize, Extent::maxSize()); + high = max(approxSize, maxSize()); } - if ( high <= Extent::minSize() ) { + if ( high <= minSize() ) { // the minimum extent size is 4097 - high = Extent::minSize() + 1; + high = minSize() + 1; } // scan free list looking for something suitable diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h index 678ff74a830..8c5f4bb656d 100644 --- a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h +++ b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h @@ -143,10 +143,7 @@ namespace mongo { */ Extent* getExtent( const DiskLoc& loc, bool doSanityCheck = true ) const; - /** - * quantizes extent size to >= min + page boundary - */ - static int quantizeExtentSize( int size ); + virtual int maxSize() const; private: diff --git a/src/mongo/db/structure/SConscript b/src/mongo/db/structure/SConscript index 0e058efe661..0e85340feb3 100644 --- a/src/mongo/db/structure/SConscript +++ b/src/mongo/db/structure/SConscript @@ -10,6 +10,7 @@ env.Library( '$BUILD_DIR/mongo/bson', '$BUILD_DIR/mongo/db/storage/extent', '$BUILD_DIR/mongo/foundation', + '$BUILD_DIR/mongo/mongocommon', ] ) diff --git a/src/mongo/db/structure/record_store_v1_simple.cpp b/src/mongo/db/structure/record_store_v1_simple.cpp index b4b4c10a2e5..bfb021f9f6c 100644 --- a/src/mongo/db/structure/record_store_v1_simple.cpp +++ b/src/mongo/db/structure/record_store_v1_simple.cpp @@ -230,8 +230,8 @@ namespace mongo { LOG(1) << "allocating new extent"; increaseStorageSize( txn, - Extent::followupSize( lengthWithHeaders, - _details->lastExtentSize()), + _extentManager->followupSize( lengthWithHeaders, + _details->lastExtentSize()), quotaMax ); loc = _allocFromExistingExtents( txn, lengthWithHeaders ); @@ -248,8 +248,8 @@ namespace mongo { log() << "try #" << z << endl; increaseStorageSize( txn, - Extent::followupSize( lengthWithHeaders, - _details->lastExtentSize()), + _extentManager->followupSize( lengthWithHeaders, + _details->lastExtentSize()), quotaMax ); loc = _allocFromExistingExtents( txn, lengthWithHeaders ); diff --git a/src/mongo/dbtests/pdfiletests.cpp b/src/mongo/dbtests/pdfiletests.cpp index a3bc2ad237f..7a6d23e2b3b 100644 --- a/src/mongo/dbtests/pdfiletests.cpp +++ b/src/mongo/dbtests/pdfiletests.cpp @@ -40,6 +40,7 @@ #include "mongo/db/storage/extent.h" #include "mongo/db/storage/extent_manager.h" #include "mongo/db/storage/mmap_v1/dur_transaction.h" +#include "mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h" #include "mongo/dbtests/dbtests.h" namespace PdfileTests { @@ -132,25 +133,29 @@ namespace PdfileTests { void run() { SmallFilesControl c; - ASSERT_EQUALS( Extent::maxSize(), - ExtentManager::quantizeExtentSize( Extent::maxSize() ) ); + Client::ReadContext ctx( "local" ); + Database* db = ctx.ctx().db(); + ExtentManager* em = db->getExtentManager(); + + ASSERT_EQUALS( em->maxSize(), + em->quantizeExtentSize( em->maxSize() ) ); // test that no matter what we start with, we always get to max extent size for ( int obj=16; obj<BSONObjMaxUserSize; obj += 111 ) { - int sz = Extent::initialSize( obj ); + int sz = em->initialSize( obj ); double totalExtentSize = sz; int numFiles = 1; - int sizeLeftInExtent = Extent::maxSize() - 1; + int sizeLeftInExtent = em->maxSize() - 1; for ( int i=0; i<100; i++ ) { - sz = Extent::followupSize( obj , sz ); + sz = em->followupSize( obj , sz ); ASSERT( sz >= obj ); - ASSERT( sz >= Extent::minSize() ); - ASSERT( sz <= Extent::maxSize() ); - ASSERT( sz <= DataFile::maxSize() ); + ASSERT( sz >= em->minSize() ); + ASSERT( sz <= em->maxSize() ); + ASSERT( sz <= em->maxSize() ); totalExtentSize += sz; @@ -159,12 +164,12 @@ namespace PdfileTests { } else { numFiles++; - sizeLeftInExtent = Extent::maxSize() - sz; + sizeLeftInExtent = em->maxSize() - sz; } } - ASSERT_EQUALS( Extent::maxSize() , sz ); + ASSERT_EQUALS( em->maxSize() , sz ); - double allocatedOnDisk = (double)numFiles * Extent::maxSize(); + double allocatedOnDisk = (double)numFiles * em->maxSize(); ASSERT( ( totalExtentSize / allocatedOnDisk ) > .95 ); |