00001 // Copyright (C) 2001, Compaq Computer Corporation 00002 // 00003 // This file is part of Vesta. 00004 // 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 // 00020 // VestaLogPrivate.H 00021 // 00022 // Log changes to the repository state 00023 // Portion of VestaLog that is private to the implementation but is 00024 // needed by the compiler to build clients. 00025 // 00026 00027 #ifndef _VLOGP 00028 #define _VLOGP 1 00029 00030 #include "Basics.H" 00031 #include <netinet/in.h> 00032 00033 static const unsigned int DiskBlockSize = 512; 00034 00035 namespace VLog 00036 { 00037 // Physical block number. We use a 64-bit integer to make sure we 00038 // support large logs 00039 typedef Basics::uint64 phy_t; 00040 00041 // Block sequence number. 00042 typedef Basics::uint32 seq_t; 00043 00044 // Block length. 00045 typedef Basics::uint16 len_t; 00046 } 00047 00048 struct VLogBlock { 00049 VLogBlock *next; 00050 VLog::phy_t phy; // "physical" block number (address in file) 00051 VLog::phy_t pocketPhy;// reading: phy # of block left in pocket after 00052 // this one was sequenced. 00053 // writing: phy # of unused block in pocket 00054 bool tailCommitted; // during reading, true if the bytes beyond 00055 // len are known to be committed 00056 struct data_block { 00057 // Both seq and len are always in big-endian order. 00058 VLog::seq_t seq_; // hashed sequence number of this logical block 00059 VLog::len_t len_; // (offset to end of last record in this block, or 00060 // 0 if no record ends in this block) + 00061 // (2 bit block version number in high-order bits) 00062 char bytes[DiskBlockSize - 6]; 00063 00064 inline VLog::seq_t getSeq() throw() 00065 { return Basics::ntoh32(seq_); }; 00066 inline VLog::len_t getLen() throw() 00067 { return Basics::ntoh16(len_) & 0x3FFF; }; 00068 inline VLog::len_t getVer() throw() 00069 { return (Basics::ntoh16(len_) >> 14) & 0x0003; }; 00070 inline void setSeq(VLog::seq_t seq) throw() 00071 { seq_ = Basics::hton32(seq); }; 00072 inline void setLen(VLog::len_t len) throw() 00073 { len_ = Basics::hton16(len | (getVer() << 14)); }; 00074 inline void setVer(VLog::len_t ver) throw() 00075 { len_ = Basics::hton16(getLen() | ((ver & 0x0003) << 14)); }; 00076 } *data; 00077 00078 VLogBlock() 00079 { 00080 data = NEW_PTRFREE(data_block); 00081 #if defined(VALGRIND_SUPPORT) 00082 memset((void *) data, 0, sizeof(data_block)); 00083 #endif 00084 } 00085 ~VLogBlock() 00086 { 00087 delete data; 00088 data = NULL; // Help out the garbage collecotr 00089 } 00090 }; 00091 00092 00093 struct VestaLogPrivate { 00094 enum State { initial=0, recovering, recovered, ready, logging, bad }; 00095 bool checkpointing; 00096 bool readonly; 00097 bool bakckp; // true if backing up checkpoints 00098 bool hitEOF; // reading: true if we got an end-of-file 00099 bool usePocket; // writing: true if we should write to pocket next 00100 bool commUsePocket; // writing: usePocket after last commit 00101 int nesting; // if state==logging, how deeply starts are nested. 00102 State state; 00103 char* directory; // directory containing log and checkpoint files 00104 char* directory2; // dir containing backup of log (and ckp), or NULL 00105 int version; // log version currently open 00106 int ccVersion; // highest committed checkpoint 00107 int ccVersion2; // highest committed checkpoint in backup (if any) 00108 int fd; // log file descriptor 00109 int fd2; // log file descriptor for backup, -1 if none 00110 int lockfd; // lock file descriptor 00111 int lockfd2; // lock file descriptor for backup 00112 VLog::seq_t curSeq; // seq number of first block in cur chain 00113 VLog::len_t curLen; // offset of next byte in buf->bytes to read or write 00114 VLog::seq_t nextSeq; // reading: seq number of next block not yet sequenced 00115 VLog::phy_t nextPhy; // reading: phy address of next block not yet read 00116 VLog::seq_t commSeq; // writing: curSeq of last block written to commit 00117 VLog::phy_t commPhy; // writing: cur->phy after last commit 00118 VLog::phy_t commPocketPhy; // writing: cur->pocketPhy after last commit 00119 VLogBlock* cur; // reading: chain of blocks already read and sequenced 00120 // writing: buffer for block being assembled 00121 VLogBlock* last; // reading: last block in cur chain, NULL if none 00122 VLogBlock* pocket; // reading: holds saved out-of-order block 00123 VLogBlock* free; // free list 00124 00125 inline VLogBlock* balloc() throw() { 00126 if (free) { 00127 VLogBlock* b = free; 00128 free = free->next; 00129 b->next = NULL; // just to be cautious 00130 return b; 00131 } else { 00132 return NEW(VLogBlock); 00133 } 00134 }; 00135 inline void bfree(VLogBlock *b) throw() { 00136 b->next = free; 00137 free = b; 00138 }; 00139 void extendCur() // extend the cur chain by one block 00140 throw(VestaLog::Eof, VestaLog::Error); 00141 void makeBytesAvail() // ensure bytes to read in cur 00142 throw(VestaLog::Eof, VestaLog::Error); 00143 void writeCur() // write out cur block 00144 throw(VestaLog::Error); 00145 void makeSpaceAvail() // write full cur block and empty cur 00146 throw(VestaLog::Error); 00147 void eraseUncommitted(int fd) // write invalid data to unused blocks 00148 throw(VestaLog::Error); 00149 VLogBlock* readBlock() // read next block, return NULL if EOF 00150 throw(VestaLog::Error); 00151 }; 00152 00153 #endif //_VLOGP
1.5.1