diff options
Diffstat (limited to 'db/pdfile.h')
-rw-r--r-- | db/pdfile.h | 112 |
1 files changed, 80 insertions, 32 deletions
diff --git a/db/pdfile.h b/db/pdfile.h index 85dc191..084a542 100644 --- a/db/pdfile.h +++ b/db/pdfile.h @@ -25,7 +25,7 @@ #pragma once -#include "../stdafx.h" +#include "../pch.h" #include "../util/mmap.h" #include "diskloc.h" #include "jsobjmanipulator.h" @@ -34,29 +34,28 @@ namespace mongo { - class MDFHeader; + class DataFileHeader; class Extent; class Record; class Cursor; class OpDebug; - void dropDatabase(const char *ns); - bool repairDatabase(const char *ns, string &errmsg, bool preserveClonedFilesOnFailure = false, bool backupOriginalFiles = false); + void dropDatabase(string db); + bool repairDatabase(string db, string &errmsg, bool preserveClonedFilesOnFailure = false, bool backupOriginalFiles = false); /* low level - only drops this ns */ void dropNS(const string& dropNs); /* deletes this ns, indexes and cursors */ void dropCollection( const string &name, string &errmsg, BSONObjBuilder &result ); - bool userCreateNS(const char *ns, BSONObj j, string& err, bool logForReplication); - auto_ptr<Cursor> findTableScan(const char *ns, const BSONObj& order, const DiskLoc &startLoc=DiskLoc()); + bool userCreateNS(const char *ns, BSONObj j, string& err, bool logForReplication, bool *deferIdIndex = 0); + shared_ptr<Cursor> findTableScan(const char *ns, const BSONObj& order, const DiskLoc &startLoc=DiskLoc()); // -1 if library unavailable. - boost::intmax_t freeSpace(); + boost::intmax_t freeSpace( const string &path = dbpath ); /*---------------------------------------------------------------------*/ - class MDFHeader; class MongoDataFile { friend class DataFileMgr; friend class BasicCursor; @@ -70,22 +69,27 @@ namespace mongo { */ Extent* createExtent(const char *ns, int approxSize, bool capped = false, int loops = 0); - MDFHeader *getHeader() { + DataFileHeader *getHeader() { return header; } /* return max size an extent may be */ static int maxSize(); - + + void flush( bool sync ); + private: int defaultSize( const char *filename ) const; Extent* getExtent(DiskLoc loc); Extent* _getExtent(DiskLoc loc); Record* recordAt(DiskLoc dl); + Record* makeRecord(DiskLoc dl, int size); + void grow(DiskLoc dl, int size); - MemoryMappedFile mmf; - MDFHeader *header; + MMF mmf; + MMF::Pointer _p; + DataFileHeader *header; int fileNo; }; @@ -98,18 +102,26 @@ namespace mongo { static Extent* allocFromFreeList(const char *ns, int approxSize, bool capped = false); /** @return DiskLoc where item ends up */ + // changedId should be initialized to false const DiskLoc updateRecord( const char *ns, NamespaceDetails *d, NamespaceDetailsTransient *nsdt, Record *toupdate, const DiskLoc& dl, - const char *buf, int len, OpDebug& debug); + const char *buf, int len, OpDebug& debug, bool &changedId, bool god=false); + // The object o may be updated if modified on insert. void insertAndLog( const char *ns, const BSONObj &o, bool god = false ); - DiskLoc insert(const char *ns, BSONObj &o, bool god = false); + + /** @param obj both and in and out param -- insert can sometimes modify an object (such as add _id). */ + DiskLoc insertWithObjMod(const char *ns, BSONObj &o, bool god = false); + + /** @param obj in value only for this version. */ + void insertNoReturnVal(const char *ns, BSONObj o, bool god = false); + DiskLoc insert(const char *ns, const void *buf, int len, bool god = false, const BSONElement &writeId = BSONElement(), bool mayAddIndex = true); void deleteRecord(const char *ns, Record *todelete, const DiskLoc& dl, bool cappedOK = false, bool noWarn = false); - static auto_ptr<Cursor> findAll(const char *ns, const DiskLoc &startLoc = DiskLoc()); + static shared_ptr<Cursor> findAll(const char *ns, const DiskLoc &startLoc = DiskLoc()); /* special version of insert for transaction logging -- streamlined a bit. assumes ns is capped and no indexes @@ -119,6 +131,8 @@ namespace mongo { static Extent* getExtent(const DiskLoc& dl); static Record* getRecord(const DiskLoc& dl); + static DeletedRecord* makeDeletedRecord(const DiskLoc& dl, int len); + static void grow(const DiskLoc& dl, int len); /* does not clean up indexes, etc. : just deletes the record in the pdfile. */ void _deleteRecord(NamespaceDetails *d, const char *ns, Record *todelete, const DiskLoc& dl); @@ -197,7 +211,9 @@ namespace mongo { int length; /* size of the extent, including these fields */ DiskLoc firstRecord, lastRecord; - char extentData[4]; + char _extentData[4]; + + static int HeaderSize() { return sizeof(Extent)-4; } bool validates() { return !(firstRecord.isNull() ^ lastRecord.isNull()) && @@ -254,8 +270,7 @@ namespace mongo { ---------------------- */ - /* data file header */ - class MDFHeader { + class DataFileHeader { public: int version; int versionMinor; @@ -266,9 +281,7 @@ namespace mongo { char data[4]; - static int headerSize() { - return sizeof(MDFHeader) - 4; - } + enum { HeaderSize = 8192 }; bool currentVersion() const { return ( version == VERSION ) && ( versionMinor == VERSION_MINOR ); @@ -279,28 +292,28 @@ namespace mongo { return false; } - Record* getRecord(DiskLoc dl) { + /*Record* __getRecord(DiskLoc dl) { int ofs = dl.getOfs(); - assert( ofs >= headerSize() ); + assert( ofs >= HeaderSize ); return (Record*) (((char *) this) + ofs); - } + }*/ void init(int fileno, int filelength) { if ( uninitialized() ) { assert(filelength > 32768 ); - assert( headerSize() == 8192 ); + assert( HeaderSize == 8192 ); fileLength = filelength; version = VERSION; versionMinor = VERSION_MINOR; - unused.setOfs( fileno, headerSize() ); - assert( (data-(char*)this) == headerSize() ); - unusedLength = fileLength - headerSize() - 16; - memcpy(data+unusedLength, " \nthe end\n", 16); + unused.setOfs( fileno, HeaderSize ); + assert( (data-(char*)this) == HeaderSize ); + unusedLength = fileLength - HeaderSize - 16; + //memcpy(data+unusedLength, " \nthe end\n", 16); } } bool isEmpty() const { - return uninitialized() || ( unusedLength == fileLength - headerSize() - 16 ); + return uninitialized() || ( unusedLength == fileLength - HeaderSize - 16 ); } }; @@ -308,7 +321,7 @@ namespace mongo { inline Extent* MongoDataFile::_getExtent(DiskLoc loc) { loc.assertOk(); - Extent *e = (Extent *) (((char *)header) + loc.getOfs()); + Extent *e = (Extent *) _p.at(loc.getOfs(), Extent::HeaderSize()); return e; } @@ -325,7 +338,20 @@ namespace mongo { namespace mongo { inline Record* MongoDataFile::recordAt(DiskLoc dl) { - return header->getRecord(dl); + int ofs = dl.getOfs(); + assert( ofs >= DataFileHeader::HeaderSize ); + return (Record*) _p.at(ofs, -1); + } + + inline void MongoDataFile::grow(DiskLoc dl, int size) { + int ofs = dl.getOfs(); + _p.grow(ofs, size); + } + + inline Record* MongoDataFile::makeRecord(DiskLoc dl, int size) { + int ofs = dl.getOfs(); + assert( ofs >= DataFileHeader::HeaderSize ); + return (Record*) _p.at(ofs, size); } inline DiskLoc Record::getNext(const DiskLoc& myLoc) { @@ -446,9 +472,31 @@ namespace mongo { assert( dl.a() != -1 ); return cc().database()->getFile(dl.a())->recordAt(dl); } + + BOOST_STATIC_ASSERT( 16 == sizeof(DeletedRecord) ); + + inline void DataFileMgr::grow(const DiskLoc& dl, int len) { + assert( dl.a() != -1 ); + cc().database()->getFile(dl.a())->grow(dl, len); + } + + inline DeletedRecord* DataFileMgr::makeDeletedRecord(const DiskLoc& dl, int len) { + assert( dl.a() != -1 ); + return (DeletedRecord*) cc().database()->getFile(dl.a())->makeRecord(dl, sizeof(DeletedRecord)); + } void ensureHaveIdIndex(const char *ns); bool dropIndexes( NamespaceDetails *d, const char *ns, const char *name, string &errmsg, BSONObjBuilder &anObjBuilder, bool maydeleteIdIndex ); + + + /** + * @return true if ns is ok + */ + inline bool nsDollarCheck( const char* ns ){ + if ( strchr( ns , '$' ) == 0 ) + return true; + return strcmp( ns, "local.oplog.$main" ) == 0; + } } // namespace mongo |