// // The developer of the original code and/or files is Tripwire, Inc. // Portions created by Tripwire, Inc. are copyright (C) 2000 Tripwire, // Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights // reserved. // // This program is free software. The contents of this file are subject // to the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your // option) any later version. You may redistribute it and/or modify it // only in compliance with the GNU General Public License. // // This program is distributed in the hope that it will be useful. // However, this program is distributed AS-IS WITHOUT ANY // WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS // FOR A PARTICULAR PURPOSE. Please see the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // Nothing in the GNU General Public License or any other license to use // the code or files shall permit you to use Tripwire's trademarks, // service marks, or other intellectual property without Tripwire's // prior written consent. // // If you have any questions, please contact Tripwire, Inc. at either // info@tripwire.org or www.tripwire.org. // /////////////////////////////////////////////////////////////////////////////// // blockfile.h // // cBlockFile -- #ifndef __BLOCKFILE_H #define __BLOCKFILE_H #ifndef __TYPES_H #include "types.h" #endif #ifndef __TCHAR_H #include "core/tchar.h" #endif #ifndef __BLOCK_H #include "block.h" #endif #ifdef _DEBUG #undef _BLOCKFILE_DEBUG // If we dont do this, test does not compile on unix #define _BLOCKFILE_DEBUG // If we dont do this, test does not compile on unix #endif class cBlockFile_i; class eArchive; class cBidirArchive; //----------------------------------------------------------------------------- // cBlockFile //----------------------------------------------------------------------------- class cBlockFile { public: enum { BLOCK_SIZE = 4096 }; typedef cBlock Block; cBlockFile(); ~cBlockFile(); void Open( const TSTRING& fileName, int numPages, bool bTruncate = false ); //throw (eArchive) // opens the given file name as a block file, and uses numPages to signify the // number of pages to cache blocks in as they are accessed from disk. // if bTruncate is true, then the file is created with zero length. void Open( cBidirArchive* pArch, int numPages ); //throw (eArchive) // the same as the previous Open(), except the passed in archive is used. This class will destroy // the archive when it is done (when Close() is called). If the archive length is zero, then // we create a new database. Otherwise, we assume we are opening an existing file. void Close(); //throw (eArchive) // writes all unsaved data to disk and disassociates the block file from its archive void Flush(); //throw (eArchive) // flushes all dirty data to disk Block* GetBlock( int blockNum ); //throw (eArchive) // returns the specified block. This asserts that the block number is below GetNumBlocks() // this method takes care of paging the block into memory and returns a pointer to the block. Block* CreateBlock(); //throw (eArchive) // this creates a new block, sets its number to GetNumBlocks(), pages it into memory, and // returns a pointer to it void DestroyLastBlock( ); // this method removes the last block from the file int GetNumBlocks() const { return mNumBlocks; } int GetBlockSize() const { return BLOCK_SIZE; } cBidirArchive* GetArchive() { return mpArchive; } // NOTE -- be _very_ careful with this archive. It should probably not be written to private: typedef cBlockImpl BlockImpl; typedef std::vector< BlockImpl > BlockVector; int mNumPages; int mNumBlocks; // the total number of blocks in the archive. uint32 mTimer; // keeps track of the current "time" cBidirArchive* mpArchive; // note: I always own the deletion of the archive BlockVector mvPagedBlocks; void FlushBlock( BlockImpl* pBlock ); //throw (eArchive) // helper function that writes a block to disk if it is dirty /////////////////////////////////////////////////////////////////////////// // Profiling / Debugging interface /////////////////////////////////////////////////////////////////////////// #ifdef _BLOCKFILE_DEBUG public: void TraceContents(int dl = -1) const; // traces out all the info we can on the current state of this class // dl is the debug level to trace it at; -1 means to use D_DEBUG void AssertValid() const; // ASSERTs as much as we can about the consistancy of our internal state. int mNumBlockWrite; // counts how many writes we have done int mNumBlockRead; // counts how many reads we have done int mNumPageFault; // number of times a page fault occured int mNumPageRequests; // number of page requests (useful to compare with mNumPageFault) #endif //_BLOCKFILE_DEBUG }; //############################################################################# // inline implementation //############################################################################# inline void cBlockFile::FlushBlock( cBlockFile::BlockImpl* pBlock ) //throw (eArchive) { if( (pBlock->GetBlockNum() != Block::INVALID_NUM) && pBlock->IsDirty() ) { // mNumBlockWrite keeps track of how many block writes we do // #ifdef _BLOCKFILE_DEBUG mNumBlockWrite++; #endif pBlock->Write( *mpArchive ); } } #endif //__BLOCKFILE_H