summaryrefslogtreecommitdiff
path: root/db/dur.h
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2010-12-09 14:44:08 -0500
committerMathias Stearn <mathias@10gen.com>2010-12-10 19:20:43 -0500
commit1c17cece76f77fa00e643ce5e4fa85ccebc9f990 (patch)
treeac651dae252641816dbdb9053aa2f76ed8656c89 /db/dur.h
parent3469206c4bebd4ee66529bb34deaf3ad9cdcfbb3 (diff)
downloadmongo-1c17cece76f77fa00e643ce5e4fa85ccebc9f990.tar.gz
Pull some durability code into a class for easy disabling
Diffstat (limited to 'db/dur.h')
-rw-r--r--db/dur.h82
1 files changed, 52 insertions, 30 deletions
diff --git a/db/dur.h b/db/dur.h
index 32f40085c12..4029de4131e 100644
--- a/db/dur.h
+++ b/db/dur.h
@@ -7,39 +7,22 @@
namespace mongo {
- namespace dur {
-
- /** it's very easy to manipulate Record::data open ended. Thus a call to writing(Record*) is suspect.
- this will override the templated version and yield an unresolved external
- */
- Record* writing(Record* r);
-
-#if !defined(_DURABLE)
- inline void startup() { }
- inline void* writingPtr(void *x, unsigned len) { return x; }
- inline DiskLoc& writingDiskLoc(DiskLoc& d) { return d; }
- inline int& writingInt(int& d) { return d; }
- inline Record* writing(Record* r) { return r; }
- template <typename T> inline T* writing(T *x) { return x; }
- inline void assertReading(void *p) { }
- template <typename T> inline T* writingNoLog(T *x) { return x; }
- inline void* writingAtOffset(void *buf, unsigned ofs, unsigned len) { return buf; }
- template <typename T> inline T* alreadyDeclared(T *x) { return x; }
- inline void declareWriteIntent(void *, unsigned) { }
- inline void createdFile(string filename, unsigned long long len) { }
-#else
+ class DurableInterface {
+ protected:
+ DurableInterface() {} // Should only be creating subclasses
+ public:
/** call during startup so durability module can initialize
throws if fatal error
*/
- void startup();
+ virtual void startup() = 0;
/** Declare that a file has been created
Normally writes are applied only after journalling, for safety. But here the file
is created first, and the journal will just replay the creation if the create didn't
happen because of crashing.
*/
- void createdFile(string filename, unsigned long long len);
+ virtual void createdFile(string filename, unsigned long long len) = 0;
/** Declarations of write intent.
@@ -53,19 +36,27 @@ namespace mongo {
/** declare intent to write to x for up to len
@return pointer where to write. this is modified when testIntent is true.
*/
- void* writingPtr(void *x, unsigned len);
+ virtual void* writingPtr(void *x, unsigned len) = 0;
/** declare write intent; should already be in the write view to work correctly when testIntent is true.
if you aren't, use writingPtr() instead.
*/
- void declareWriteIntent(void *x, unsigned len);
+ virtual void declareWriteIntent(void *x, unsigned len) = 0;
/** declare intent to write
@param ofs offset within buf at which we will write
@param len the length at ofs we will write
@return new buffer pointer. this is modified when testIntent is true.
*/
- void* writingAtOffset(void *buf, unsigned ofs, unsigned len);
+ virtual void* writingAtOffset(void *buf, unsigned ofs, unsigned len) = 0;
+
+ virtual void debugCheckLastDeclaredWrite() = 0;
+
+ virtual ~DurableInterface() { assert(!"don't destroy me"); }
+
+ //////////////////////////////
+ // END OF VIRTUAL FUNCTIONS //
+ //////////////////////////////
inline DiskLoc& writingDiskLoc(DiskLoc& d) {
return *((DiskLoc*) writingPtr(&d, sizeof(d)));
@@ -94,6 +85,11 @@ namespace mongo {
return (T*) writingPtr(x, sizeof(T));
}
+ /** it's very easy to manipulate Record::data open ended. Thus a call to writing(Record*) is suspect.
+ this will override the templated version and yield an unresolved external
+ */
+ Record* writing(Record* r);
+
/** declare our intent to write, but it doesn't have to be journaled, as this write is
something 'unimportant'. depending on our implementation, we may or may not be able
to take advantage of this versus doing the normal work we do.
@@ -110,13 +106,39 @@ namespace mongo {
dassert( !testIntent || MongoMMF::switchToPrivateView(p) != p );
}
-#endif
+ private:
+ static DurableInterface* _impl;
- void debugCheckLastDeclaredWrite();
+ // in mongo:: namespace
+ friend DurableInterface& getDur();
+ friend void enableDurability(); // should only be called once at startup
+
+ }; // class DurableInterface
+
+ inline DurableInterface& getDur() { return *DurableInterface::_impl; }
+ void enableDurability();
- } // namespace dur
+ class NonDurableImpl : public DurableInterface {
+ void startup() { }
+ void* writingPtr(void *x, unsigned len) { return x; }
+ void* writingAtOffset(void *buf, unsigned ofs, unsigned len) { return buf; }
+ void declareWriteIntent(void *, unsigned) { }
+ void createdFile(string filename, unsigned long long len) { }
+ void debugCheckLastDeclaredWrite() {}
+ };
+
+#ifdef _DURABLE
+ class DurableImpl : public DurableInterface {
+ void startup();
+ void* writingPtr(void *x, unsigned len);
+ void* writingAtOffset(void *buf, unsigned ofs, unsigned len);
+ void declareWriteIntent(void *, unsigned);
+ void createdFile(string filename, unsigned long long len);
+ void debugCheckLastDeclaredWrite();
+ };
+#endif
/** declare that we are modifying a diskloc and this is a datafile write. */
- inline DiskLoc& DiskLoc::writing() const { return dur::writingDiskLoc(*const_cast< DiskLoc * >( this )); }
+ inline DiskLoc& DiskLoc::writing() const { return getDur().writingDiskLoc(*const_cast< DiskLoc * >( this )); }
}