void Database::flushFiles( bool sync ) { assertDbAtLeastReadLocked(this); for( vector<MongoDataFile*>::iterator i = _files.begin(); i != _files.end(); i++ ) { MongoDataFile *f = *i; f->flush(sync); } }
// todo: this is called a lot. streamline the common case MongoDataFile* Database::getFile( int n, int sizeNeeded , bool preallocateOnly) { assert(this); DEV assertDbAtLeastReadLocked(this); namespaceIndex.init(); if ( n < 0 || n >= DiskLoc::MaxFiles ) { out() << "getFile(): n=" << n << endl; massert( 10295 , "getFile(): bad file number value (corrupt db?): run repair", false); } DEV { if ( n > 100 ) { out() << "getFile(): n=" << n << endl; } } MongoDataFile* p = 0; if ( !preallocateOnly ) { while ( n >= (int) _files.size() ) { assert(this); if( !Lock::isWriteLocked(this->name) ) { log() << "error: getFile() called in a read lock, yet file to return is not yet open" << endl; log() << " getFile(" << n << ") _files.size:" <<_files.size() << ' ' << fileName(n).string() << endl; log() << " context ns: " << cc().ns() << " openallfiles:" << _openAllFiles << endl; assert(false); } _files.push_back(0); } p = _files[n]; } if ( p == 0 ) { assertDbWriteLocked(this); boost::filesystem::path fullName = fileName( n ); string fullNameString = fullName.string(); p = new MongoDataFile(n); int minSize = 0; if ( n != 0 && _files[ n - 1 ] ) minSize = _files[ n - 1 ]->getHeader()->fileLength; if ( sizeNeeded + DataFileHeader::HeaderSize > minSize ) minSize = sizeNeeded + DataFileHeader::HeaderSize; try { p->open( fullNameString.c_str(), minSize, preallocateOnly ); } catch ( AssertionException& ) { delete p; throw; } if ( preallocateOnly ) delete p; else _files[n] = p; } return preallocateOnly ? 0 : p; }
bool Database::openExistingFile( int n ) { assert(this); assertDbAtLeastReadLocked(this); { // must not yet be visible to others as we aren't in the db's write lock and // we will write to _files vector - thus this assert. bool loaded = dbHolder.__isLoaded(name, path); assert( !loaded ); } // additionally must be in the dbholder mutex (no assert for that yet) // todo: why here? that could be bad as we may be read locked only here namespaceIndex.init(); if ( n < 0 || n >= DiskLoc::MaxFiles ) { massert( 15924 , str::stream() << "getFile(): bad file number value " << n << " (corrupt db?): run repair", false); } { if( n < (int) _files.size() && _files[n] ) { dlog(2) << "openExistingFile " << n << " is already open" << endl; return true; } } { boost::filesystem::path fullName = fileName( n ); string fullNameString = fullName.string(); MongoDataFile *df = new MongoDataFile(n); try { if( !df->openExisting( fullNameString.c_str() ) ) { delete df; return false; } } catch ( AssertionException& ) { delete df; throw; } while ( n >= (int) _files.size() ) { _files.push_back(0); } _files[n] = df; } return true; }
int Database::numFiles() const { DEV assertDbAtLeastReadLocked(this); return (int) _files.size(); }