summaryrefslogtreecommitdiff
path: root/db/reccache.cpp
diff options
context:
space:
mode:
authorDwight <dmerriman@gmail.com>2009-02-06 13:29:57 -0500
committerDwight <dmerriman@gmail.com>2009-02-06 13:29:57 -0500
commit94f125e8552d580b4f3038153b52f3e2ec1025d0 (patch)
treefafe3255abf38276adcd90f8ca9613b1781f1523 /db/reccache.cpp
parent75712322a1efbdfdf873e4a4bb26ac1111b04899 (diff)
downloadmongo-94f125e8552d580b4f3038153b52f3e2ec1025d0.tar.gz
new pagewriter
File class sleepmillis fixed
Diffstat (limited to 'db/reccache.cpp')
-rw-r--r--db/reccache.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/db/reccache.cpp b/db/reccache.cpp
new file mode 100644
index 00000000000..bc8882255f2
--- /dev/null
+++ b/db/reccache.cpp
@@ -0,0 +1,134 @@
+// storage.cpp
+
+#include "stdafx.h"
+#include "pdfile.h"
+#include "reccache.h"
+#include "rec.h"
+#include "db.h"
+
+namespace mongo {
+
+RecCache theRecCache(BucketSize);
+
+void writerThread() {
+ sleepsecs(10);
+ while( 1 ) {
+ try {
+ theRecCache.writeLazily();
+ }
+ catch(...) {
+ log() << "exception in writerThread()" << endl;
+ sleepsecs(3);
+ }
+ }
+}
+
+// called on program exit.
+void recCacheCloseAll() {
+#if defined(_RECSTORE)
+ assert( dbMutexInfo.isLocked() );
+ (cout << "TEMP: recCacheCloseAll() writing dirty pages...\n").flush();
+ theRecCache.writeDirty( theRecCache.dirtyl.begin(), true );
+ (cout << "TEMP: write dirty done\n").flush();
+#endif
+}
+
+int ndirtywritten;
+
+inline void RecCache::writeIfDirty(Node *n) {
+ if( n->dirty ) {
+ ndirtywritten++;
+ n->dirty = false;
+ tempStore.update(fileOfs(n->loc), n->data, recsize);
+ }
+}
+
+/* note that this is written in order, as much as possible, given that dirtyl is of type set. */
+void RecCache::writeDirty( set<DiskLoc>::iterator startAt, bool rawLog ) {
+ try {
+ ndirtywritten=0;
+ for( set<DiskLoc>::iterator i = startAt; i != dirtyl.end(); i++ ) {
+ map<DiskLoc, Node*>::iterator j = m.find(*i);
+ if( j != m.end() )
+ writeIfDirty(j->second);
+ }
+ OCCASIONALLY out() << "TEMP: ndirtywritten: " << ndirtywritten << endl;
+ }
+ catch(...) {
+ const char *message = "Problem: bad() in RecCache::writeDirty, file io error\n";
+ if ( rawLog )
+ rawOut( message );
+ else
+ ( log() << message ).flush();
+ }
+ dirtyl.clear();
+}
+
+void RecCache::writeLazily() {
+ int sleep = 0;
+ int k;
+ {
+ dblock lk;
+ Timer t;
+ set<DiskLoc>::iterator i = dirtyl.end();
+ for( k = 0; k < 100; k++ ) {
+ if( i == dirtyl.begin() ) {
+ // we're not very far behind
+ sleep = k < 20 ? 2000 : 1000;
+ break;
+ }
+ i--;
+ }
+ writeDirty(i);
+ if( sleep == 0 ) {
+ sleep = t.millis() * 4 + 10;
+ }
+ }
+
+ OCCASIONALLY cout << "writeLazily " << k << " sleep:" << sleep << '\n';
+ sleepmillis(sleep);
+}
+
+// 100k * 8KB = 800MB
+const unsigned RECCACHELIMIT = 150000;
+
+inline void RecCache::ejectOld() {
+ if( nnodes <= RECCACHELIMIT )
+ return;
+ Node *n = oldest;
+ while( 1 ) {
+ if( nnodes <= RECCACHELIMIT - 4 ) {
+ n->older = 0;
+ oldest = n;
+ assert( oldest ) ;
+ break;
+ }
+ nnodes--;
+ assert(n);
+ Node *nxt = n->newer;
+ writeIfDirty(n);
+ m.erase(n->loc);
+ delete n;
+ n = nxt;
+ }
+}
+
+void RecCache::dump() {
+ Node *n = oldest;
+ Node *last = 0;
+ while( n ) {
+ assert( n->older == last );
+ last = n;
+// cout << n << ' ' << n->older << ' ' << n->newer << '\n';
+ n=n->newer;
+ }
+ assert( newest == last );
+// cout << endl;
+}
+
+void dbunlocking() {
+ dassert( dbMutexInfo.isLocked() );
+ theRecCache.ejectOld();
+}
+
+}