From 6b24994f08a37739b359aed6950f87286aa562df Mon Sep 17 00:00:00 2001 From: Eliot Horowitz Date: Wed, 11 Jul 2012 15:23:59 -0400 Subject: SERVER-6414 - use regular file io, not mmap for external sort Conflicts: db/extsort.cpp db/extsort.h --- db/extsort.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++---------- db/extsort.h | 8 ++++--- 2 files changed, 65 insertions(+), 15 deletions(-) diff --git a/db/extsort.cpp b/db/extsort.cpp index 0cc36f159ed..e0d4d0cf93c 100644 --- a/db/extsort.cpp +++ b/db/extsort.cpp @@ -217,24 +217,72 @@ namespace mongo { // ----------------------------------- BSONObjExternalSorter::FileIterator::FileIterator( string file ) { - unsigned long long length; - _buf = (char*)_file.map( file.c_str() , length , MemoryMappedFile::SEQUENTIAL ); - massert( 10308 , "mmap failed" , _buf ); - assert( length == (unsigned long long) file_size( file ) ); - _end = _buf + length; + _file = ::open( file.c_str(), O_CREAT | O_RDWR | O_NOATIME , S_IRUSR | S_IWUSR ); + massert( 16392, + str::stream() << "FileIterator can't open file: " + << file << errnoWithDescription(), + _file >= 0 ); + +#ifdef POSIX_FADV_DONTNEED + posix_fadvise(_file, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_DONTNEED); +#endif + + _length = (unsigned long long)boost::filesystem::file_size( file ); + _readSoFar = 0; + } + + BSONObjExternalSorter::FileIterator::~FileIterator() { + if ( _file >= 0 ) + close( _file ); } - BSONObjExternalSorter::FileIterator::~FileIterator() {} bool BSONObjExternalSorter::FileIterator::more() { - return _buf < _end; + return _readSoFar < _length; } + + bool BSONObjExternalSorter::FileIterator::_read( char* buf, ssize_t count ) { + ssize_t total = 0; + while ( total < count ) { + ssize_t now = ::read( _file, buf, count ); + if ( now < 0 ) { + log() << "read failed for BSONObjExternalSorter " << errnoWithDescription() << endl; + return false; + } + if ( now == 0 ) { + return false; + } + total += now; + buf += now; + } + return true; + } + BSONObjExternalSorter::Data BSONObjExternalSorter::FileIterator::next() { - BSONObj o( _buf ); - _buf += o.objsize(); - DiskLoc * l = (DiskLoc*)_buf; - _buf += 8; - return Data( o , *l ); + // read BSONObj + + int size; + assert( _read( reinterpret_cast(&size), 4 ) ); + char* buf = reinterpret_cast( malloc( sizeof(unsigned) + size ) ); + assert( buf ); + + memset( buf, 0, 4 ); // for Holder + memcpy( buf+sizeof(unsigned), reinterpret_cast(&size), sizeof(int) ); // size of doc + if ( ! _read( buf + sizeof(unsigned) + sizeof(int), size-sizeof(int) ) ) { // doc content + free( buf ); + msgasserted( 16394, "reading doc for external sort failed" ); + } + + // read DiskLoc + DiskLoc l; + if ( ! _read( reinterpret_cast(&l), 8 ) ) { + free( buf ); + msgasserted( 16393, "reading DiskLoc for external sort failed" ); + } + _readSoFar += 8 + size; + + BSONObj::Holder* h = reinterpret_cast(buf); + return Data( BSONObj(h), l ); } } diff --git a/db/extsort.h b/db/extsort.h index ae6a334f77a..04f9e5e6f85 100644 --- a/db/extsort.h +++ b/db/extsort.h @@ -76,9 +76,11 @@ namespace mongo { bool more(); Data next(); private: - MemoryMappedFile _file; - char * _buf; - char * _end; + bool _read( char* buf, ssize_t count ); + + int _file; + unsigned long long _length; + unsigned long long _readSoFar; }; public: -- cgit v1.2.1