From 5e5765f9b4c8f9dd4700946e4ef52be21fa298dd Mon Sep 17 00:00:00 2001 From: dwight Date: Sun, 1 Feb 2009 14:53:54 -0500 Subject: [PATCH] recstore --- db/db.vcproj | 12 +++++ db/dbinfo.cpp | 5 +++ db/instance.cpp | 2 +- db/pdfile.cpp | 6 +-- db/rec.h | 7 ++- db/recstore.h | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ stdafx.h | 13 +++--- 7 files changed, 148 insertions(+), 10 deletions(-) create mode 100644 db/recstore.h diff --git a/db/db.vcproj b/db/db.vcproj index 6bed1141e4a..42c2e3593d8 100644 --- a/db/db.vcproj +++ b/db/db.vcproj @@ -661,6 +661,18 @@ RelativePath=".\queryoptimizer.h" > + + + + + + diff --git a/db/dbinfo.cpp b/db/dbinfo.cpp index 79ece1f6eca..198ceb27f31 100644 --- a/db/dbinfo.cpp +++ b/db/dbinfo.cpp @@ -20,6 +20,11 @@ #include "db.h" #include "query.h" +#if 0 +#else asdfl(0) + +#endif + namespace mongo { void DBInfo::setHaveLogged() { diff --git a/db/instance.cpp b/db/instance.cpp index 59fa0e54111..6a6464ad73f 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -528,7 +528,7 @@ namespace mongo { } } else { - mongo::out() << " jnicall: operation isn't supported: " << m.data->operation() << endl; + mongo::out() << " jnicall: operation isn't supported: " << m.data->operation() << endl; assert(false); } diff --git a/db/pdfile.cpp b/db/pdfile.cpp index d3386a5a145..20cbf1ea2fd 100644 --- a/db/pdfile.cpp +++ b/db/pdfile.cpp @@ -208,7 +208,7 @@ namespace mongo { string s = "db disk space quota exceeded "; if ( database ) s += database->name; - uasserted(s.c_str()); + uasserted(s); } } @@ -958,7 +958,7 @@ namespace mongo { tabletoidxns << "\n ourns:" << ns; out() << "\n idxobj:" << io.toString() << endl; string s = "bad add index attempt " + tabletoidxns + " key:" + key.toString(); - uasserted(s.c_str()); + uasserted(s); } tableToIndex = nsdetails(tabletoidxns.c_str()); if ( tableToIndex == 0 ) { @@ -977,7 +977,7 @@ namespace mongo { ss << "add index fails, too many indexes for " << tabletoidxns << " key:" << key.toString(); string s = ss.str(); log() << s << '\n'; - uasserted(s.c_str()); + uasserted(s); } if ( tableToIndex->findIndexByName(name) >= 0 ) { //out() << "INFO: index:" << name << " already exists for:" << tabletoidxns << endl; diff --git a/db/rec.h b/db/rec.h index d7ddba02e44..0195b0c7d7b 100644 --- a/db/rec.h +++ b/db/rec.h @@ -26,9 +26,12 @@ class InMem_RecStore : public RecStoreInterface { public: static char* get(DiskLoc d, unsigned len) { assert( d.a() == INMEMFILE ); - //return (char *) d.getOfs(); +#ifdef __LP64__ massert("64 bit not done", false); return 0; +#else + return (char *) d.getOfs(); +#endif } static DiskLoc insert(const char *ns, const void *obuf, int len, bool god) { @@ -61,3 +64,5 @@ inline BtreeBucket* DiskLoc::btree() const { } } + +#include "recstore.h" diff --git a/db/recstore.h b/db/recstore.h new file mode 100644 index 00000000000..695e53db5eb --- /dev/null +++ b/db/recstore.h @@ -0,0 +1,113 @@ +// recstore.h + +#pragma once + +namespace mongo { + +typedef uint64_t fileofs; + +struct RecStoreHeader { + uint32_t version; + uint32_t recsize; + uint64_t leof; // logical eof, actual file might be prealloc'd further + uint64_t firstDeleted; // 0 = no deleted recs + uint32_t cleanShutdown; // = clean + char reserved[8192-8-8-4-4]; // we want our records page-aligned in the file if they are a multiple of a page's size -- so we make this 8KB with that goal + RecStoreHeader() { + version = 65; + recsize = 0; + leof = sizeof(RecStoreHeader); + firstDeleted = 0; + cleanShutdown = 1; + memset(reserved, 0, sizeof(reserved)); + } +}; + +/* Current version supports only consistent record sizes within a store. */ + +class RecStore { +public: + ~RecStore(); + RecStore(const char *fn, unsigned recsize); + fileofs insert(const char *buf, unsigned len); + void update(fileofs o, const char *buf, unsigned len); + void remove(fileofs o, unsigned len); +private: + void writeHeader(); + fstream f; + fileofs len; + RecStoreHeader h; // h.reserved is wasteful here; fix later. +}; + +/* --- implementation --- */ + +inline RecStore::~RecStore() { + h.cleanShutdown = 0; + writeHeader(); +} + +inline +RecStore::RecStore(const char *fn, unsigned recsize) : + f(fn, ios::ate | ios::binary | ios::in | ios::out) +{ + massert( "compile packing problem recstore?", sizeof(RecStoreHeader) == 512); + uassert( string("couldn't open file:")+fn, f.is_open() ); + len = f.tellg(); + if( len == 0 ) { + log() << "creating recstore file " << fn << '\n'; + h.recsize = recsize; + len = sizeof(RecStoreHeader); + f.seekp(0); + f.write((const char *) &h, sizeof(RecStoreHeader)); + } + else { + f.seekg(0); + f.read((char *) &h, sizeof(RecStoreHeader)); + massert(string("recstore recsize mismatch, file:")+fn, h.recsize == recsize); + massert(string("bad recstore [1], file:")+fn, (h.leof-sizeof(RecStoreHeader)) % recsize == 0); + massert(string("bad recstore [1], file:")+fn, h.leof <= len); + if( h.cleanShutdown ) + log() << "warning: non-clean shutdown for file " << fn << '\n'; + h.cleanShutdown = 2; + writeHeader(); + } +} + +inline void RecStore::writeHeader() { + f.seekp(0); + f.write((const char *) &h, 28); // update header in file for new leof + uassert("file io error in RecStore [1]", !f.bad()); +} + +inline fileofs RecStore::insert(const char *buf, unsigned reclen) { + if( h.firstDeleted ) { + uasserted("deleted not yet implemented recstoreinsert"); + } + massert("bad len", reclen == h.recsize); + fileofs ofs = h.leof; + h.leof += reclen; + if( h.leof > len ) { + // grow the file. we grow quite a bit to avoid excessive file system fragmentations + len += (len / 8) + h.recsize; + uassert( "recstore file too big for 32 bit", len <= 0x7fffffff || sizeof(std::streamoff) > 4 ); + f.seekp((std::streamoff)len); + f.write("", 0); + } + writeHeader(); + f.seekp((std::streamoff)ofs); + f.write(buf, reclen); + uassert("file io error in RecStore [2]", !f.bad()); + return ofs; +} + +inline void RecStore::update(fileofs o, const char *buf, unsigned len) { + assert(o <= h.leof && o >= sizeof(RecStoreHeader)); + f.seekp((std::streamoff)o); + f.write(buf, len); +} + +inline void RecStore::remove(fileofs o, unsigned len) { + uasserted("not yet implemented recstoreremove"); +} + +} diff --git a/stdafx.h b/stdafx.h index 3048a0f851b..788292db112 100644 --- a/stdafx.h +++ b/stdafx.h @@ -159,8 +159,10 @@ namespace mongo { void asserted(const char *msg, const char *file, unsigned line); void wasserted(const char *msg, const char *file, unsigned line); void uasserted(const char *msg); + inline void uasserted(string msg) { uasserted(msg.c_str()); } void uassert_nothrow(const char *msg); // reported via lasterror, but don't throw exception void msgasserted(const char *msg); + inline void msgasserted(string msg) { msgasserted(msg.c_str()); } #ifdef assert #undef assert @@ -310,11 +312,12 @@ namespace mongo { #define yassert 1 using namespace boost::filesystem; -#if defined(__linux__) -#include "stdint.h" -#else if( !defined(uint64_t) ) -typedef unsigned long long uint64_t; -#endif +// boost::uint64_T is defined, don't need this +//#if defined(__linux__) +//#include "stdint.h" +//#else if( !defined(uint64_t) ) +//typedef unsigned long long uint64_t; +//#endif #include "util/goodies.h" #include "util/log.h"