00001
00002
00003 #pragma once
00004
00005 #include "diskloc.h"
00006 #include "mongommf.h"
00007
00008 namespace mongo {
00009
00010 class NamespaceDetails;
00011
00012 namespace dur {
00013
00014
00015 #if defined(__i386__) || defined(_M_IX86)
00016 const unsigned UncommittedBytesLimit = 50 * 1024 * 1024;
00017 #else
00018 const unsigned UncommittedBytesLimit = 100 * 1024 * 1024;
00019 #endif
00020
00025 void startup();
00026
00027 class DurableInterface : boost::noncopyable {
00028 public:
00029 virtual ~DurableInterface() { log() << "ERROR warning ~DurableInterface not intended to be called" << endl; }
00030
00036 virtual void createdFile(string filename, unsigned long long len) = 0;
00037
00050 virtual void* writingPtr(void *x, unsigned len) = 0;
00051
00055 virtual void declareWriteIntent(void *x, unsigned len) = 0;
00056
00062 virtual void* writingAtOffset(void *buf, unsigned ofs, unsigned len) = 0;
00063
00070 virtual void* writingRangesAtOffsets(void *buf, const vector< pair< long long, unsigned > > &ranges ) = 0;
00071
00076 virtual bool awaitCommit() = 0;
00077
00091 virtual bool commitNow() = 0;
00092
00101 virtual bool commitIfNeeded() = 0;
00102
00104 inline DiskLoc& writingDiskLoc(DiskLoc& d) { return *((DiskLoc*) writingPtr(&d, sizeof(d))); }
00105
00107 inline int& writingInt(const int& d) { return *((int*) writingPtr((int*) &d, sizeof(d))); }
00108
00112 template <typename T>
00113 inline
00114 T* alreadyDeclared(T *x) {
00115 #if defined(_TESTINTENT)
00116 return (T*) MongoMMF::switchToPrivateView(x);
00117 #else
00118 return x;
00119 #endif
00120 }
00121
00123 template <typename T>
00124 inline
00125 T* writing(T *x) {
00126 return (T*) writingPtr(x, sizeof(T));
00127 }
00128
00135 virtual void setNoJournal(void *dst, void *src, unsigned len) = 0;
00136
00144 virtual void syncDataAndTruncateJournal() = 0;
00145
00146 static DurableInterface& getDur() { return *_impl; }
00147
00148 private:
00153 Record* writing(Record* r);
00155 BtreeBucket* writing( BtreeBucket* );
00157 NamespaceDetails* writing( NamespaceDetails* );
00158
00159 static DurableInterface* _impl;
00160 static void enableDurability();
00161 static void disableDurability();
00162
00163
00164 friend void startup();
00165 friend class TempDisableDurability;
00166 };
00167
00168 class NonDurableImpl : public DurableInterface {
00169 void* writingPtr(void *x, unsigned len) { return x; }
00170 void* writingAtOffset(void *buf, unsigned ofs, unsigned len) { return buf; }
00171 void* writingRangesAtOffsets(void *buf, const vector< pair< long long, unsigned > > &ranges) { return buf; }
00172 void declareWriteIntent(void *, unsigned) { }
00173 void createdFile(string filename, unsigned long long len) { }
00174 bool awaitCommit() { return false; }
00175 bool commitNow() { return false; }
00176 bool commitIfNeeded() { return false; }
00177 void setNoJournal(void *dst, void *src, unsigned len);
00178 void syncDataAndTruncateJournal() {}
00179 };
00180
00181 class DurableImpl : public DurableInterface {
00182 void* writingPtr(void *x, unsigned len);
00183 void* writingAtOffset(void *buf, unsigned ofs, unsigned len);
00184 void* writingRangesAtOffsets(void *buf, const vector< pair< long long, unsigned > > &ranges);
00185 void declareWriteIntent(void *, unsigned);
00186 void createdFile(string filename, unsigned long long len);
00187 bool awaitCommit();
00188 bool commitNow();
00189 bool commitIfNeeded();
00190 void setNoJournal(void *dst, void *src, unsigned len);
00191 void syncDataAndTruncateJournal();
00192 };
00193
00194 }
00195
00196 inline dur::DurableInterface& getDur() { return dur::DurableInterface::getDur(); }
00197
00199 inline DiskLoc& DiskLoc::writing() const { return getDur().writingDiskLoc(*const_cast< DiskLoc * >( this )); }
00200
00201 }