00001
00002
00019 #pragma once
00020
00021 #include "../util/md5.hpp"
00022
00023 namespace mongo {
00024
00025 namespace dur {
00026
00027 #pragma pack(1)
00028
00031 struct JHeader {
00032 JHeader() { }
00033 JHeader(string fname);
00034
00035 char magic[2];
00036
00037
00038
00039 enum { CurrentVersion = 0x4147 };
00040 unsigned short _version;
00041
00042
00043 char n1;
00044 char ts[20];
00045 char n2;
00046 char dbpath[128];
00047 char n3, n4;
00048
00049 unsigned long long fileId;
00050
00051 char reserved3[8026];
00052 char txt2[2];
00053
00054 bool versionOk() const { return _version == CurrentVersion; }
00055 bool valid() const { return magic[0] == 'j' && txt2[1] == '\n' && fileId; }
00056 };
00057
00061 struct JSectHeader {
00062 unsigned len;
00063 unsigned long long seqNumber;
00064 unsigned long long fileId;
00065 };
00066
00070 struct JEntry {
00071 enum OpCodes {
00072 OpCode_Footer = 0xffffffff,
00073 OpCode_DbContext = 0xfffffffe,
00074 OpCode_FileCreated = 0xfffffffd,
00075 OpCode_DropDb = 0xfffffffc,
00076 OpCode_Min = 0xfffff000
00077 };
00078 union {
00079 unsigned len;
00080 OpCodes opcode;
00081 };
00082
00083 unsigned ofs;
00084
00085
00086 enum {
00087 DotNsSuffix = 0x7fffffff,
00088 LocalDbBit = 0x80000000
00089 };
00090 int _fileNo;
00091
00092
00093 const char * srcData() const {
00094 const int *i = &_fileNo;
00095 return (const char *) (i+1);
00096 }
00097
00098 int getFileNo() const { return _fileNo & (~LocalDbBit); }
00099 void setFileNo(int f) { _fileNo = f; }
00100 bool isNsSuffix() const { return getFileNo() == DotNsSuffix; }
00101
00102 void setLocalDbContextBit() { _fileNo |= LocalDbBit; }
00103 bool isLocalDbContext() const { return _fileNo & LocalDbBit; }
00104 void clearLocalDbContextBit() { _fileNo = getFileNo(); }
00105
00106 static string suffix(int fileno) {
00107 if( fileno == DotNsSuffix ) return "ns";
00108 stringstream ss;
00109 ss << fileno;
00110 return ss.str();
00111 }
00112 };
00113
00115 struct JSectFooter {
00116 JSectFooter(const void* begin, int len) {
00117 sentinel = JEntry::OpCode_Footer;
00118 reserved = 0;
00119 magic[0] = magic[1] = magic[2] = magic[3] = '\n';
00120
00121
00122 (const char*&)begin += sizeof(JSectHeader);
00123 len -= sizeof(JSectHeader);
00124
00125 md5(begin, len, hash);
00126 }
00127 unsigned sentinel;
00128 md5digest hash;
00129 unsigned long long reserved;
00130 char magic[4];
00131
00132 bool checkHash(const void* begin, int len) const {
00133
00134 (const char*&)begin += sizeof(JSectHeader);
00135 len -= sizeof(JSectHeader);
00136 md5digest current;
00137 md5(begin, len, current);
00138 DEV log() << "checkHash len:" << len << " hash:" << toHex(hash, 16) << " current:" << toHex(current, 16) << endl;
00139 return (memcmp(hash, current, sizeof(hash)) == 0);
00140 }
00141 };
00142
00144 struct JDbContext {
00145 JDbContext() : sentinel(JEntry::OpCode_DbContext) { }
00146 const unsigned sentinel;
00147
00148 };
00149
00151 struct LSNFile {
00152 unsigned ver;
00153 unsigned reserved2;
00154 unsigned long long lsn;
00155 unsigned long long checkbytes;
00156 unsigned long long reserved[8];
00157
00158 void set(unsigned long long lsn);
00159 unsigned long long get();
00160 };
00161
00162 #pragma pack()
00163
00164 }
00165
00166 }