/vesta/vestasys.org/vesta/log/12/src/VestaLogPrivate.H

Go to the documentation of this file.
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

Generated on Thu May 24 23:01:51 2007 for Vesta by  doxygen 1.5.1