summaryrefslogtreecommitdiff
path: root/db/pdfile.h
diff options
context:
space:
mode:
Diffstat (limited to 'db/pdfile.h')
-rw-r--r--db/pdfile.h112
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